… | |
… | |
12 | #endif |
12 | #endif |
13 | #if PATCHLEVEL < 6 |
13 | #if PATCHLEVEL < 6 |
14 | # define call_sv perl_call_sv |
14 | # define call_sv perl_call_sv |
15 | #endif |
15 | #endif |
16 | |
16 | |
|
|
17 | #define LZF_STANDALONE 1 |
|
|
18 | #define LZF_STATE_ARG 1 |
|
|
19 | |
17 | #include "lzf_c.c" |
20 | #include "lzf_c.c" |
18 | #include "lzf_d.c" |
21 | #include "lzf_d.c" |
19 | |
22 | |
20 | /* we re-use the storable header for our purposes */ |
23 | /* we re-use the storable header for our purposes */ |
21 | #define MAGIC_LO 0 |
24 | #define MAGIC_LO 0 |
… | |
… | |
41 | #endif |
44 | #endif |
42 | |
45 | |
43 | static SV * |
46 | static SV * |
44 | compress_sv (SV *data, char cprepend, int uprepend) |
47 | compress_sv (SV *data, char cprepend, int uprepend) |
45 | { |
48 | { |
|
|
49 | LZF_STATE *state; |
46 | STRLEN usize, csize; |
50 | STRLEN usize, csize; |
47 | char *src = (char *)SvPV (data, usize); |
51 | char *src = (char *)SvPV (data, usize); |
48 | |
52 | |
49 | if (usize) |
53 | if (usize) |
50 | { |
54 | { |
… | |
… | |
98 | dst[skip++] = (( usize & 0x3f) | 0x80); |
102 | dst[skip++] = (( usize & 0x3f) | 0x80); |
99 | } |
103 | } |
100 | else |
104 | else |
101 | croak ("compress can only compress up to %ld bytes", 0x7fffffffL); |
105 | croak ("compress can only compress up to %ld bytes", 0x7fffffffL); |
102 | |
106 | |
|
|
107 | New (0, state, 1, LZF_STATE); |
|
|
108 | if (!state) |
|
|
109 | croak ("Compress::LZF unable to allocate memory for compression state"); |
|
|
110 | |
103 | /* 11 bytes is the smallest compressible string */ |
111 | /* 11 bytes is the smallest compressible string */ |
104 | csize = usize < 11 ? 0 : |
112 | csize = usize < 11 ? 0 : |
105 | lzf_compress (src, usize, |
113 | lzf_compress (src, usize, dst + skip, usize - skip, *state); |
106 | dst + skip, |
114 | |
107 | usize - skip); |
115 | Safefree (state); |
108 | |
116 | |
109 | if (csize) |
117 | if (csize) |
110 | { |
118 | { |
111 | SvCUR_set (ret, csize + skip); |
119 | SvCUR_set (ret, csize + skip); |
112 | } |
120 | } |
… | |
… | |
143 | |
151 | |
144 | csize -= skip; |
152 | csize -= skip; |
145 | |
153 | |
146 | if (src[0]) |
154 | if (src[0]) |
147 | { |
155 | { |
148 | if (!(src[0] & 0x80)) |
156 | if (!(src[0] & 0x80) && csize >= 1) |
149 | { |
157 | { |
150 | csize -= 1; |
158 | csize -= 1; |
151 | usize = *src++ & 0xff; |
159 | usize = *src++ & 0xff; |
152 | } |
160 | } |
153 | else if (!(src[0] & 0x20)) |
161 | else if (!(src[0] & 0x20) && csize >= 2) |
154 | { |
162 | { |
155 | csize -= 2; |
163 | csize -= 2; |
156 | usize = *src++ & 0x1f; |
164 | usize = *src++ & 0x1f; |
157 | usize = (usize << 6) | (*src++ & 0x3f); |
165 | usize = (usize << 6) | (*src++ & 0x3f); |
158 | } |
166 | } |
159 | else if (!(src[0] & 0x10)) |
167 | else if (!(src[0] & 0x10) && csize >= 3) |
160 | { |
168 | { |
161 | csize -= 3; |
169 | csize -= 3; |
162 | usize = *src++ & 0x0f; |
170 | usize = *src++ & 0x0f; |
163 | usize = (usize << 6) | (*src++ & 0x3f); |
171 | usize = (usize << 6) | (*src++ & 0x3f); |
164 | usize = (usize << 6) | (*src++ & 0x3f); |
172 | usize = (usize << 6) | (*src++ & 0x3f); |
165 | } |
173 | } |
166 | else if (!(src[0] & 0x08)) |
174 | else if (!(src[0] & 0x08) && csize >= 4) |
167 | { |
175 | { |
168 | csize -= 4; |
176 | csize -= 4; |
169 | usize = *src++ & 0x07; |
177 | usize = *src++ & 0x07; |
170 | usize = (usize << 6) | (*src++ & 0x3f); |
178 | usize = (usize << 6) | (*src++ & 0x3f); |
171 | usize = (usize << 6) | (*src++ & 0x3f); |
179 | usize = (usize << 6) | (*src++ & 0x3f); |
172 | usize = (usize << 6) | (*src++ & 0x3f); |
180 | usize = (usize << 6) | (*src++ & 0x3f); |
173 | } |
181 | } |
174 | else if (!(src[0] & 0x04)) |
182 | else if (!(src[0] & 0x04) && csize >= 5) |
175 | { |
183 | { |
176 | csize -= 5; |
184 | csize -= 5; |
177 | usize = *src++ & 0x03; |
185 | usize = *src++ & 0x03; |
178 | usize = (usize << 6) | (*src++ & 0x3f); |
186 | usize = (usize << 6) | (*src++ & 0x3f); |
179 | usize = (usize << 6) | (*src++ & 0x3f); |
187 | usize = (usize << 6) | (*src++ & 0x3f); |
180 | usize = (usize << 6) | (*src++ & 0x3f); |
188 | usize = (usize << 6) | (*src++ & 0x3f); |
181 | usize = (usize << 6) | (*src++ & 0x3f); |
189 | usize = (usize << 6) | (*src++ & 0x3f); |
182 | } |
190 | } |
183 | else if (!(src[0] & 0x02)) |
191 | else if (!(src[0] & 0x02) && csize >= 6) |
184 | { |
192 | { |
185 | csize -= 6; |
193 | csize -= 6; |
186 | usize = *src++ & 0x01; |
194 | usize = *src++ & 0x01; |
187 | usize = (usize << 6) | (*src++ & 0x3f); |
195 | usize = (usize << 6) | (*src++ & 0x3f); |
188 | usize = (usize << 6) | (*src++ & 0x3f); |
196 | usize = (usize << 6) | (*src++ & 0x3f); |
189 | usize = (usize << 6) | (*src++ & 0x3f); |
197 | usize = (usize << 6) | (*src++ & 0x3f); |
190 | usize = (usize << 6) | (*src++ & 0x3f); |
198 | usize = (usize << 6) | (*src++ & 0x3f); |
191 | usize = (usize << 6) | (*src++ & 0x3f); |
199 | usize = (usize << 6) | (*src++ & 0x3f); |
192 | } |
200 | } |
193 | else |
201 | else |
|
|
202 | croak ("compressed data corrupted (invalid length)"); |
|
|
203 | |
|
|
204 | if (!usize) |
194 | croak ("compressed data corrupted (invalid length)"); |
205 | croak ("compressed data corrupted (invalid length)"); |
195 | |
206 | |
196 | ret = NEWSV (0, usize); |
207 | ret = NEWSV (0, usize); |
197 | SvPOK_only (ret); |
208 | SvPOK_only (ret); |
198 | dst = SvPVX (ret); |
209 | dst = SvPVX (ret); |
199 | |
210 | |
200 | if (lzf_decompress (src, csize, dst, usize) != usize) |
211 | if (lzf_decompress (src, csize, dst, usize) != usize) |
|
|
212 | { |
|
|
213 | SvREFCNT_dec (ret); |
201 | croak ("compressed data corrupted (size mismatch)", csize, skip, usize); |
214 | croak ("compressed data corrupted (size mismatch)", csize, skip, usize); |
|
|
215 | } |
202 | } |
216 | } |
203 | else |
217 | else |
204 | { |
218 | { |
205 | usize = csize - 1; |
219 | usize = csize - 1; |
206 | ret = NEWSV (0, usize); |
220 | ret = NEWSV (0, usize | 1); |
207 | SvPOK_only (ret); |
221 | SvPOK_only (ret); |
208 | |
222 | |
209 | Move ((void *)(src + 1), (void *)SvPVX (ret), usize, unsigned char); |
223 | Move ((void *)(src + 1), (void *)SvPVX (ret), usize, unsigned char); |
210 | } |
224 | } |
211 | |
225 | |