nim-snappy/snappy/types.nim

53 lines
1.8 KiB
Nim

type
SnappyError* = object of CatchableError
SnappyDecodingError* = object of SnappyError
SnappyEncodingError* = object of SnappyError
UnexpectedEofError* = object of SnappyDecodingError
MalformedSnappyData* = object of SnappyDecodingError
InputTooLarge* = object of SnappyEncodingError
const
maxUncompressedLen* = 0xffffffff'u32
maxBlockSize* = 65536
template raiseInputTooLarge* =
raise newException(InputTooLarge, "Input too large to be compressed with Snappy")
proc checkInputLen*(len: Natural): uint32 =
when sizeof(int) == 8:
if len > 0xffffffff:
raiseInputTooLarge()
uint32(len)
# maxCompressedLen returns the maximum length of a snappy block, given its
# uncompressed length.
#
# It will return a zero value if srcLen is too large to encode.
func maxCompressedLen*(srcLen: uint32): uint64 =
# Compressed data can be defined as:
# compressed := item* literal*
# item := literal* copy
#
# The trailing literal sequence has a space blowup of at most 62/60
# since a literal of length 60 needs one tag byte + one extra byte
# for length information.
#
# Item blowup is trickier to measure. Suppose the "copy" op copies
# 4 bytes of data. Because of a special check in the encoding code,
# we produce a 4-byte copy only if the offset is < 65536. Therefore
# the copy op takes 3 bytes to encode, and this type of item leads
# to at most the 62/60 blowup for representing literals.
#
# Suppose the "copy" op copies 5 bytes of data. If the offset is big
# enough, it will take 5 bytes to encode the copy op. Therefore the
# worst case here is a one-byte literal followed by a five-byte copy.
# That is, 6 bytes of input turn into 7 bytes of "compressed" data.
#
# This last factor dominates the blowup, so the final estimate is:
let n = srcLen.uint64
32'u64 + n + n div 6'u64