diff --git a/README.md b/README.md new file mode 100644 index 0000000..b4decfa --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Snappy\nSnappy library for D. diff --git a/dub.json b/dub.json new file mode 100644 index 0000000..0d866a7 --- /dev/null +++ b/dub.json @@ -0,0 +1,6 @@ +{ + "name": "snappy", + "license": "Apache-2.0", + "copyright": "Copyright (C) 2015-2017 Shanghai Putao Technology Co., Ltd", + "description": "Snappy library for dlang." +} diff --git a/source/snappy/package.d b/source/snappy/package.d new file mode 100644 index 0000000..b7ece1d --- /dev/null +++ b/source/snappy/package.d @@ -0,0 +1,4 @@ +module snappy; + +public import snappy.snappy; + diff --git a/source/snappy/snappy.d b/source/snappy/snappy.d new file mode 100644 index 0000000..0b2655f --- /dev/null +++ b/source/snappy/snappy.d @@ -0,0 +1,76 @@ +module snappy.snappy; + +import std.conv; + +extern (C) { + enum snappy_status { + SNAPPY_OK = 0, + SNAPPY_INVALID_INPUT = 1, + SNAPPY_BUFFER_TOO_SMALL = 2, + }; + + snappy_status snappy_uncompressed_length(const byte* compressed, + size_t compressed_length, + size_t* result); + + snappy_status snappy_uncompress(const byte* compressed, + size_t compressed_length, + byte* uncompressed, + size_t* uncompressed_length); + snappy_status snappy_compress(const byte* input, + size_t input_length, + byte* compressed, + size_t* compressed_length); + size_t snappy_max_compressed_length(size_t source_length); +} + +class Snappy { + +static byte[] uncompress(byte[] compressed) { + size_t uncompressedPrediction; + snappy_status ok = snappy_uncompressed_length(compressed.ptr, compressed.length, &uncompressedPrediction); + if (ok != snappy_status.SNAPPY_OK) { + throw new Exception(to!(string)(ok)); + } + auto res = new byte[uncompressedPrediction]; + size_t uncompressed = uncompressedPrediction; + ok = snappy_uncompress(compressed.ptr, compressed.length, res.ptr, &uncompressed); + if (ok != snappy_status.SNAPPY_OK) { + throw new Exception(to!(string)(ok)); + } + if (uncompressed != uncompressedPrediction) { + throw new Exception("uncompressedPrediction " ~ to!(string)(uncompressedPrediction) ~ " != " ~ "uncompressed " ~ to!(string)(uncompressed)); + } + return res; + } + + + + static byte[] compress(byte[] uncompressed) { + size_t maxCompressedSize = snappy_max_compressed_length(uncompressed.length); + byte[] res = new byte[maxCompressedSize]; + size_t compressedSize = maxCompressedSize; + snappy_status ok = snappy_compress(uncompressed.ptr, uncompressed.length, res.ptr, &compressedSize); + if (ok != snappy_status.SNAPPY_OK) { + throw new Exception(to!(string)(ok)); + } + return res[0..compressedSize]; + } + +} + + +unittest{ + import std.stdio; + import util.snappy; + + byte[] data = cast(byte[])"ffdsffffffffffffffffaaaaaaaaaaaaaaaaaaccccccccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeee"; + writeln("-------------------------------------------------"); + writefln("start test compress data, length:%s", data.length); + + byte[] cprData = Snappy.compress(data); + writefln("compress data, length:%s, data:%s", cprData.length, cprData); + + byte[] unData = Snappy.uncompress(cprData); + writefln("uncompress data, length:%s, data:%s", unData.length, unData); +}