ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Compress-LZF/LZF.xs
(Generate patch)

Comparing Compress-LZF/LZF.xs (file contents):
Revision 1.23 by root, Fri Feb 16 22:11:17 2007 UTC vs.
Revision 1.31 by root, Sun Aug 25 18:13:26 2013 UTC

1#include "EXTERN.h" 1#include "EXTERN.h"
2#include "perl.h" 2#include "perl.h"
3#include "XSUB.h" 3#include "XSUB.h"
4 4
5/* try to be compatible with older perls */
6/* SvPV_nolen() macro first defined in 5.005_55 */
7/* this is slow, not threadsafe, but works */
8#include "patchlevel.h"
9#if (PATCHLEVEL == 4) || ((PATCHLEVEL == 5) && (SUBVERSION < 55))
10static STRLEN nolen_na;
11# define SvPV_nolen(sv) SvPV ((sv), nolen_na)
12#endif
13#if PATCHLEVEL < 6
14# define call_sv perl_call_sv
15#endif
16
17#define LZF_STANDALONE 1 5#define LZF_STANDALONE 1
18#define LZF_STATE_ARG 1 6#define LZF_STATE_ARG 1
19 7
20#include "lzf_c.c" 8#include "lzf_c.c"
21#include "lzf_d.c" 9#include "lzf_d.c"
10#include "lzf_c_best.c"
22 11
23/* we re-use the storable header for our purposes */ 12/* we re-use the storable header for our purposes */
24#define MAGIC_LO 0 13#define MAGIC_LO 0
25#define MAGIC_U 0 /* uncompressed data follows */ 14#define MAGIC_U 0 /* uncompressed data follows */
26#define MAGIC_C 1 /* compressed data follows */ 15#define MAGIC_C 1 /* compressed data follows */
42#else 31#else
43# define MAX_LENGTH ((Size_t) 0x8000000L) 32# define MAX_LENGTH ((Size_t) 0x8000000L)
44#endif 33#endif
45 34
46static SV * 35static SV *
47compress_sv (SV *data, char cprepend, int uprepend) 36compress_sv (SV *data, char cprepend, int uprepend, int best)
48{ 37{
49 LZF_STATE *state; 38 LZF_STATE *state;
50 STRLEN usize, csize; 39 STRLEN usize, csize;
51 char *src = (char *)SvPV (data, usize); 40 char *src = (char *)SvPVbyte (data, usize);
52 41
53 if (usize) 42 if (usize)
54 { 43 {
55 SV *ret = NEWSV (0, usize + 1); 44 SV *ret = NEWSV (0, usize + 1);
56 unsigned char *dst; 45 unsigned char *dst;
64 53
65 if (usize <= 0x7f) 54 if (usize <= 0x7f)
66 { 55 {
67 dst[skip++] = usize; 56 dst[skip++] = usize;
68 } 57 }
69 else if (usize <= 0x7ff) 58 else if (usize <= 0x7ff)
70 { 59 {
71 dst[skip++] = (( usize >> 6) | 0xc0); 60 dst[skip++] = (( usize >> 6) | 0xc0);
72 dst[skip++] = (( usize & 0x3f) | 0x80); 61 dst[skip++] = (( usize & 0x3f) | 0x80);
73 } 62 }
74 else if (usize <= 0xffff) 63 else if (usize <= 0xffff)
108 if (!state) 97 if (!state)
109 croak ("Compress::LZF unable to allocate memory for compression state"); 98 croak ("Compress::LZF unable to allocate memory for compression state");
110 99
111 /* 11 bytes is the smallest compressible string */ 100 /* 11 bytes is the smallest compressible string */
112 csize = usize < 11 ? 0 : 101 csize = usize < 11 ? 0 :
102 (best ? lzf_compress_best (src, usize, dst + skip, usize - skip)
113 lzf_compress (src, usize, dst + skip, usize - skip, *state); 103 : lzf_compress (src, usize, dst + skip, usize - skip, *state));
114 104
115 Safefree (state); 105 Safefree (state);
116 106
117 if (csize) 107 if (csize)
118 { 108 {
140 130
141static SV * 131static SV *
142decompress_sv (SV *data, int skip) 132decompress_sv (SV *data, int skip)
143{ 133{
144 STRLEN usize, csize; 134 STRLEN usize, csize;
145 unsigned char *src = (unsigned char *)SvPV (data, csize) + skip; 135 unsigned char *src = (unsigned char *)SvPVbyte (data, csize) + skip;
146 136
147 if (csize) 137 if (csize)
148 { 138 {
149 void *dst; 139 void *dst;
150 SV *ret; 140 SV *ret;
230 else 220 else
231 return newSVpvn ("", 0); 221 return newSVpvn ("", 0);
232} 222}
233 223
234static void 224static void
235need_storable(void) 225need_storable (void)
236{ 226{
237#if PATCHLEVEL < 6 227 eval_sv (sv_2mortal (newSVpvf ("require %s", SvPVbyte_nolen (serializer_package))), G_VOID | G_DISCARD);
238 char req[8192];
239 sprintf (req, "require %s;", SvPV_nolen (serializer_package));
240 perl_eval_pv (req, 1);
241#else
242 load_module (PERL_LOADMOD_NOIMPORT, serializer_package, Nullsv);
243#endif
244 228
245 storable_mstore = GvCV (gv_fetchpv (SvPV_nolen (serializer_mstore ), TRUE, SVt_PVCV)); 229 storable_mstore = (CV *)SvREFCNT_inc (GvCV (gv_fetchpv (SvPVbyte_nolen (serializer_mstore ), TRUE, SVt_PVCV)));
246 storable_mretrieve = GvCV (gv_fetchpv (SvPV_nolen (serializer_mretrieve), TRUE, SVt_PVCV)); 230 storable_mretrieve = (CV *)SvREFCNT_inc (GvCV (gv_fetchpv (SvPVbyte_nolen (serializer_mretrieve), TRUE, SVt_PVCV)));
247} 231}
248 232
249MODULE = Compress::LZF PACKAGE = Compress::LZF 233MODULE = Compress::LZF PACKAGE = Compress::LZF
250 234
251BOOT: 235BOOT:
261 PROTOTYPE: $$$ 245 PROTOTYPE: $$$
262 PPCODE: 246 PPCODE:
263 SvSetSV (serializer_package , package ); 247 SvSetSV (serializer_package , package );
264 SvSetSV (serializer_mstore , mstore ); 248 SvSetSV (serializer_mstore , mstore );
265 SvSetSV (serializer_mretrieve, mretrieve); 249 SvSetSV (serializer_mretrieve, mretrieve);
266 storable_mstore = 250 SvREFCNT_dec (storable_mstore ); storable_mstore = 0;
267 storable_mretrieve = 0; 251 SvREFCNT_dec (storable_mretrieve); storable_mretrieve = 0;
268 252
269void 253void
270compress(data) 254compress(data)
271 SV * data 255 SV * data
256 ALIAS:
257 compress_best = 1
272 PROTOTYPE: $ 258 PROTOTYPE: $
273 PPCODE: 259 PPCODE:
274 XPUSHs (sv_2mortal (compress_sv (data, 0, MAGIC_U))); 260 XPUSHs (sv_2mortal (compress_sv (data, 0, MAGIC_U, ix)));
275 261
276void 262void
277decompress(data) 263decompress(data)
278 SV * data 264 SV * data
279 PROTOTYPE: $ 265 PROTOTYPE: $
282 268
283void 269void
284sfreeze(sv) 270sfreeze(sv)
285 SV * sv 271 SV * sv
286 ALIAS: 272 ALIAS:
273 sfreeze = 0
287 sfreeze_cr = 1 274 sfreeze_cr = 1
288 sfreeze_c = 2 275 sfreeze_c = 2
276 sfreeze_best = 4
277 sfreeze_cr_best = 5
278 sfreeze_c_best = 6
289 PROTOTYPE: $ 279 PROTOTYPE: $
290 PPCODE: 280 PPCODE:
281{
282 int best = ix & 4;
283 ix &= 3;
291 284
292 SvGETMAGIC (sv); 285 SvGETMAGIC (sv);
293 286
294 if (!SvOK (sv)) 287 if (!SvOK (sv))
295 XPUSHs (sv_2mortal (newSVpvn ("\02", 1))); /* 02 == MAGIC_undef */ 288 XPUSHs (sv_2mortal (newSVpvn ("\02", 1))); /* 02 == MAGIC_undef */
296 else if (SvROK (sv) 289 else if (SvROK (sv)
290 || SvUTF8 (sv)
297 || (SvTYPE(sv) != SVt_IV 291 || (SvTYPE(sv) != SVt_IV
298 && SvTYPE(sv) != SVt_NV 292 && SvTYPE(sv) != SVt_NV
299 && SvTYPE(sv) != SVt_PV 293 && SvTYPE(sv) != SVt_PV
300 && SvTYPE(sv) != SVt_PVIV 294 && SvTYPE(sv) != SVt_PVIV
301 && SvTYPE(sv) != SVt_PVNV 295 && SvTYPE(sv) != SVt_PVNV
302 && SvTYPE(sv) != SVt_PVMG)) /* mstore */ 296 && SvTYPE(sv) != SVt_PVMG)) /* mstore */
303 { 297 {
304 int deref = !SvROK (sv); 298 int deref = !SvROK (sv);
299 char *pv;
305 300
306 if (!storable_mstore) 301 if (!storable_mstore)
302 {
303 PUTBACK;
307 need_storable (); 304 need_storable ();
305 SPAGAIN;
306 }
308 307
309 if (deref) 308 if (deref)
310 sv = newRV_noinc (sv); 309 sv = newRV_noinc (sv);
311 310
312 PUSHMARK (SP); 311 PUSHMARK (SP);
313 XPUSHs (sv); 312 XPUSHs (sv);
314 PUTBACK; 313 PUTBACK;
315 314
316 if (1 != call_sv ((SV *)storable_mstore, G_SCALAR)) 315 if (1 != call_sv ((SV *)storable_mstore, G_SCALAR))
317 croak ("Storable::mstore didn't return a single scalar"); 316 croak ("%s didn't return a single scalar", SvPVbyte_nolen (serializer_mstore));
318 317
319 SPAGAIN; 318 SPAGAIN;
320 319
321 sv = POPs; 320 sv = POPs;
321 pv = SvPV_nolen (sv);
322 322
323 if (SvPVX (sv)[0] == MAGIC_R) 323 if (*pv == MAGIC_R)
324 { 324 {
325 if (deref) 325 if (deref)
326 SvPVX (sv)[0] = MAGIC_R_deref; 326 *pv = MAGIC_R_deref;
327 } 327 }
328 else 328 else
329 { 329 {
330 char pfx[2]; 330 char pfx[2];
331 331
334 334
335 sv_insert (sv, 0, 0, pfx, 2); 335 sv_insert (sv, 0, 0, pfx, 2);
336 } 336 }
337 337
338 if (ix) /* compress */ 338 if (ix) /* compress */
339 sv = sv_2mortal (compress_sv (sv, deref ? MAGIC_CR_deref : MAGIC_CR, -1)); 339 sv = sv_2mortal (compress_sv (sv, deref ? MAGIC_CR_deref : MAGIC_CR, -1, best));
340 340
341 XPUSHs (sv); 341 XPUSHs (sv);
342 } 342 }
343 else if (SvPOKp (sv) && IN_RANGE (SvPVX (sv)[0], MAGIC_LO, MAGIC_HI)) 343 else if (SvPOKp (sv) && IN_RANGE (SvPVX (sv)[0], MAGIC_LO, MAGIC_HI))
344 XPUSHs (sv_2mortal (compress_sv (sv, MAGIC_C, MAGIC_U))); /* need to prefix only */ 344 XPUSHs (sv_2mortal (compress_sv (sv, MAGIC_C, MAGIC_U, best))); /* need to prefix only */
345 else if (ix == 2) /* compress always */ 345 else if (ix == 2) /* compress always */
346 XPUSHs (sv_2mortal (compress_sv (sv, MAGIC_C, -1))); 346 XPUSHs (sv_2mortal (compress_sv (sv, MAGIC_C, -1, best)));
347 else if (SvNIOK (sv)) /* don't compress */ 347 else if (SvNIOK (sv)) /* don't compress */
348 { 348 {
349 STRLEN len; 349 STRLEN len;
350 char *s = SvPV (sv, len); 350 char *s = SvPV (sv, len);
351 XPUSHs (sv_2mortal (newSVpvn (s, len))); 351 XPUSHs (sv_2mortal (newSVpvn (s, len)));
352 } 352 }
353 else /* don't compress */ 353 else /* don't compress */
354 XPUSHs (sv_2mortal (newSVsv (sv))); 354 XPUSHs (sv_2mortal (newSVsv (sv)));
355}
355 356
356void 357void
357sthaw(sv) 358sthaw(sv)
358 SV * sv 359 SV * sv
359 PROTOTYPE: $ 360 PROTOTYPE: $
361{ 362{
362 STRLEN svlen; 363 STRLEN svlen;
363 int deref = 0; 364 int deref = 0;
364 365
365 SvGETMAGIC (sv); 366 SvGETMAGIC (sv);
366 if (SvPOK (sv) && IN_RANGE (SvPV (sv, svlen)[0], MAGIC_LO, MAGIC_HI)) 367 if (SvPOK (sv) && IN_RANGE (SvPVbyte (sv, svlen)[0], MAGIC_LO, MAGIC_HI))
367 { 368 {
368 redo: 369 redo:
369 370
370 switch (SvPVX (sv)[0]) 371 switch (SvPVX (sv)[0])
371 { 372 {
380 croak ("Compress::LZF::sthaw(): invalid data, maybe you need a newer version of Compress::LZF?"); 381 croak ("Compress::LZF::sthaw(): invalid data, maybe you need a newer version of Compress::LZF?");
381 382
382 sv_chop (sv, SvPVX (sv) + 2); 383 sv_chop (sv, SvPVX (sv) + 2);
383 384
384 if (!storable_mstore) 385 if (!storable_mstore)
386 {
387 PUTBACK;
385 need_storable (); 388 need_storable ();
389 SPAGAIN;
390 }
386 391
387 PUSHMARK (SP); 392 PUSHMARK (SP);
388 XPUSHs (sv); 393 XPUSHs (sv);
389 PUTBACK; 394 PUTBACK;
390 395
391 if (1 != call_sv ((SV *)storable_mretrieve, G_SCALAR)) 396 if (1 != call_sv ((SV *)storable_mretrieve, G_SCALAR))
392 croak ("Storable::mstore didn't return a single scalar"); 397 croak ("%s didn't return a single scalar", SvPVbyte_nolen (serializer_mretrieve));
393 398
394 SPAGAIN; 399 SPAGAIN;
395 400
396 if (deref) 401 if (deref)
397 SETs (sv_2mortal (SvREFCNT_inc (SvRV (TOPs)))); 402 SETs (sv_2mortal (SvREFCNT_inc (SvRV (TOPs))));
424 goto redo; 429 goto redo;
425 430
426 case MAGIC_R: 431 case MAGIC_R:
427 handle_MAGIC_R: 432 handle_MAGIC_R:
428 if (!storable_mstore) 433 if (!storable_mstore)
434 {
435 PUTBACK;
429 need_storable (); 436 need_storable ();
437 SPAGAIN;
438 }
430 439
431 PUSHMARK (SP); 440 PUSHMARK (SP);
432 XPUSHs (sv); 441 XPUSHs (sv);
433 PUTBACK; 442 PUTBACK;
434 443
435 if (1 != call_sv ((SV *)storable_mretrieve, G_SCALAR)) 444 if (1 != call_sv ((SV *)storable_mretrieve, G_SCALAR))
436 croak ("Storable::mstore didn't return a single scalar"); 445 croak ("%s didn't return a single scalar", SvPVbyte_nolen (serializer_mretrieve));
437 446
438 SPAGAIN; 447 SPAGAIN;
439 448
440 if (deref) 449 if (deref)
441 { 450 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines