import snappy, os, unittest, terminal, strutils, randgen {.passL: "-lsnappy".} {.passL: "-L.".} {.passL: "-lstdc++".} proc snappy_compress(input: cstring, input_length: csize, compressed: cstring, compressed_length: var csize): cint {.importc, cdecl.} proc snappy_uncompress(compressed: cstring, compressed_length: csize, uncompressed: cstring, uncompressed_length: var csize): cint {.importc, cdecl.} proc snappy_max_compressed_length(source_length: csize): csize {.importc, cdecl.} proc snappy_uncompressed_length(compressed: cstring, compressed_length: csize, res: var csize): cint {.importc, cdecl.} const testDataDir = "data" & DirSep let empty: seq[byte] = @[] oneZero = @[0.byte] proc readSource(sourceName: string): seq[byte] = var f = open(sourceName, fmRead) if f.isNil: return let size = f.getFileSize() result = newSeq[byte](size) doAssert(size == f.readBytes(result, 0, size)) f.close() proc roundTrip(msg: string, source: openArray[byte]): bool = var encoded = snappy.encode(source) cpp_encoded = newString(snappy_max_compressed_length(source.len.csize)) output_size: csize = cpp_encoded.len success: cint = 0 if source.len > 0: success = snappy_compress(cast[cstring](source[0].unsafeAddr), source.len.csize, cpp_encoded[0].addr, output_size) else: success = snappy_compress(cast[cstring](0), source.len.csize, cpp_encoded[0].addr, output_size) var ok = success == 0 if not ok: echo "cpp_compress failed" ok = output_size == encoded.len if not ok: echo "cpp output size and nim output size differ" if ok: ok = equalMem(encoded[0].addr, cpp_encoded[0].addr, output_size.int) if not ok: echo "cpp output and nim output differ" if ok: ok = snappy.decode(encoded) == source if not ok: echo "roundtrip failure" if ok: stdout.styledWriteLine(" ", msg, "...", fgGreen, "[PASS]") else: stdout.styledWriteLine(" ", msg, "...", fgRed, "[FAILED]") result = ok proc roundTrip(msg: string, sourceName: string): bool = var src = readSource(sourceName) roundTrip(msg, src) proc roundTripRev(msg: string, source: openArray[byte]): bool = var decoded = snappy.decode(source) output_size: csize = 0 ok = snappy_uncompressed_length(cast[cstring](source[0].unsafeAddr), source.len.csize, output_size) == 0 cpp_decoded: string if not ok: echo "maybe a bad data" if ok: cpp_decoded = newString(output_size) ok = snappy_uncompress(cast[cstring](source[0].unsafeAddr), source.len.csize, cpp_decoded, output_size) == 0 if not ok: echo "cpp failed to uncompress" if ok: ok = equalMem(decoded[0].addr, cpp_decoded[0].addr, output_size.int) if not ok: echo "cpp output and nim output differ" if ok: ok = snappy.encode(decoded) == source if not ok: echo "rev roundtrip failure" if ok: stdout.styledWriteLine(" ", msg, "...", fgGreen, "[PASS]") else: stdout.styledWriteLine(" ", msg, "...", fgRed, "[FAILED]") result = ok proc roundTripRev(msg: string, sourceName: string): bool = var src = readSource(sourceName) roundTripRev(msg, src) template toBytes(s: string): auto = toOpenArrayByte(s, 0, s.len-1) suite "snappy": test "basic roundtrip test": check roundTrip("empty", empty) check roundTrip("oneZero", oneZero) check roundTrip("data_html", testDataDir & "html") check roundTrip("data_urls", testDataDir & "urls.10K") check roundTrip("data_jpg", testDataDir & "fireworks.jpeg") check roundTrip("data_pdf", testDataDir & "paper-100k.pdf") check roundTrip("data_html4", testDataDir & "html_x_4") check roundTrip("data_txt1", testDataDir & "alice29.txt") check roundTrip("data_txt2", testDataDir & "asyoulik.txt") check roundTrip("data_txt3", testDataDir & "lcet10.txt") check roundTrip("data_txt4", testDataDir & "plrabn12.txt") check roundTrip("data_pb", testDataDir & "geo.protodata") check roundTrip("data_gaviota", testDataDir & "kppkn.gtb") check roundTrip("data_golden", testDataDir & "Mark.Twain-Tom.Sawyer.txt") check roundTripRev("data_golden_rev", testDataDir & "Mark.Twain-Tom.Sawyer.txt.rawsnappy") test "misc test": for i in 1..32: let x = repeat("b", i) let y = "aaaa$1aaaabbbb" % [x] check roundTrip("repeat " & $i, toBytes(y)) var i = 1 while i < 20_000: var buf = newSeq[byte](i) for j in 0..