* Created : 22nd January 1996
* Version : 2.000
*
- * Copyright (c) 1995-2010 Paul Marquess. All rights reserved.
+ * Copyright (c) 1995-2013 Paul Marquess. All rights reserved.
* This program is free software; you can redistribute it and/or
* modify it under the same terms as Perl itself.
*
*/
-
+#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
# define AT_LEAST_ZLIB_1_2_5_2
#endif
+#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1280
+# define AT_LEAST_ZLIB_1_2_8
+#endif
+
#ifdef USE_PPPORT_H
# define NEED_sv_2pvbyte
# define NEED_sv_2pv_nolen
+# define NEED_sv_pvn_force_flags
# include "ppport.h"
#endif
static void
#ifdef CAN_PROTOTYPE
-DispStream(di_stream * s, char * message)
+DispStream(di_stream * s, const char * message)
#else
DispStream(s, message)
di_stream * s;
- char * message;
+ const char * message;
#endif
{
#define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
- printf("DispStream 0x%p", s) ;
+ printf("DispStream %p", s) ;
if (message)
printf("- %s \n", message) ;
printf("\n") ;
printf(" stream pointer is NULL\n");
}
else {
- printf(" stream 0x%p\n", &(s->stream));
- printf(" zalloc 0x%p\n", s->stream.zalloc);
- printf(" zfree 0x%p\n", s->stream.zfree);
- printf(" opaque 0x%p\n", s->stream.opaque);
+ printf(" stream %p\n", &(s->stream));
+ printf(" zalloc %p\n", s->stream.zalloc);
+ printf(" zfree %p\n", s->stream.zfree);
+ printf(" opaque %p\n", s->stream.opaque);
+ printf(" state %p\n", s->stream.state);
if (s->stream.msg)
printf(" msg %s\n", s->stream.msg);
else
printf(" msg \n");
- printf(" next_in 0x%p", s->stream.next_in);
+ printf(" next_in %p", s->stream.next_in);
if (s->stream.next_in){
printf(" =>");
DispHex(s->stream.next_in, 4);
}
printf("\n");
- printf(" next_out 0x%p", s->stream.next_out);
+ printf(" next_out %p", s->stream.next_out);
if (s->stream.next_out){
printf(" =>");
DispHex(s->stream.next_out, 4);
printf(" total_out %ld\n", s->stream.total_out);
printf(" adler %ld\n", s->stream.adler );
printf(" bufsize %ld\n", s->bufsize);
- printf(" dictionary 0x%p\n", s->dictionary);
+ printf(" dictionary %p\n", s->dictionary);
printf(" dict_adler 0x%ld\n",s->dict_adler);
printf(" zip_mode %d\n", s->zip_mode);
printf(" crc32 0x%x\n", (unsigned)s->crc32);
#ifdef MAGIC_APPEND
- printf(" window 0x%p\n", s->window);
+ printf(" window %p\n", s->window);
#endif
printf("\n");
croak("%s: buffer parameter is a reference to a reference", string) ;
}
- if (!SvOK(sv)) {
- sv = newSVpv("", 0);
- }
+ if (!SvOK(sv))
+ sv = sv_2mortal(newSVpv("", 0));
return sv ;
}
{
dTHX;
bool wipe = 0 ;
+ STRLEN na;
SvGETMAGIC(sv);
wipe = ! SvOK(sv) ;
SvUPGRADE(sv, SVt_PV);
if (wipe)
- SvCUR_set(sv, 0);
-
- SvOOK_off(sv);
- SvPOK_only(sv);
+ sv_setpv(sv, "") ;
+ else
+ (void)SvPVbyte_force(sv, na) ;
return sv ;
}
err = deflateInit2(&(s->stream), level,
method, windowBits, memLevel, strategy);
- if (trace)
- warn(" _deflateInit2 returned %d\n", err);
+ if (trace) {
+ warn(" _deflateInit2 returned %d (state %p)\n", err, s);
+ DispStream(s, "INIT");
+ }
/* Check if a dictionary has been specified */
-
- if (err == Z_OK && SvCUR(dictionary)) {
+ SvGETMAGIC(dictionary);
+ if (err == Z_OK && SvPOK(dictionary) && SvCUR(dictionary)) {
#ifdef UTF8_AVAILABLE
- if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
- croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
+ if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
+ croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
#endif
- err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVbyte_nolen(dictionary),
- SvCUR(dictionary)) ;
+ err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary), SvCUR(dictionary)) ;
+ if (trace)
+ warn("deflateSetDictionary returned %d\n", err);
s->dict_adler = s->stream.adler ;
}
Safefree(s) ;
s = NULL ;
}
- else if (SvCUR(dictionary)) {
+ else if (sv_len(dictionary)) {
#ifdef AT_LEAST_ZLIB_1_2_2_1
/* Zlib 1.2.2.1 or better allows a dictionary with raw inflate */
if (s->WindowBits < 0) {
+ STRLEN dlen;
+ const Bytef* b = (const Bytef*)SvPVbyte(dictionary, dlen);
err = inflateSetDictionary(&(s->stream),
- (const Bytef*)SvPVbyte_nolen(dictionary),
- SvCUR(dictionary));
+ b, dlen);
if (err != Z_OK) {
Safefree(s) ;
s = NULL ;
}
}
else
-#endif
+#endif
/* Dictionary specified - take a copy for use in inflate */
s->dictionary = newSVsv(dictionary) ;
}
void
DispStream(s, message=NULL)
Compress::Raw::Zlib::deflateStream s
- char * message
+ const char * message
DualType
deflateReset(s)
uInt prefix = NO_INIT
int RETVAL = 0;
uLong bufinc = NO_INIT
+ STRLEN origlen = NO_INIT
CODE:
bufinc = s->bufsize;
if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
#endif
- s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
- s->stream.avail_in = SvCUR(buf) ;
+ s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
+ s->stream.avail_in = origlen;
if (s->flags & FLAG_CRC32)
s->crc32 = crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
/* sv_setpvn(output, "", 0); */
}
prefix = cur_length = SvCUR(output) ;
- s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
+ s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
increment = SvLEN(output) - cur_length;
s->stream.avail_out = increment;
#ifdef SETP_BYTE
s->deflateParams_out_length = 0;
}
#endif
+ RETVAL = Z_OK ;
while (s->stream.avail_in != 0) {
if (s->stream.avail_out == 0) {
/* out of space in the output buffer so make it bigger */
- Sv_Grow(output, SvLEN(output) + bufinc) ;
+ s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
cur_length += increment ;
- s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
+ s->stream.next_out += cur_length ;
increment = bufinc ;
s->stream.avail_out = increment;
bufinc *= 2 ;
}
+ if (trace) {
+ printf("DEFLATE Avail In %d, Out %d\n", s->stream.avail_in, s->stream.avail_out);
+ DispStream(s, "BEFORE");
+ /* Perl_sv_dump(output); */
+ }
+
RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
+
+ if (trace) {
+ printf("DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
+ GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out);
+ DispStream(s, "AFTER");
+ }
+
if (RETVAL != Z_OK)
break;
}
s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
- s->uncompressedBytes += SvCUR(buf) - s->stream.avail_in ;
+ s->uncompressedBytes += origlen - s->stream.avail_in ;
s->last_error = RETVAL ;
if (RETVAL == Z_OK) {
DESTROY(s)
Compress::Raw::Zlib::deflateStream s
CODE:
+ if (trace)
+ printf("Compress::Raw::Zlib::deflateStream::DESTROY %p\n", s);
deflateEnd(&s->stream) ;
if (s->dictionary)
SvREFCNT_dec(s->dictionary) ;
/* sv_setpvn(output, "", 0); */
}
prefix = cur_length = SvCUR(output) ;
- s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
+ s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
increment = SvLEN(output) - cur_length;
s->stream.avail_out = increment;
#ifdef SETP_BYTE
for (;;) {
if (s->stream.avail_out == 0) {
/* consumed all the available output, so extend it */
- Sv_Grow(output, SvLEN(output) + bufinc) ;
+ s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
cur_length += increment ;
- s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
+ s->stream.next_out += cur_length ;
increment = bufinc ;
s->stream.avail_out = increment;
bufinc *= 2 ;
availableout = s->stream.avail_out ;
+ if (trace) {
+ printf("flush (%d) DEFLATE Avail In %d, Out %d\n", f, s->stream.avail_in, s->stream.avail_out);
+ DispStream(s, "BEFORE");
+ /* Perl_sv_dump(output); */
+ }
+
RETVAL = deflate(&(s->stream), f);
+ if (trace) {
+ printf("flush DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
+ GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out);
+ DispStream(s, "AFTER");
+ }
+
/* Ignore the second of two consecutive flushes: */
if (availableout == s->stream.avail_out && RETVAL == Z_BUF_ERROR)
RETVAL = Z_OK;
void
DispStream(s, message=NULL)
Compress::Raw::Zlib::inflateStream s
- char * message
+ const char * message
DualType
inflateReset(s)
uInt cur_length = 0;
uInt prefix_length = 0;
int increment = 0;
- STRLEN stmp = NO_INIT
- uLong bufinc = NO_INIT
+ uLong bufinc = NO_INIT
+ STRLEN na = NO_INIT ;
PREINIT:
#ifdef UTF8_AVAILABLE
bool out_utf8 = FALSE;
#endif
- CODE:
+ STRLEN origlen;
+ CODE:
bufinc = s->bufsize;
/* If the buffer is a reference, dereference it */
buf = deRef(buf, "inflate") ;
- if (s->flags & FLAG_CONSUME_INPUT && SvREADONLY(buf))
- croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
+ if (s->flags & FLAG_CONSUME_INPUT) {
+ if (SvREADONLY(buf))
+ croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
+ SvPV_force(buf, na);
+ }
#ifdef UTF8_AVAILABLE
if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
#endif
/* initialise the input buffer */
- s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
- s->stream.avail_in = SvCUR(buf) ;
+ s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
+ s->stream.avail_in = origlen ;
/* and retrieve the output buffer */
output = deRef_l(output, "inflate") ;
*/
if (SvLEN(output) > cur_length + 1)
{
- s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
+ s->stream.next_out = (Bytef*) SvPV_nomg_nolen(output) + cur_length;
increment = SvLEN(output) - cur_length - 1;
s->stream.avail_out = increment;
}
while (RETVAL == Z_OK) {
if (s->stream.avail_out == 0) {
/* out of space in the output buffer so make it bigger */
- Sv_Grow(output, SvLEN(output) + bufinc +1) ;
+ s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc +1) ;
cur_length += increment ;
- s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
+ s->stream.next_out += cur_length ;
increment = bufinc ;
s->stream.avail_out = increment;
bufinc *= 2 ;
if (RETVAL == Z_NEED_DICT && s->dictionary) {
+ STRLEN dlen;
+ const Bytef* b = (const Bytef*)SvPV(s->dictionary, dlen) ;
s->dict_adler = s->stream.adler ;
RETVAL = inflateSetDictionary(&(s->stream),
- (const Bytef*)SvPVbyte_nolen(s->dictionary),
- SvCUR(s->dictionary));
+ b, dlen);
if (RETVAL == Z_OK)
continue;
}
if (s->flags & FLAG_LIMIT_OUTPUT &&
+ (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR )) {
+ if (s->stream.avail_out == 0)
+ RETVAL = Z_BUF_ERROR;
+ break;
+ }
+ if (s->flags & FLAG_LIMIT_OUTPUT &&
(RETVAL == Z_OK || RETVAL == Z_BUF_ERROR ))
break;
s->stream.avail_in = 1;
if (s->stream.avail_out == 0) {
/* out of space in the output buffer so make it bigger */
- Sv_Grow(output, SvLEN(output) + bufinc) ;
+ s->stream.next_out = Sv_Grow(output, SvLEN(output) + bufinc) ;
cur_length += increment ;
- s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
+ s->stream.next_out += cur_length ;
increment = bufinc ;
s->stream.avail_out = increment;
bufinc *= 2 ;
s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
s->uncompressedBytes += s->bytesInflated ;
- s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
+ s->compressedBytes += origlen - s->stream.avail_in ;
SvPOK_only(output);
SvCUR_set(output, prefix_length + s->bytesInflated) ;
if (s->flags & FLAG_CRC32 )
s->crc32 = crc32(s->crc32,
- (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
+ (const Bytef*)SvPVX(output)+prefix_length,
SvCUR(output)-prefix_length) ;
if (s->flags & FLAG_ADLER32)
s->adler32 = adler32(s->adler32,
- (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
+ (const Bytef*)SvPVX(output)+prefix_length,
SvCUR(output)-prefix_length) ;
/* fix the input buffer */
in = s->stream.avail_in ;
SvCUR_set(buf, in) ;
if (in)
- Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
+ Move(s->stream.next_in, SvPVX(buf), in, char) ;
*SvEND(buf) = '\0';
SvSETMAGIC(buf);
}
#endif
/* initialise the input buffer */
- s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
+ s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
s->stream.avail_in = SvCUR(buf) ;
/* inflateSync doesn't create any output */
unsigned in = s->stream.avail_in ;
SvCUR_set(buf, in) ;
if (in)
- Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
+ Move(s->stream.next_in, SvPVX(buf), in, char) ;
*SvEND(buf) = '\0';
SvSETMAGIC(buf);
}
void
DispStream(s, message=NULL)
Compress::Raw::Zlib::inflateScanStream s
- char * message
+ const char * message
DualType
inflateReset(s)
bool eof
bool eof_mode = FALSE;
int start_len = NO_INIT
- STRLEN stmp = NO_INIT
CODE:
/* If the input buffer is a reference, dereference it */
#ifndef MAGIC_APPEND
croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
#endif
/* initialise the input buffer */
- s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
+ s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
s->stream.avail_in = SvCUR(buf) ;
start_len = s->stream.avail_in ;
s->bytesInflated = 0 ;
unsigned in = s->stream.avail_in ;
SvCUR_set(buf, in) ;
if (in)
- Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
- *SvEND(buf) = '\0';
- SvSETMAGIC(buf);
+ Move(s->stream.next_in, SvPVX(buf), in, char) ;
+ *SvEND(buf) = '\0';
+ SvSETMAGIC(buf);
}
}
#endif