lzf 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []