1 module snappy.snappy;
2 
3 import std.conv;
4 
5 extern (C) {
6   enum snappy_status {
7     SNAPPY_OK = 0,
8     SNAPPY_INVALID_INPUT = 1,
9     SNAPPY_BUFFER_TOO_SMALL = 2,
10   };
11 
12   snappy_status snappy_uncompressed_length(const byte* compressed,
13                                            size_t compressed_length,
14                                            size_t* result);
15 
16   snappy_status snappy_uncompress(const byte* compressed,
17                                   size_t compressed_length,
18                                   byte* uncompressed,
19                                   size_t* uncompressed_length);
20   snappy_status snappy_compress(const byte* input,
21                                 size_t input_length,
22                                 byte* compressed,
23                                 size_t* compressed_length);
24   size_t snappy_max_compressed_length(size_t source_length);
25 }
26 
27 class Snappy {
28   
29 static byte[] uncompress(byte[] compressed) {
30     size_t uncompressedPrediction;
31     snappy_status ok = snappy_uncompressed_length(compressed.ptr, compressed.length, &uncompressedPrediction);
32     if (ok != snappy_status.SNAPPY_OK) {
33       throw new Exception(to!(string)(ok));
34     }
35     auto res = new byte[uncompressedPrediction];
36     size_t uncompressed = uncompressedPrediction;
37     ok = snappy_uncompress(compressed.ptr, compressed.length, res.ptr, &uncompressed);
38     if (ok != snappy_status.SNAPPY_OK) {
39       throw new Exception(to!(string)(ok));
40     }
41     if (uncompressed != uncompressedPrediction) {
42       throw new Exception("uncompressedPrediction " ~ to!(string)(uncompressedPrediction) ~ " != " ~ "uncompressed " ~ to!(string)(uncompressed));
43     }
44     return res;
45   }
46 
47 
48 
49   static byte[] compress(byte[] uncompressed) {
50     size_t maxCompressedSize = snappy_max_compressed_length(uncompressed.length);
51     byte[] res = new byte[maxCompressedSize];
52     size_t compressedSize = maxCompressedSize;
53     snappy_status ok = snappy_compress(uncompressed.ptr, uncompressed.length, res.ptr, &compressedSize);
54     if (ok != snappy_status.SNAPPY_OK) {
55       throw new Exception(to!(string)(ok));
56     }
57     return res[0..compressedSize];
58   }
59 
60 }
61 
62 
63 unittest{
64 	import std.stdio;
65 	import util.snappy;
66 
67 	byte[] data = cast(byte[])"ffdsffffffffffffffffaaaaaaaaaaaaaaaaaaccccccccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeee";
68 	writeln("-------------------------------------------------");
69 	writefln("start test compress data, length:%s", data.length);
70 
71 	byte[] cprData = Snappy.compress(data);
72 	writefln("compress data, length:%s, data:%s", cprData.length, cprData);
73 
74 	byte[] unData = Snappy.uncompress(cprData);
75 	writefln("uncompress data, length:%s, data:%s", unData.length, unData);
76 }