raises annotations for framed format

This commit is contained in:
Jacek Sieka 2022-03-28 12:24:46 +02:00
parent 3d39a6228a
commit 6afa8377e1
No known key found for this signature in database
GPG Key ID: A1B09461ABB656B8
1 changed files with 26 additions and 10 deletions

View File

@ -6,6 +6,8 @@ import
export export
types types
{.push raises: [Defect].}
{.compile: "crc32c.c".} {.compile: "crc32c.c".}
# TODO: we don't have a native implementation of CRC32C algorithm yet. # TODO: we don't have a native implementation of CRC32C algorithm yet.
# we can't use nimPNG CRC32 # we can't use nimPNG CRC32
@ -14,9 +16,11 @@ proc masked_crc32c(buf: ptr byte, len: uint): cuint {.cdecl, importc.}
func checkCrc*(data: openArray[byte], expected: uint32): bool = func checkCrc*(data: openArray[byte], expected: uint32): bool =
let startPtr = if data.len == 0: nil else: data[0].unsafeAddr let startPtr = if data.len == 0: nil else: data[0].unsafeAddr
let actual = masked_crc32c(startPtr, data.len.uint) let actual = masked_crc32c(startPtr, data.len.uint)
result = actual == expected actual == expected
proc checkCrcAndAppend*(output: OutputStream, data: openArray[byte], crc: uint32): bool = proc checkCrcAndAppend*(
output: OutputStream, data: openArray[byte], crc: uint32): bool {.
raises: [Defect, IOError].}=
if checkCrc(data, crc): if checkCrc(data, crc):
output.write(data) output.write(data)
return true return true
@ -35,10 +39,12 @@ const
STREAM_HEADER* = "\xff\x06\x00\x00sNaPpY" STREAM_HEADER* = "\xff\x06\x00\x00sNaPpY"
proc uncompressFramedStream*(input: InputStream, output: OutputStream) {.fsMultiSync.} = proc uncompressFramedStream*(
input: InputStream, output: OutputStream) {.
fsMultiSync, raises: [Defect, IOError, SnappyError].} =
try: try:
if not input.readable(STREAM_HEADER.len): if not input.readable(STREAM_HEADER.len):
raise newException(UnexpectedEofError, "Failed to read strean header") raise newException(UnexpectedEofError, "Failed to read stream header")
if input.read(STREAM_HEADER.len) != STREAM_HEADER.toOpenArrayByte(0, STREAM_HEADER.len-1): if input.read(STREAM_HEADER.len) != STREAM_HEADER.toOpenArrayByte(0, STREAM_HEADER.len-1):
raise newException(MalformedSnappyData, "Invalid header value") raise newException(MalformedSnappyData, "Invalid header value")
@ -91,15 +97,21 @@ proc uncompressFramedStream*(input: InputStream, output: OutputStream) {.fsMulti
finally: finally:
close output close output
proc framingFormatUncompress*(input: InputStream): seq[byte] = proc framingFormatUncompress*(input: InputStream): seq[byte] {.
raises: [Defect, SnappyError].} =
var output = memoryOutput() var output = memoryOutput()
try:
uncompressFramedStream input, output uncompressFramedStream input, output
except IOError as e: raiseAssert e.msg # Doesn't happen with memory outputs
return output.getOutput return output.getOutput
proc framingFormatUncompress*(input: openarray[byte]): seq[byte] = proc framingFormatUncompress*(input: openarray[byte]): seq[byte] {.
raises: [Defect, SnappyError].} =
framingFormatUncompress unsafeMemoryInput(input) framingFormatUncompress unsafeMemoryInput(input)
proc processFrame(output: OutputStream, dst: var openArray[byte], src: openArray[byte]) = proc processFrame(
output: OutputStream, dst: var openArray[byte], src: openArray[byte]) {.
raises: [Defect, IOError].} =
let let
crc = masked_crc32c(src[0].unsafeAddr, src.len.uint) crc = masked_crc32c(src[0].unsafeAddr, src.len.uint)
leb128 = uint32(src.len).toBytes(Leb128) leb128 = uint32(src.len).toBytes(Leb128)
@ -127,7 +139,8 @@ proc processFrame(output: OutputStream, dst: var openArray[byte], src: openArray
output.write toBytesLE(crc) output.write toBytesLE(crc)
output.write dst.toOpenArray(0, encodedLen-1) output.write dst.toOpenArray(0, encodedLen-1)
proc framingFormatCompress*(output: OutputStream, src: openArray[byte]) = proc framingFormatCompress*(output: OutputStream, src: openArray[byte]) {.
raises: [Defect, IOError].} =
const maxFrameSize = MAX_UNCOMPRESSED_DATA_LEN const maxFrameSize = MAX_UNCOMPRESSED_DATA_LEN
var compressedData = newSeq[byte](MAX_COMPRESSED_DATA_LEN) var compressedData = newSeq[byte](MAX_COMPRESSED_DATA_LEN)
@ -148,5 +161,8 @@ proc framingFormatCompress*(output: OutputStream, src: openArray[byte]) =
proc framingFormatCompress*(src: openArray[byte]): seq[byte] = proc framingFormatCompress*(src: openArray[byte]): seq[byte] =
var output = memoryOutput() var output = memoryOutput()
try:
framingFormatCompress(output, src) framingFormatCompress(output, src)
except IOError as e: raiseAssert e.msg
return output.getOutput return output.getOutput