-
Notifications
You must be signed in to change notification settings - Fork 5
/
snappy.lua
79 lines (71 loc) · 2.51 KB
/
snappy.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
local ffi = require "ffi"
local ffi_new = ffi.new
local ffi_typeof = ffi.typeof
local ffi_cdef = ffi.cdef
local ffi_load = ffi.load
local ffi_str = ffi.string
local C = ffi.C
local tonumber = tonumber
ffi_cdef[[
typedef enum {
SNAPPY_OK = 0,
SNAPPY_INVALID_INPUT = 1,
SNAPPY_BUFFER_TOO_SMALL = 2
} snappy_status;
snappy_status snappy_compress(const char* input, size_t input_length, char* compressed, size_t* compressed_length);
snappy_status snappy_uncompress(const char* compressed, size_t compressed_length, char* uncompressed, size_t* uncompressed_length);
size_t snappy_max_compressed_length(size_t source_length);
snappy_status snappy_uncompressed_length(const char* compressed, size_t compressed_length, size_t* result);
snappy_status snappy_validate_compressed_buffer(const char* compressed, size_t compressed_length);
]]
local lib = ffi_load "snappy"
local char_t = ffi_typeof "char[?]"
local size_t = ffi_typeof "size_t[1]"
local snappy = {}
function snappy.compress(input)
local il = #input
local ml = snappy.max_compressed_length(il)
local compressed = ffi_new(char_t, ml)
local cl = ffi_new(size_t)
cl[0] = tonumber(ml)
local status = lib.snappy_compress(input, il, compressed, cl)
local len = tonumber(cl[0])
if (status == C.SNAPPY_OK) then
return ffi_str(compressed, len), len
else
return nil, tonumber(status)
end
end
function snappy.uncompress(compressed)
local cl = #compressed
local ul = ffi_new(size_t)
local status = lib.snappy_uncompressed_length(compressed, cl, ul)
if (status ~= C.SNAPPY_OK) then
return nil, tonumber(status)
end
local uncompressed = ffi_new(char_t, tonumber(ul[0]))
status = lib.snappy_uncompress(compressed, cl, uncompressed, ul)
local len = tonumber(ul[0])
if (status == C.SNAPPY_OK) then
return ffi_str(uncompressed, len), len
else
return nil, tonumber(status)
end
end
function snappy.max_compressed_length(source_length)
return tonumber(lib.snappy_max_compressed_length(source_length))
end
function snappy.uncompressed_length(compressed)
local result = ffi_new(size_t)
local status = lib.snappy_uncompressed_length(compressed, #compressed, result)
if (status == C.SNAPPY_OK) then
return tonumber(result[0])
else
return nil
end
end
function snappy.validate_compressed_buffer(compressed)
local status = lib.snappy_validate_compressed_buffer(compressed, #compressed)
return status == C.SNAPPY_OK
end
return snappy