├── CHANGES ├── LICENSE ├── README.md ├── lib └── resty │ └── snappy.lua └── lua-resty-snappy-dev-1.rockspec /CHANGES: -------------------------------------------------------------------------------- 1 | 2 | Changes with lua-resty-snappy 1.0 1 Oct 2014 3 | 4 | *) Feature: LuaRocks Support via MoonRocks. 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Aapo Talvensaari 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | lua-resty-snappy 2 | ================ 3 | 4 | `lua-resty-snappy` provides LuaJIT FFI bindings to Snappy, a fast compressor/decompressor (https://code.google.com/p/snappy/). 5 | 6 | ## Installation 7 | 8 | Just place [`snappy.lua`](https://github.com/bungle/lua-resty-snappy/blob/master/lib/resty/snappy.lua) somewhere in your `package.path`, preferably under `resty` directory. If you are using OpenResty, the default location would be `/usr/local/openresty/lualib/resty`. 9 | 10 | ### Compiling and Installing Snappy C-library 11 | 12 | 1. Install snappy with your operating system's package management OR build it manually from the sources provided from 13 | [Snappy repository](https://code.google.com/p/snappy/). 14 | 2. Check that you have `snappy.so` (or `.dylib`, or `.dll`) somewhere in the default search path for dynamic libraries of your operating system (or modify `snappy.lua` and point `ffi_load("snappy")` 15 | with full path to `snappy.so`, e.g. `local json = ffi_load("/usr/local/lib/lua/5.1/snappy.so")`). 16 | 17 | ### Using LuaRocks or MoonRocks 18 | 19 | This will only install the Lua module, not the Snappy C-library. 20 | 21 | If you are using LuaRocks >= 2.2: 22 | 23 | ```Shell 24 | $ luarocks install lua-resty-snappy 25 | ``` 26 | 27 | If you are using LuaRocks < 2.2: 28 | 29 | ```Shell 30 | $ luarocks install --server=http://rocks.moonscript.org moonrocks 31 | $ moonrocks install lua-resty-snappy 32 | ``` 33 | 34 | MoonRocks repository for `lua-resty-snappy` is located here: https://rocks.moonscript.org/modules/bungle/lua-resty-snappy. 35 | 36 | ## Lua API 37 | 38 | #### Error Codes 39 | 40 | ```c 41 | SNAPPY_OK = 0 42 | SNAPPY_INVALID_INPUT = 1 43 | SNAPPY_BUFFER_TOO_SMALL = 2 44 | ``` 45 | 46 | #### string, len snappy.compress(input) 47 | 48 | Compresses `input` with Snappy algorithm, and returns compressed data and its length. 49 | On error this will return nil and an error code. 50 | 51 | ##### Example 52 | 53 | ```lua 54 | local snappy = require "resty.snappy" 55 | local comp, err = snappy.compress("test") 56 | if comp then 57 | -- do something with compressed data and length 58 | -- (length is stored in err value)... 59 | else 60 | if err = 1 then 61 | print "Invalid input" 62 | elseif err == 2 then 63 | print "Buffer too small" 64 | end 65 | end 66 | ``` 67 | 68 | #### string, len snappy.uncompress(compressed) 69 | 70 | Uncompresses `compressed` with Snappy algorithm, and returns uncompressed data and its length. 71 | On error this will return nil and an error code. 72 | 73 | ##### Example 74 | 75 | ```lua 76 | local snappy = require "resty.snappy" 77 | local uncomp, err = snappy.uncompress(snappy.compress("test")) 78 | ``` 79 | 80 | #### number snappy.max_compressed_length(source_length) 81 | 82 | Returns maximum-possible length as a number of bytes of compressed data when 83 | uncompressed `source_length` is given. This is used to create buffer for compressing, 84 | but can also be used in quick measurement (and it may have nothing to do with 85 | final compressed output length, other than it cannot be larger than what this 86 | function returns). 87 | 88 | ##### Example 89 | 90 | ```lua 91 | local snappy = require "resty.snappy" 92 | local number = snappy.max_compressed_length(1000) 93 | ``` 94 | 95 | #### number snappy.uncompressed_length(compressed) 96 | 97 | This is quicker way (than using `snappy.uncompress` to determine how many bytes 98 | the compressed data will be when it is uncompressed. 99 | 100 | ##### Example 101 | 102 | ```lua 103 | local snappy = require "resty.snappy" 104 | local number = snappy.uncompressed_length(snappy.compress("test")) 105 | ``` 106 | 107 | #### boolean snappy.validate_compressed_buffer(compressed) 108 | 109 | This can be used to check if the compressed bytes are actually Snappy compressed 110 | bytes or something else. I.e. something that can be uncompressed with Snappy. 111 | 112 | ##### Example 113 | 114 | ```lua 115 | local snappy = require "resty.snappy" 116 | local bool = snappy.validate_compressed_buffer(snappy.compress("test")) 117 | ``` 118 | 119 | ## License 120 | 121 | `lua-resty-snappy` uses two clause BSD license. 122 | 123 | ``` 124 | Copyright (c) 2014, Aapo Talvensaari 125 | All rights reserved. 126 | 127 | Redistribution and use in source and binary forms, with or without modification, 128 | are permitted provided that the following conditions are met: 129 | 130 | * Redistributions of source code must retain the above copyright notice, this 131 | list of conditions and the following disclaimer. 132 | 133 | * Redistributions in binary form must reproduce the above copyright notice, this 134 | list of conditions and the following disclaimer in the documentation and/or 135 | other materials provided with the distribution. 136 | 137 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 138 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 139 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 140 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 141 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 142 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 143 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 144 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 145 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 146 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 147 | ``` 148 | -------------------------------------------------------------------------------- /lib/resty/snappy.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | local ffi_new = ffi.new 3 | local ffi_typeof = ffi.typeof 4 | local ffi_cdef = ffi.cdef 5 | local ffi_load = ffi.load 6 | local ffi_str = ffi.string 7 | local C = ffi.C 8 | local tonumber = tonumber 9 | 10 | ffi_cdef[[ 11 | typedef enum { 12 | SNAPPY_OK = 0, 13 | SNAPPY_INVALID_INPUT = 1, 14 | SNAPPY_BUFFER_TOO_SMALL = 2 15 | } snappy_status; 16 | snappy_status snappy_compress(const char* input, size_t input_length, char* compressed, size_t* compressed_length); 17 | snappy_status snappy_uncompress(const char* compressed, size_t compressed_length, char* uncompressed, size_t* uncompressed_length); 18 | size_t snappy_max_compressed_length(size_t source_length); 19 | snappy_status snappy_uncompressed_length(const char* compressed, size_t compressed_length, size_t* result); 20 | snappy_status snappy_validate_compressed_buffer(const char* compressed, size_t compressed_length); 21 | ]] 22 | 23 | local lib = ffi_load "snappy" 24 | local char_t = ffi_typeof "char[?]" 25 | local size_t = ffi_typeof "size_t[1]" 26 | local snappy = {} 27 | 28 | function snappy.compress(input) 29 | local il = #input 30 | local ml = snappy.max_compressed_length(il) 31 | local compressed = ffi_new(char_t, ml) 32 | local cl = ffi_new(size_t) 33 | cl[0] = tonumber(ml) 34 | local status = lib.snappy_compress(input, il, compressed, cl) 35 | local len = tonumber(cl[0]) 36 | if (status == C.SNAPPY_OK) then 37 | return ffi_str(compressed, len), len 38 | else 39 | return nil, tonumber(status) 40 | end 41 | end 42 | 43 | function snappy.uncompress(compressed) 44 | local cl = #compressed 45 | local ul = ffi_new(size_t) 46 | local status = lib.snappy_uncompressed_length(compressed, cl, ul) 47 | if (status ~= C.SNAPPY_OK) then 48 | return nil, tonumber(status) 49 | end 50 | local uncompressed = ffi_new(char_t, tonumber(ul[0])) 51 | status = lib.snappy_uncompress(compressed, cl, uncompressed, ul) 52 | local len = tonumber(ul[0]) 53 | if (status == C.SNAPPY_OK) then 54 | return ffi_str(uncompressed, len), len 55 | else 56 | return nil, tonumber(status) 57 | end 58 | end 59 | 60 | function snappy.max_compressed_length(source_length) 61 | return tonumber(lib.snappy_max_compressed_length(source_length)) 62 | end 63 | 64 | function snappy.uncompressed_length(compressed) 65 | local result = ffi_new(size_t) 66 | local status = lib.snappy_uncompressed_length(compressed, #compressed, result) 67 | if (status == C.SNAPPY_OK) then 68 | return tonumber(result[0]) 69 | else 70 | return nil 71 | end 72 | end 73 | 74 | function snappy.validate_compressed_buffer(compressed) 75 | local status = lib.snappy_validate_compressed_buffer(compressed, #compressed) 76 | return status == C.SNAPPY_OK 77 | end 78 | 79 | return snappy -------------------------------------------------------------------------------- /lua-resty-snappy-dev-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "lua-resty-snappy" 2 | version = "dev-1" 3 | source = { 4 | url = "git://github.com/bungle/lua-resty-snappy.git" 5 | } 6 | description = { 7 | summary = "LuaJIT FFI bindings for Snappy, a fast compressor/decompressor (https://code.google.com/p/snappy/).", 8 | detailed = "lua-resty-snappy provides LuaJIT FFI bindings to Snappy, a fast compressor/decompressor (https://code.google.com/p/snappy/).", 9 | homepage = "https://github.com/bungle/lua-resty-snappy", 10 | maintainer = "Aapo Talvensaari ", 11 | license = "BSD" 12 | } 13 | dependencies = { 14 | "lua >= 5.1" 15 | } 16 | build = { 17 | type = "builtin", 18 | modules = { 19 | ["resty.snappy"] = "lib/resty/snappy.lua" 20 | } 21 | } 22 | --------------------------------------------------------------------------------