Use the latest faststreams OutputStream API

This commit is contained in:
Zahary Karadjov 2020-04-09 23:02:36 +03:00
parent f08cbf9dc5
commit b5196c17b6
No known key found for this signature in database
GPG Key ID: C8936F8A3073D609
6 changed files with 46 additions and 36 deletions

View File

@ -11,7 +11,7 @@ const
inputMargin = 16 - 1
# PutUvarint encodes a uint64 into buf and returns the number of bytes written.
proc putUvarint(s: OutputStreamVar, x: uint64) =
proc putUvarint(s: OutputStream, x: uint64) =
var x = x
while x >= 0x80'u64:
s.append byte(x and 0xFF) or 0x80
@ -73,7 +73,7 @@ func load64(b: openArray[byte], i: int): uint64 =
#
# It assumes that:
# 1 <= len(lit) and len(lit) <= 65536
proc emitLiteral(s: OutputStreamVar, lit: openarray[byte]) =
proc emitLiteral(s: OutputStream, lit: openarray[byte]) =
let n = lit.len - 1
if n < 60:
@ -93,7 +93,7 @@ proc emitLiteral(s: OutputStreamVar, lit: openarray[byte]) =
# It assumes that:
# 1 <= offset and offset <= 65535
# 4 <= length and length <= 65535
proc emitCopy(s: OutputStreamVar, offset, length: int) =
proc emitCopy(s: OutputStream, offset, length: int) =
var length = length
# The maximum length for a single tagCopy1 or tagCopy2 op is 64 bytes. The
# threshold for this loop is a little higher (at 68 = 64 + 4), and the
@ -153,7 +153,7 @@ func hash(u, shift: uint32): uint32 =
# It also assumes that:
# len(dst) >= MaxEncodedLen(len(src)) and
# minNonLiteralBlockSize <= len(src) and len(src) <= maxBlockSize
proc encodeBlock(output: OutputStreamVar, src: openArray[byte]) =
proc encodeBlock(output: OutputStream, src: openArray[byte]) =
# Initialize the hash table. Its size ranges from 1shl8 to 1shl14 inclusive.
# The table element type is uint16, as s < sLimit and sLimit < len(src)
# and len(src) <= maxBlockSize and maxBlockSize == 65536.
@ -396,7 +396,7 @@ const
# Otherwise, a newly allocated slice will be returned.
#
# The dst and src must not overlap. It is valid to pass a nil dst.
proc appendSnappyBytes*(s: OutputStreamVar, src: openArray[byte]) =
proc appendSnappyBytes*(s: OutputStream, src: openArray[byte]) =
let n = maxEncodedLen(src.len)
if n == 0: return
@ -421,30 +421,40 @@ proc appendSnappyBytes*(s: OutputStreamVar, src: openArray[byte]) =
dec(len, blockSize)
let SnappyStreamVTable = OutputStreamVTable(
writePage: proc (s: OutputStreamVar, data: openarray[byte])
writePage: proc (s: OutputStream, data: openarray[byte])
{.nimcall, gcsafe, raises: [IOError, Defect].} =
OutputStreamVar(s.outputDevice).encodeBlock data
encodeBlock(LayeredOutputStream(s).subStream, data)
,
flush: proc (s: OutputStreamVar) {.nimcall, gcsafe.} =
OutputStreamVar(s.outputDevice).flush
flush: proc (s: OutputStream) {.nimcall, gcsafe.} =
flush LayeredOutputStream(s).subStream
)
proc initSnappyStream*(targetStream: OutputStreamVar): ref OutputStream =
new result
result.initWithSinglePage maxBlockSize, maxBlockSize
result.outputDevice = targetStream
result.vtable = unsafeAddr SnappyStreamVTable
func initSnappyStream*(targetStream: OutputStream): OutputStreamHandle =
var stream = LayeredOutputStream(
vtable: vtableAddr(SnappyStreamVTable),
pageSize: maxBlockSize,
maxWriteSize: maxBlockSize,
subStream: targetStream)
stream.initWithSinglePage()
OutputStreamHandle(s: stream)
# Encode returns the encoded form of src.
proc encode*(src: openarray[byte]): seq[byte] =
func encode*(src: openarray[byte]): seq[byte] =
let n = maxEncodedLen(src.len)
if n == 0: return
result = newSeq[byte](n)
var outputStream = OutputStream.init(addr result[0], result.len)
outputStream.putUVarInt uint64(src.len)
var snappyStream = initSnappyStream(outputStream)
snappyStream.append src
snappyStream.flush
{.noSideEffect.}:
# We assume no side-effects here, because we are working
# with a `memoryOutput`. The computed side-effects differ
# because the code of the SnappyStream may be used to write
# to a file or a network device as well.
var outputStream = memoryOutput(addr result[0], result.len)
outputStream.putUVarInt uint64(src.len)
var snappyStream = initSnappyStream(outputStream)
snappyStream.append src
snappyStream.flush
result.setLen outputStream.pos
# decodedLen returns the length of the decoded block and the number of bytes

View File

@ -12,6 +12,6 @@ requires "nim >= 0.19.0",
"stew"
task test, "Run all tests":
exec "nim c --passL:\"-lsnappy -L./tests -lstdc++\" -r tests/all_tests"
exec "nim c --passL:\"-lsnappy -L./tests -lstdc++\" -d:debug -r tests/all_tests"
exec "nim c --passL:\"-lsnappy -L./tests -lstdc++\" -d:release -r tests/all_tests"
exec "nim c --passL:\"-lsnappy -L./tests -lstdc++\" --threads:on -d:release -r tests/all_tests"

View File

@ -13,7 +13,7 @@ func checkCrc32(data: openArray[byte], expected: uint32): bool =
let actual = masked_crc32c(data[0].unsafeAddr, data.len.uint)
result = actual == expected
proc checkData(data: openArray[byte], crc: uint32, output: OutputStreamVar): bool =
proc checkData(data: openArray[byte], crc: uint32, output: OutputStream): bool =
if not checkCrc32(data, crc):
return
@ -38,8 +38,8 @@ const
STREAM_HEADER = "\xff\x06\x00\x00sNaPpY"
proc framing_format_uncompress*(input: ByteStreamVar, output: OutputStreamVar) =
if not input[].ensureBytes(STREAM_HEADER.len):
proc framing_format_uncompress*(input: InputStream, output: OutputStream) =
if not input.ensureBytes(STREAM_HEADER.len):
# debugEcho "NOT A SNAPPY STREAM"
return
@ -50,11 +50,11 @@ proc framing_format_uncompress*(input: ByteStreamVar, output: OutputStreamVar) =
var uncompressedData = newSeq[byte](MAX_UNCOMPRESSED_DATA_LEN)
while true:
if input[].eof():
if input.eof():
break
# ensure bytes
if not input[].ensureBytes(4):
if not input.ensureBytes(4):
# debugEcho "CHK 1 NOT ENOUGH BYTES"
return
@ -62,7 +62,7 @@ proc framing_format_uncompress*(input: ByteStreamVar, output: OutputStreamVar) =
let id = x and 0xFF
let dataLen = (x shr 8).int
if not input[].ensureBytes(dataLen):
if not input.ensureBytes(dataLen):
# debugEcho "CHK 2 NOT ENOUGH BYTES"
# debugEcho "request: ", dataLen
# debugEcho "pos: ", input[].pos
@ -104,7 +104,7 @@ proc framing_format_uncompress*(input: ByteStreamVar, output: OutputStreamVar) =
output.flush()
proc processFrame*(output: OutputStreamVar, dst: var openArray[byte], src: openArray[byte]) =
proc processFrame*(output: OutputStream, dst: var openArray[byte], src: openArray[byte]) =
let
crc = masked_crc32c(src[0].unsafeAddr, src.len.uint)
varintLen = oas.putUvarint(dst, src.len.uint64)
@ -123,7 +123,7 @@ proc processFrame*(output: OutputStreamVar, dst: var openArray[byte], src: openA
output.append toBytesLE(crc)
output.append dst.toOpenArray(0, encodedLen-1)
proc framing_format_compress*(output: OutputStreamVar, src: openArray[byte]) =
proc framing_format_compress*(output: OutputStream, src: openArray[byte]) =
const maxFrameSize = MAX_UNCOMPRESSED_DATA_LEN
var compressedData = newSeq[byte](MAX_COMPRESSED_DATA_LEN)

View File

@ -1,3 +1,4 @@
import
test_codec,
test_framing_format

View File

@ -1,7 +1,6 @@
import
os, unittest, terminal, strutils, streams,
faststreams, snappy,
randgen, openarrays_snappy, nimstreams_snappy
snappy, randgen, openarrays_snappy, nimstreams_snappy
include system/timers

View File

@ -5,8 +5,8 @@ import
template check_uncompress(source, target: string) =
test "uncompress " & source & " to " & target:
var inStream = openFile(compDir & source)
var outStream = OutputStream.init
var inStream = fileInput(compDir & source)
var outStream = memoryOutput()
framing_format_uncompress(inStream, outStream)
@ -21,14 +21,14 @@ template check_uncompress(source, target: string) =
template check_roundtrip(source) =
test "roundtrip " & source:
let expected = readFile(uncompDir & source)
var ost = OutputStream.init
var ost = memoryOutput()
framing_format_compress(ost, expected.toOpenArrayByte(0, expected.len-1))
let compressed = ost.getOutput(string)
debugEcho "compressed len: ", compressed.len
var inst = memoryStream(compressed)
var outst = OutputStream.init
var inst = memoryInput(compressed)
var outst = memoryOutput()
framing_format_uncompress(inst, outst)
let actual = outst.getOutput(string)
check actual.len == expected.len