This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Magic flags harmonization.
[perl5.git] / cpan / Compress-Raw-Zlib / Zlib.xs
index 4ed7c59..e57a38a 100644 (file)
@@ -3,7 +3,7 @@
  * Created : 22nd January 1996
  * Version : 2.000
  *
- *   Copyright (c) 1995-2010 Paul Marquess. All rights reserved.
+ *   Copyright (c) 1995-2012 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.
  *
@@ -44,6 +44,7 @@
 
 #if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1210
 #  define MAGIC_APPEND
+#  define AT_LEAST_ZLIB_1_2_1
 #endif
 
 #if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
 #  define AT_LEAST_ZLIB_1_2_3
 #endif
 
+#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1252
+/* 
+    Use Z_SOLO to build source means need own malloc/free
+ */
+#  define AT_LEAST_ZLIB_1_2_5_2
+#endif
+
 #ifdef USE_PPPORT_H
 #  define NEED_sv_2pvbyte
 #  define NEED_sv_2pv_nolen
@@ -482,6 +490,21 @@ DispStream(s, message)
     }
 }
 
+#ifdef AT_LEAST_ZLIB_1_2_5_2
+voidpf my_zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    return safemalloc(items * size);
+}
+
+
+void my_zcfree (voidpf opaque, voidpf ptr)
+{
+    safefree(ptr);
+    return; 
+}
+
+#endif
+
 static di_stream *
 #ifdef CAN_PROTOTYPE
 InitStream(void)
@@ -493,8 +516,12 @@ InitStream()
 
     ZMALLOC(s, di_stream) ;
 
+#ifdef AT_LEAST_ZLIB_1_2_5_2
+    s->stream.zalloc = my_zcalloc;
+    s->stream.zfree = my_zcfree;
+#endif
+
     return s ;
-    
 }
 
 static void
@@ -548,9 +575,8 @@ char * string;
             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 ;
 }
@@ -566,6 +592,7 @@ char * string ;
 {
     dTHX;
     bool wipe = 0 ;
+    STRLEN na;
     
     SvGETMAGIC(sv);
     wipe = ! SvOK(sv) ;
@@ -590,14 +617,11 @@ char * string ;
     if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
         croak("%s: buffer parameter is read-only", string);
 
-    SvUPGRADE(sv, SVt_PV);
-
+    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 ;
 }
 
@@ -637,10 +661,19 @@ ZLIB_VERNUM()
         RETVAL  = (ZLIB_VERSION[0] - '0') << 12 ;
         RETVAL += (ZLIB_VERSION[2] - '0') <<  8 ;
         RETVAL += (ZLIB_VERSION[4] - '0') <<  4 ;
+        if (strlen(ZLIB_VERSION) > 5)
+            RETVAL += (ZLIB_VERSION[6] - '0')  ;
 #endif
     OUTPUT:
         RETVAL
 
+
+#ifndef AT_LEAST_ZLIB_1_2_1
+#define zlibCompileFlags() 0
+#endif
+uLong
+zlibCompileFlags()
+
 MODULE = Compress::Raw::Zlib   PACKAGE = Compress::Raw::Zlib   PREFIX = Zip_
 
 #define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
@@ -669,13 +702,14 @@ Zip_adler32(buf, adler=adlerInitial)
     OUTPUT:
         RETVAL
  
-#define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len)
+#define Zip_crc32(buf, crc, offset) crc32(crc, buf+offset, (uInt)len-offset)
 
 uLong
-Zip_crc32(buf, crc=crcInitial)
+Zip_crc32(buf, crc=crcInitial, offset=0)
         uLong    crc = NO_INIT
         STRLEN   len = NO_INIT
         Bytef *  buf = NO_INIT
+        int      offset       
        SV *     sv = ST(0) ;
        INIT:
        /* If the buffer is a reference, dereference it */
@@ -692,8 +726,7 @@ Zip_crc32(buf, crc=crcInitial)
          crc = SvUV(ST(1)) ;
        else
          crc = crcInitial;
-
-
 uLong
 crc32_combine(crc1, crc2, len2)
         uLong    crc1 
@@ -756,15 +789,18 @@ _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dicti
         err = deflateInit2(&(s->stream), level, 
                           method, windowBits, memLevel, strategy);
 
+        if (trace) 
+            warn(" _deflateInit2 returned %d\n", err);
+
        /* 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)) ;
            s->dict_adler = s->stream.adler ;
        }
 
@@ -887,11 +923,11 @@ deflate (s, buf, output)
     Compress::Raw::Zlib::deflateStream s
     SV *       buf
     SV *       output 
-    uInt       cur_length = NO_INIT
-    uInt       increment = NO_INIT
-    uInt       prefix    = NO_INIT
-    int                RETVAL = 0;
-    uLong     bufinc = NO_INIT
+  PREINIT:
+    uInt       cur_length;
+    uInt       increment;
+    uInt       prefix;
+    uLong      bufinc;
   CODE:
     bufinc = s->bufsize;
 
@@ -903,7 +939,7 @@ deflate (s, buf, output)
     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.next_in = (Bytef*)SvPV_nomg_nolen(buf) ;
     s->stream.avail_in = SvCUR(buf) ;
     
     if (s->flags & FLAG_CRC32)
@@ -924,7 +960,7 @@ deflate (s, buf, output)
         /* 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
@@ -955,13 +991,14 @@ deflate (s, buf, output)
        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) ;
             cur_length += increment ;
-            s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
+            s->stream.next_out = (Bytef*) SvPVX(output) + cur_length ;
             increment = bufinc ;
             s->stream.avail_out = increment;
             bufinc *= 2 ;
@@ -1008,6 +1045,7 @@ flush(s, output, f=Z_FINISH)
     uInt       increment = NO_INIT
     uInt       prefix    = NO_INIT
     uLong     bufinc = NO_INIT
+    uLong     availableout = NO_INIT    
   CODE:
     bufinc = s->bufsize;
   
@@ -1024,7 +1062,7 @@ flush(s, output, f=Z_FINISH)
         /* 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
@@ -1057,17 +1095,24 @@ flush(s, output, f=Z_FINISH)
 #endif
 
     for (;;) {
-        if (s->stream.avail_out == 0) {
-           /* consumed all the available output, so extend it */
+        if (s->stream.avail_out == 0) {        
+            /* consumed all the available output, so extend it */
             Sv_Grow(output, SvLEN(output) + bufinc) ;
             cur_length += increment ;
-            s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
+            s->stream.next_out = (Bytef*) SvPVX(output) + cur_length ;
             increment = bufinc ;
             s->stream.avail_out = increment;
             bufinc *= 2 ;
         }
+        
+        availableout = s->stream.avail_out ;
+        
         RETVAL = deflate(&(s->stream), f);
     
+        /* Ignore the second of two consecutive flushes: */
+        if (availableout == s->stream.avail_out && RETVAL == Z_BUF_ERROR) 
+            RETVAL = Z_OK; 
+        
         /* deflate has finished flushing only when it hasn't used up
          * all the available space in the output buffer: 
          */
@@ -1274,12 +1319,11 @@ inflate (s, buf, output, eof=FALSE)
     SV *       buf
     SV *       output 
     bool       eof 
+  PREINIT:
     uInt       cur_length = 0;
     uInt       prefix_length = 0;
     int            increment = 0;
-    STRLEN  stmp    = NO_INIT
-    uLong     bufinc = NO_INIT
-  PREINIT:
+    uLong   bufinc;
 #ifdef UTF8_AVAILABLE    
     bool       out_utf8  = FALSE;
 #endif    
@@ -1296,7 +1340,7 @@ inflate (s, buf, output, eof=FALSE)
 #endif         
     
     /* initialise the input buffer */
-    s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
+    s->stream.next_in = (Bytef*)SvPV_nomg_nolen(buf) ;
     s->stream.avail_in = SvCUR(buf) ;
        
     /* and retrieve the output buffer */
@@ -1328,7 +1372,7 @@ inflate (s, buf, output, eof=FALSE)
         */
         if (SvLEN(output) > cur_length + 1)
         {
-            s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
+            s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
             increment = SvLEN(output) -  cur_length - 1;
             s->stream.avail_out = increment;
         }
@@ -1344,7 +1388,7 @@ inflate (s, buf, output, eof=FALSE)
            /* out of space in the output buffer so make it bigger */
             Sv_Grow(output, SvLEN(output) + bufinc +1) ;
             cur_length += increment ;
-            s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
+            s->stream.next_out = (Bytef*) SvPVX(output) + cur_length ;
             increment = bufinc ;
             s->stream.avail_out = increment;
             bufinc *= 2 ; 
@@ -1362,7 +1406,7 @@ Perl_sv_dump(output); */
         if (RETVAL == Z_NEED_DICT && s->dictionary) {
             s->dict_adler = s->stream.adler ;
             RETVAL = inflateSetDictionary(&(s->stream), 
-            (const Bytef*)SvPVbyte_nolen(s->dictionary),
+            (const Bytef*)SvPVX(s->dictionary),
             SvCUR(s->dictionary));
             if (RETVAL == Z_OK)
                 continue;
@@ -1395,7 +1439,7 @@ Perl_sv_dump(output); */
            /* out of space in the output buffer so make it bigger */
             Sv_Grow(output, SvLEN(output) + bufinc) ;
             cur_length += increment ;
-            s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
+            s->stream.next_out = (Bytef*) SvPVX(output) + cur_length ;
             increment = bufinc ;
             s->stream.avail_out = increment;
             bufinc *= 2 ;
@@ -1425,12 +1469,12 @@ Perl_sv_dump(output); */
 
         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 */
@@ -1438,7 +1482,7 @@ Perl_sv_dump(output); */
            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);
        }
@@ -1486,7 +1530,7 @@ inflateSync (s, buf)
 #endif         
     
     /* initialise the input buffer */
-    s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
+    s->stream.next_in = (Bytef*)SvPV_nomg_nolen(buf) ;
     s->stream.avail_in = SvCUR(buf) ;
        
     /* inflateSync doesn't create any output */
@@ -1501,7 +1545,7 @@ inflateSync (s, buf)
        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);
     }
@@ -1647,7 +1691,6 @@ scan(s, buf, out=NULL, eof=FALSE)
     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
@@ -1660,7 +1703,7 @@ scan(s, buf, out=NULL, eof=FALSE)
         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_nomg_nolen(buf) ;
     s->stream.avail_in = SvCUR(buf) ;
     start_len = s->stream.avail_in ;
     s->bytesInflated = 0 ; 
@@ -1745,9 +1788,9 @@ scan(s, buf, out=NULL, eof=FALSE)
             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