lzf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4e0c58aad17afd1248a64a10f0be8331b2dd8746
4
+ data.tar.gz: 041ecfa49d2475edba77b8895a10cddd490ea897
5
+ SHA512:
6
+ metadata.gz: d5dce1978fbb60097806f8ba0bcad5227468dd9003746f54bf85f22db8dc0eb878caae3081df9a9a7577f206662a7eb65764fdf217525dce0b26b10dbde8f09f
7
+ data.tar.gz: 5d6997fdb1886e5f790326bc2e24a4502c0c4efd55044f17a0eab8c11fd7e60af2452a4bfd7ad09eb70b35c5802774ec0437fc66d115f07e074b5dab0e74b49f
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ test_data
19
+
@@ -0,0 +1 @@
1
+ lzf
@@ -0,0 +1 @@
1
+ 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lzf.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 glebtv
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ # Lzf
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'lzf'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install lzf
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
30
+
31
+ ## Credits
32
+
33
+ Loosely based on https://bitbucket.org/winebarrel/lzf-ruby/overview
34
+ which won't compile for me.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('lzf')
4
+
@@ -0,0 +1,185 @@
1
+ /*
2
+ * Copyright (c) 2000-2007 Marc Alexander Lehmann <schmorp@schmorp.de>
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without modifica-
5
+ * tion, are permitted provided that the following conditions are met:
6
+ *
7
+ * 1. Redistributions of source code must retain the above copyright notice,
8
+ * this list of conditions and the following disclaimer.
9
+ *
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
16
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
18
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
22
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
24
+ *
25
+ * Alternatively, the contents of this file may be used under the terms of
26
+ * the GNU General Public License ("GPL") version 2 or any later version,
27
+ * in which case the provisions of the GPL are applicable instead of
28
+ * the above. If you wish to allow the use of your version of this file
29
+ * only under the terms of the GPL and not to allow others to use your
30
+ * version of this file under the BSD license, indicate your decision
31
+ * by deleting the provisions above and replace them with the notice
32
+ * and other provisions required by the GPL. If you do not delete the
33
+ * provisions above, a recipient may use your version of this file under
34
+ * either the BSD or the GPL.
35
+ */
36
+
37
+ #ifndef LZFP_h
38
+ #define LZFP_h
39
+
40
+ #define STANDALONE 1 /* at the moment, this is ok. */
41
+
42
+ #ifndef STANDALONE
43
+ # include "lzf.h"
44
+ #endif
45
+
46
+ /*
47
+ * Size of hashtable is (1 << HLOG) * sizeof (char *)
48
+ * decompression is independent of the hash table size
49
+ * the difference between 15 and 14 is very small
50
+ * for small blocks (and 14 is usually a bit faster).
51
+ * For a low-memory/faster configuration, use HLOG == 13;
52
+ * For best compression, use 15 or 16 (or more, up to 22).
53
+ */
54
+ #ifndef HLOG
55
+ # define HLOG 16
56
+ #endif
57
+
58
+ /*
59
+ * Sacrifice very little compression quality in favour of compression speed.
60
+ * This gives almost the same compression as the default code, and is
61
+ * (very roughly) 15% faster. This is the preferred mode of operation.
62
+ */
63
+ #ifndef VERY_FAST
64
+ # define VERY_FAST 1
65
+ #endif
66
+
67
+ /*
68
+ * Sacrifice some more compression quality in favour of compression speed.
69
+ * (roughly 1-2% worse compression for large blocks and
70
+ * 9-10% for small, redundant, blocks and >>20% better speed in both cases)
71
+ * In short: when in need for speed, enable this for binary data,
72
+ * possibly disable this for text data.
73
+ */
74
+ #ifndef ULTRA_FAST
75
+ # define ULTRA_FAST 0
76
+ #endif
77
+
78
+ /*
79
+ * Unconditionally aligning does not cost very much, so do it if unsure
80
+ */
81
+ #ifndef STRICT_ALIGN
82
+ # define STRICT_ALIGN !(defined(__i386) || defined (__amd64))
83
+ #endif
84
+
85
+ /*
86
+ * You may choose to pre-set the hash table (might be faster on some
87
+ * modern cpus and large (>>64k) blocks, and also makes compression
88
+ * deterministic/repeatable when the configuration otherwise is the same).
89
+ */
90
+ #ifndef INIT_HTAB
91
+ # define INIT_HTAB 0
92
+ #endif
93
+
94
+ /*
95
+ * Avoid assigning values to errno variable? for some embedding purposes
96
+ * (linux kernel for example), this is necessary. NOTE: this breaks
97
+ * the documentation in lzf.h. Avoiding errno has no speed impact.
98
+ */
99
+ #ifndef AVOID_ERRNO
100
+ # define AVOID_ERRNO 0
101
+ #endif
102
+
103
+ /*
104
+ * Whether to pass the LZF_STATE variable as argument, or allocate it
105
+ * on the stack. For small-stack environments, define this to 1.
106
+ * NOTE: this breaks the prototype in lzf.h.
107
+ */
108
+ #ifndef LZF_STATE_ARG
109
+ # define LZF_STATE_ARG 0
110
+ #endif
111
+
112
+ /*
113
+ * Whether to add extra checks for input validity in lzf_decompress
114
+ * and return EINVAL if the input stream has been corrupted. This
115
+ * only shields against overflowing the input buffer and will not
116
+ * detect most corrupted streams.
117
+ * This check is not normally noticeable on modern hardware
118
+ * (<1% slowdown), but might slow down older cpus considerably.
119
+ */
120
+ #ifndef CHECK_INPUT
121
+ # define CHECK_INPUT 1
122
+ #endif
123
+
124
+ /*
125
+ * Whether to store pointers or offsets inside the hash table. On
126
+ * 64 bit architetcures, pointers take up twice as much space,
127
+ * and might also be slower. Default is to autodetect.
128
+ */
129
+ /*#define LZF_USER_OFFSETS autodetect */
130
+
131
+ /*****************************************************************************/
132
+ /* nothing should be changed below */
133
+
134
+ #ifdef __cplusplus
135
+ # include <cstring>
136
+ # include <climits>
137
+ using namespace std;
138
+ #else
139
+ # include <string.h>
140
+ # include <limits.h>
141
+ #endif
142
+
143
+ #ifndef LZF_USE_OFFSETS
144
+ # if defined (WIN32)
145
+ # define LZF_USE_OFFSETS defined(_M_X64)
146
+ # else
147
+ # if __cplusplus > 199711L
148
+ # include <cstdint>
149
+ # else
150
+ # include <stdint.h>
151
+ # endif
152
+ # define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU)
153
+ # endif
154
+ #endif
155
+
156
+ typedef unsigned char u8;
157
+
158
+ #if LZF_USE_OFFSETS
159
+ # define LZF_HSLOT_BIAS ((const u8 *)in_data)
160
+ typedef unsigned int LZF_HSLOT;
161
+ #else
162
+ # define LZF_HSLOT_BIAS 0
163
+ typedef const u8 *LZF_HSLOT;
164
+ #endif
165
+
166
+ typedef LZF_HSLOT LZF_STATE[1 << (HLOG)];
167
+
168
+ #if !STRICT_ALIGN
169
+ /* for unaligned accesses we need a 16 bit datatype. */
170
+ # if USHRT_MAX == 65535
171
+ typedef unsigned short u16;
172
+ # elif UINT_MAX == 65535
173
+ typedef unsigned int u16;
174
+ # else
175
+ # undef STRICT_ALIGN
176
+ # define STRICT_ALIGN 1
177
+ # endif
178
+ #endif
179
+
180
+ #if ULTRA_FAST
181
+ # undef VERY_FAST
182
+ #endif
183
+
184
+ #endif
185
+
@@ -0,0 +1,291 @@
1
+ /*
2
+ * Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without modifica-
5
+ * tion, are permitted provided that the following conditions are met:
6
+ *
7
+ * 1. Redistributions of source code must retain the above copyright notice,
8
+ * this list of conditions and the following disclaimer.
9
+ *
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
16
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
18
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
22
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
24
+ *
25
+ * Alternatively, the contents of this file may be used under the terms of
26
+ * the GNU General Public License ("GPL") version 2 or any later version,
27
+ * in which case the provisions of the GPL are applicable instead of
28
+ * the above. If you wish to allow the use of your version of this file
29
+ * only under the terms of the GPL and not to allow others to use your
30
+ * version of this file under the BSD license, indicate your decision
31
+ * by deleting the provisions above and replace them with the notice
32
+ * and other provisions required by the GPL. If you do not delete the
33
+ * provisions above, a recipient may use your version of this file under
34
+ * either the BSD or the GPL.
35
+ */
36
+
37
+ #include "lzfP.h"
38
+
39
+ #define HSIZE (1 << (HLOG))
40
+
41
+ /*
42
+ * don't play with this unless you benchmark!
43
+ * the data format is not dependent on the hash function.
44
+ * the hash function might seem strange, just believe me,
45
+ * it works ;)
46
+ */
47
+ #ifndef FRST
48
+ # define FRST(p) (((p[0]) << 8) | p[1])
49
+ # define NEXT(v,p) (((v) << 8) | p[2])
50
+ # if ULTRA_FAST
51
+ # define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1))
52
+ # elif VERY_FAST
53
+ # define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
54
+ # else
55
+ # define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
56
+ # endif
57
+ #endif
58
+ /*
59
+ * IDX works because it is very similar to a multiplicative hash, e.g.
60
+ * ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1))
61
+ * the latter is also quite fast on newer CPUs, and compresses similarly.
62
+ *
63
+ * the next one is also quite good, albeit slow ;)
64
+ * (int)(cos(h & 0xffffff) * 1e6)
65
+ */
66
+
67
+ #if 0
68
+ /* original lzv-like hash function, much worse and thus slower */
69
+ # define FRST(p) (p[0] << 5) ^ p[1]
70
+ # define NEXT(v,p) ((v) << 5) ^ p[2]
71
+ # define IDX(h) ((h) & (HSIZE - 1))
72
+ #endif
73
+
74
+ #define MAX_LIT (1 << 5)
75
+ #define MAX_OFF (1 << 13)
76
+ #define MAX_REF ((1 << 8) + (1 << 3))
77
+
78
+ #if __GNUC__ >= 3
79
+ # define expect(expr,value) __builtin_expect ((expr),(value))
80
+ # define inline inline
81
+ #else
82
+ # define expect(expr,value) (expr)
83
+ # define inline static
84
+ #endif
85
+
86
+ #define expect_false(expr) expect ((expr) != 0, 0)
87
+ #define expect_true(expr) expect ((expr) != 0, 1)
88
+
89
+ /*
90
+ * compressed format
91
+ *
92
+ * 000LLLLL <L+1> ; literal, L+1=1..33 octets
93
+ * LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset
94
+ * 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset
95
+ *
96
+ */
97
+
98
+ unsigned int
99
+ lzf_compress (const void *const in_data, unsigned int in_len,
100
+ void *out_data, unsigned int out_len
101
+ #if LZF_STATE_ARG
102
+ , LZF_STATE htab
103
+ #endif
104
+ )
105
+ {
106
+ #if !LZF_STATE_ARG
107
+ LZF_STATE htab;
108
+ #endif
109
+ const u8 *ip = (const u8 *)in_data;
110
+ u8 *op = (u8 *)out_data;
111
+ const u8 *in_end = ip + in_len;
112
+ u8 *out_end = op + out_len;
113
+ const u8 *ref;
114
+
115
+ /* off requires a type wide enough to hold a general pointer difference.
116
+ * ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
117
+ * works for differences within a single object). We also assume that no
118
+ * no bit pattern traps. Since the only platform that is both non-POSIX
119
+ * and fails to support both assumptions is windows 64 bit, we make a
120
+ * special workaround for it.
121
+ */
122
+ #if defined (WIN32) && defined (_M_X64)
123
+ unsigned _int64 off; /* workaround for missing POSIX compliance */
124
+ #else
125
+ unsigned long off;
126
+ #endif
127
+ unsigned int hval;
128
+ int lit;
129
+
130
+ if (!in_len || !out_len)
131
+ return 0;
132
+
133
+ #if INIT_HTAB
134
+ memset (htab, 0, sizeof (htab));
135
+ #endif
136
+
137
+ lit = 0; op++; /* start run */
138
+
139
+ hval = FRST (ip);
140
+ while (ip < in_end - 2)
141
+ {
142
+ LZF_HSLOT *hslot;
143
+
144
+ hval = NEXT (hval, ip);
145
+ hslot = htab + IDX (hval);
146
+ ref = *hslot + LZF_HSLOT_BIAS; *hslot = ip - LZF_HSLOT_BIAS;
147
+
148
+ if (1
149
+ #if INIT_HTAB
150
+ && ref < ip /* the next test will actually take care of this, but this is faster */
151
+ #endif
152
+ && (off = ip - ref - 1) < MAX_OFF
153
+ && ref > (u8 *)in_data
154
+ && ref[2] == ip[2]
155
+ #if STRICT_ALIGN
156
+ && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0])
157
+ #else
158
+ && *(u16 *)ref == *(u16 *)ip
159
+ #endif
160
+ )
161
+ {
162
+ /* match found at *ref++ */
163
+ unsigned int len = 2;
164
+ unsigned int maxlen = in_end - ip - len;
165
+ maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
166
+
167
+ if (expect_false (op + 3 + 1 >= out_end)) /* first a faster conservative test */
168
+ if (op - !lit + 3 + 1 >= out_end) /* second the exact but rare test */
169
+ return 0;
170
+
171
+ op [- lit - 1] = lit - 1; /* stop run */
172
+ op -= !lit; /* undo run if length is zero */
173
+
174
+ for (;;)
175
+ {
176
+ if (expect_true (maxlen > 16))
177
+ {
178
+ len++; if (ref [len] != ip [len]) break;
179
+ len++; if (ref [len] != ip [len]) break;
180
+ len++; if (ref [len] != ip [len]) break;
181
+ len++; if (ref [len] != ip [len]) break;
182
+
183
+ len++; if (ref [len] != ip [len]) break;
184
+ len++; if (ref [len] != ip [len]) break;
185
+ len++; if (ref [len] != ip [len]) break;
186
+ len++; if (ref [len] != ip [len]) break;
187
+
188
+ len++; if (ref [len] != ip [len]) break;
189
+ len++; if (ref [len] != ip [len]) break;
190
+ len++; if (ref [len] != ip [len]) break;
191
+ len++; if (ref [len] != ip [len]) break;
192
+
193
+ len++; if (ref [len] != ip [len]) break;
194
+ len++; if (ref [len] != ip [len]) break;
195
+ len++; if (ref [len] != ip [len]) break;
196
+ len++; if (ref [len] != ip [len]) break;
197
+ }
198
+
199
+ do
200
+ len++;
201
+ while (len < maxlen && ref[len] == ip[len]);
202
+
203
+ break;
204
+ }
205
+
206
+ len -= 2; /* len is now #octets - 1 */
207
+ ip++;
208
+
209
+ if (len < 7)
210
+ {
211
+ *op++ = (off >> 8) + (len << 5);
212
+ }
213
+ else
214
+ {
215
+ *op++ = (off >> 8) + ( 7 << 5);
216
+ *op++ = len - 7;
217
+ }
218
+
219
+ *op++ = off;
220
+
221
+ lit = 0; op++; /* start run */
222
+
223
+ ip += len + 1;
224
+
225
+ if (expect_false (ip >= in_end - 2))
226
+ break;
227
+
228
+ #if ULTRA_FAST || VERY_FAST
229
+ --ip;
230
+ # if VERY_FAST && !ULTRA_FAST
231
+ --ip;
232
+ # endif
233
+ hval = FRST (ip);
234
+
235
+ hval = NEXT (hval, ip);
236
+ htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
237
+ ip++;
238
+
239
+ # if VERY_FAST && !ULTRA_FAST
240
+ hval = NEXT (hval, ip);
241
+ htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
242
+ ip++;
243
+ # endif
244
+ #else
245
+ ip -= len + 1;
246
+
247
+ do
248
+ {
249
+ hval = NEXT (hval, ip);
250
+ htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
251
+ ip++;
252
+ }
253
+ while (len--);
254
+ #endif
255
+ }
256
+ else
257
+ {
258
+ /* one more literal byte we must copy */
259
+ if (expect_false (op >= out_end))
260
+ return 0;
261
+
262
+ lit++; *op++ = *ip++;
263
+
264
+ if (expect_false (lit == MAX_LIT))
265
+ {
266
+ op [- lit - 1] = lit - 1; /* stop run */
267
+ lit = 0; op++; /* start run */
268
+ }
269
+ }
270
+ }
271
+
272
+ if (op + 3 > out_end) /* at most 3 bytes can be missing here */
273
+ return 0;
274
+
275
+ while (ip < in_end)
276
+ {
277
+ lit++; *op++ = *ip++;
278
+
279
+ if (expect_false (lit == MAX_LIT))
280
+ {
281
+ op [- lit - 1] = lit - 1; /* stop run */
282
+ lit = 0; op++; /* start run */
283
+ }
284
+ }
285
+
286
+ op [- lit - 1] = lit - 1; /* end run */
287
+ op -= !lit; /* undo run if length is zero */
288
+
289
+ return op - (u8 *)out_data;
290
+ }
291
+
@@ -0,0 +1,185 @@
1
+ /*
2
+ * Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without modifica-
5
+ * tion, are permitted provided that the following conditions are met:
6
+ *
7
+ * 1. Redistributions of source code must retain the above copyright notice,
8
+ * this list of conditions and the following disclaimer.
9
+ *
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
16
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
18
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
22
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
24
+ *
25
+ * Alternatively, the contents of this file may be used under the terms of
26
+ * the GNU General Public License ("GPL") version 2 or any later version,
27
+ * in which case the provisions of the GPL are applicable instead of
28
+ * the above. If you wish to allow the use of your version of this file
29
+ * only under the terms of the GPL and not to allow others to use your
30
+ * version of this file under the BSD license, indicate your decision
31
+ * by deleting the provisions above and replace them with the notice
32
+ * and other provisions required by the GPL. If you do not delete the
33
+ * provisions above, a recipient may use your version of this file under
34
+ * either the BSD or the GPL.
35
+ */
36
+
37
+ #include "lzfP.h"
38
+
39
+ #if AVOID_ERRNO
40
+ # define SET_ERRNO(n)
41
+ #else
42
+ # include <errno.h>
43
+ # define SET_ERRNO(n) errno = (n)
44
+ #endif
45
+
46
+ #if USE_REP_MOVSB /* small win on amd, big loss on intel */
47
+ #if (__i386 || __amd64) && __GNUC__ >= 3
48
+ # define lzf_movsb(dst, src, len) \
49
+ asm ("rep movsb" \
50
+ : "=D" (dst), "=S" (src), "=c" (len) \
51
+ : "0" (dst), "1" (src), "2" (len));
52
+ #endif
53
+ #endif
54
+
55
+ unsigned int
56
+ lzf_decompress (const void *const in_data, unsigned int in_len,
57
+ void *out_data, unsigned int out_len)
58
+ {
59
+ u8 const *ip = (const u8 *)in_data;
60
+ u8 *op = (u8 *)out_data;
61
+ u8 const *const in_end = ip + in_len;
62
+ u8 *const out_end = op + out_len;
63
+
64
+ do
65
+ {
66
+ unsigned int ctrl = *ip++;
67
+
68
+ if (ctrl < (1 << 5)) /* literal run */
69
+ {
70
+ ctrl++;
71
+
72
+ if (op + ctrl > out_end)
73
+ {
74
+ SET_ERRNO (E2BIG);
75
+ return 0;
76
+ }
77
+
78
+ #if CHECK_INPUT
79
+ if (ip + ctrl > in_end)
80
+ {
81
+ SET_ERRNO (EINVAL);
82
+ return 0;
83
+ }
84
+ #endif
85
+
86
+ #ifdef lzf_movsb
87
+ lzf_movsb (op, ip, ctrl);
88
+ #else
89
+ switch (ctrl)
90
+ {
91
+ case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++;
92
+ case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++;
93
+ case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++;
94
+ case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++;
95
+ case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++;
96
+ case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case 9: *op++ = *ip++;
97
+ case 8: *op++ = *ip++; case 7: *op++ = *ip++; case 6: *op++ = *ip++; case 5: *op++ = *ip++;
98
+ case 4: *op++ = *ip++; case 3: *op++ = *ip++; case 2: *op++ = *ip++; case 1: *op++ = *ip++;
99
+ }
100
+ #endif
101
+ }
102
+ else /* back reference */
103
+ {
104
+ unsigned int len = ctrl >> 5;
105
+
106
+ u8 *ref = op - ((ctrl & 0x1f) << 8) - 1;
107
+
108
+ #if CHECK_INPUT
109
+ if (ip >= in_end)
110
+ {
111
+ SET_ERRNO (EINVAL);
112
+ return 0;
113
+ }
114
+ #endif
115
+ if (len == 7)
116
+ {
117
+ len += *ip++;
118
+ #if CHECK_INPUT
119
+ if (ip >= in_end)
120
+ {
121
+ SET_ERRNO (EINVAL);
122
+ return 0;
123
+ }
124
+ #endif
125
+ }
126
+
127
+ ref -= *ip++;
128
+
129
+ if (op + len + 2 > out_end)
130
+ {
131
+ SET_ERRNO (E2BIG);
132
+ return 0;
133
+ }
134
+
135
+ if (ref < (u8 *)out_data)
136
+ {
137
+ SET_ERRNO (EINVAL);
138
+ return 0;
139
+ }
140
+
141
+ #ifdef lzf_movsb
142
+ len += 2;
143
+ lzf_movsb (op, ref, len);
144
+ #else
145
+ switch (len)
146
+ {
147
+ default:
148
+ len += 2;
149
+
150
+ if (op >= ref + len)
151
+ {
152
+ /* disjunct areas */
153
+ memcpy (op, ref, len);
154
+ op += len;
155
+ }
156
+ else
157
+ {
158
+ /* overlapping, use octte by octte copying */
159
+ do
160
+ *op++ = *ref++;
161
+ while (--len);
162
+ }
163
+
164
+ break;
165
+
166
+ case 9: *op++ = *ref++;
167
+ case 8: *op++ = *ref++;
168
+ case 7: *op++ = *ref++;
169
+ case 6: *op++ = *ref++;
170
+ case 5: *op++ = *ref++;
171
+ case 4: *op++ = *ref++;
172
+ case 3: *op++ = *ref++;
173
+ case 2: *op++ = *ref++;
174
+ case 1: *op++ = *ref++;
175
+ case 0: *op++ = *ref++; /* two octets more */
176
+ *op++ = *ref++;
177
+ }
178
+ #endif
179
+ }
180
+ }
181
+ while (ip < in_end);
182
+
183
+ return op - (u8 *)out_data;
184
+ }
185
+
@@ -0,0 +1,70 @@
1
+ #include <ruby.h>
2
+
3
+ #include "lib/lzf_c.c"
4
+ #include "lib/lzf_d.c"
5
+
6
+ static VALUE rb_mLZF;
7
+ static VALUE rb_eLZF;
8
+
9
+ static VALUE lzfruby_compress(int argc, VALUE *argv, VALUE self) {
10
+ VALUE src, dst;
11
+ unsigned int output_length, result;
12
+
13
+ rb_scan_args(argc, argv, "1", &src);
14
+
15
+ StringValue(src);
16
+
17
+ output_length = (unsigned int) (RSTRING_LEN(src) * 1.05);
18
+
19
+ dst = rb_str_new(NULL, output_length);
20
+
21
+ result = lzf_compress(RSTRING_PTR(src), RSTRING_LEN(src), RSTRING_PTR(dst), &output_length);
22
+ if (result == 0) {
23
+ rb_raise(rb_eLZF, "ERROR");
24
+ return Qnil;
25
+ } else {
26
+ StringValue(dst);
27
+ rb_str_resize(dst, result);
28
+ return dst;
29
+ }
30
+ }
31
+
32
+ static VALUE lzfruby_decompress(int argc, VALUE *argv, VALUE self) {
33
+ VALUE src, dst;
34
+ rb_scan_args(argc, argv, "1", &src);
35
+ StringValue(src);
36
+ unsigned int result, i = 1, buffer_size = 1024;
37
+
38
+ dst = rb_str_new(NULL, buffer_size);
39
+
40
+ // Pretty inefficient for large data, but PHP does it the same way
41
+ do {
42
+ buffer_size *= i++;
43
+ rb_str_resize(dst, buffer_size);
44
+ result = lzf_decompress(RSTRING_PTR(src), RSTRING_LEN(src), RSTRING_PTR(dst), buffer_size);
45
+ } while (result == 0 && errno == E2BIG);
46
+
47
+ if (result == 0) {
48
+ if (errno == EINVAL) {
49
+ rb_raise(rb_eLZF, "LZF error: compressed data corrupted");
50
+ return Qnil;
51
+ } else {
52
+ rb_raise(rb_eLZF, printf("LZF error %d", errno));
53
+ return Qnil;
54
+ }
55
+ } else {
56
+ StringValue(dst);
57
+ rb_str_resize(dst, result);
58
+ return dst;
59
+ }
60
+ }
61
+
62
+
63
+ void Init_lzf(void) {
64
+ rb_mLZF = rb_define_module("LZF");
65
+ rb_eLZF = rb_define_class_under(rb_mLZF, "Error", rb_eStandardError);
66
+
67
+ rb_define_singleton_method(rb_mLZF, "compress", lzfruby_compress, -1);
68
+ rb_define_singleton_method(rb_mLZF, "decompress", lzfruby_decompress, -1);
69
+ }
70
+
@@ -0,0 +1,3 @@
1
+ module Lzf
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'lzf/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "lzf"
8
+ spec.version = Lzf::VERSION
9
+ spec.authors = ["glebtv"]
10
+ spec.email = ["glebtv@gmail.com"]
11
+ spec.description = %q{LZF compression with liblzf for ruby}
12
+ spec.summary = %q{LZF compression with liblzf for ruby}
13
+ spec.homepage = "https://github.com/glebtv/lzf"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+
20
+ spec.extensions = ['ext/extconf.rb']
21
+
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ end
data/test.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'lzf'
2
+ require 'zlib'
3
+
4
+ Dir.glob('./test_data/*.lzf').each do |f|
5
+ hash = File.basename(f, '.lzf')
6
+ # puts hash
7
+ compressed = File.read(f)
8
+ decompressed = LZF.decompress(compressed)
9
+ # p decompressed
10
+ if Zlib.adler32(decompressed) != hash.to_f
11
+ puts "crc error: #{Zlib.adler32(decompressed)} != #{hash}"
12
+ puts decompressed
13
+ end
14
+
15
+ if LZF.decompress(LZF.compress(decompressed)) != decompressed
16
+ puts "#{hash} compressed != decompressed"
17
+ end
18
+ end
19
+
20
+ puts "all ok"
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lzf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - glebtv
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: LZF compression with liblzf for ruby
42
+ email:
43
+ - glebtv@gmail.com
44
+ executables: []
45
+ extensions:
46
+ - ext/extconf.rb
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - .ruby-gemset
51
+ - .ruby-version
52
+ - Gemfile
53
+ - LICENSE.txt
54
+ - README.md
55
+ - Rakefile
56
+ - ext/extconf.rb
57
+ - ext/lib/lzfP.h
58
+ - ext/lib/lzf_c.c
59
+ - ext/lib/lzf_d.c
60
+ - ext/lzf.c
61
+ - lib/lzf/version.rb
62
+ - lzf.gemspec
63
+ - test.rb
64
+ homepage: https://github.com/glebtv/lzf
65
+ licenses:
66
+ - MIT
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.0.3
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: LZF compression with liblzf for ruby
88
+ test_files: []