pike.git / src / modules / Gz / zlibmod.c

version» Context lines:

pike.git/src/modules/Gz/zlibmod.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information.   */      #include "global.h"   #include "zlib_machine.h"   #include "module.h"   #include "program.h" + #include "mapping.h"   #include "module_support.h"      #if !defined(HAVE_LIBZ) && !defined(HAVE_LIBGZ)   #undef HAVE_ZLIB_H   #endif      #ifdef HAVE_ZLIB_H      #include "interpret.h"   #include "svalue.h"
pike.git/src/modules/Gz/zlibmod.c:31:   #include <zlib.h>         #define sp Pike_sp      struct zipper   {    int level;    int state;    struct z_stream_s gz; -  struct pike_string *epilogue; +  struct pike_string *epilogue, *dict;   #ifdef _REENTRANT    DEFINE_MUTEX(lock);   #endif /* _REENTRANT */   };      #define BUF 32768   #define MAX_BUF (64*BUF)      #undef THIS   #define THIS ((struct zipper *)(Pike_fp->current_storage))
pike.git/src/modules/Gz/zlibmod.c:78:    *! @note    *! This class is only available if libz was available and found when    *! Pike was compiled.    *!    *! @seealso    *! @[Gz.inflate()]    */      /*! @decl void create(int(-9..9)|void level, int|void strategy,@    *! int(8..15)|void window_size) +  *! @decl void create(mapping options)    *!    *! This function can also be used to re-initialize a Gz.deflate object    *! so it can be re-used.    *! -  +  *! If a mapping is passed as the only argument, it will accept the +  *! parameters described below as indices, and additionally it accepts +  *! a @expr{string@} as @expr{dictionary@}. +  *!    *! @param level    *! Indicates the level of effort spent to make the data compress    *! well. Zero means no packing, 2-3 is considered 'fast', 6 is    *! default and higher is considered 'slow' but gives better    *! packing.    *!    *! If the argument is negative, no headers will be emitted. This is    *! needed to produce ZIP-files, as an example. The negative value    *! is then negated, and handled as a positive value.    *!
pike.git/src/modules/Gz/zlibmod.c:135:    int strategy = Z_DEFAULT_STRATEGY;    THIS->level=Z_DEFAULT_COMPRESSION;       if(THIS->gz.state)    {   /* mt_lock(& THIS->lock); */    deflateEnd(&THIS->gz);   /* mt_unlock(& THIS->lock); */    }    +  do_free_string(THIS->dict); +  THIS->dict = NULL; +     if(args>2)    {    if(TYPEOF(sp[2-args]) != T_INT)    Pike_error("Bad argument 3 to gz->create()\n");    wbits = sp[2-args].u.integer;    if( wbits == 0 ) wbits = 15;    if( wbits < 8 || wbits > 15 )    Pike_error("Invalid window size for gz_deflate->create().\n");    }    -  + #define TTS(type) (((type) == PIKE_T_STRING && "string") \ +  || ((type) == PIKE_T_MAPPING && "mapping")\ +  || ((type) == PIKE_T_ARRAY && "array") \ +  || ((type) == PIKE_T_FLOAT && "float") \ +  || ((type) == PIKE_T_INT && "int") \ +  || ((type) == PIKE_T_OBJECT && "object") \ +  || "mixed") + #define GET_TYPE(type, name) ((tmp = simple_mapping_string_lookup(m, name)) \ +  && (TYPEOF(*(tmp)) == PIKE_T_##type || (Pike_error("Expected type %s,"\ +  "got type %s for " name ".", TTS(PIKE_T_##type), TTS(TYPEOF(*tmp))), 0)))    if(args)    { -  +  if (TYPEOF(sp[-args]) == T_MAPPING && args == 1) { +  struct mapping *m = sp[-args].u.mapping; +  struct svalue *tmp; +  +  if (GET_TYPE(INT, "strategy")) strategy = tmp->u.integer; +  if (GET_TYPE(INT, "window_size")) +  { +  wbits = tmp->u.integer; +  if (wbits == 0) wbits = 15; +  if (wbits < 8 || wbits > 15) +  Pike_error("Invalid window size for gz_deflate->create().\n"); +  } +  if (GET_TYPE(STRING, "dictionary")) +  { +  if (tmp->u.string->size_shift) +  Pike_error("dictionary cannot be a wide string in " +  "gz_deflate->create().\n"); +  THIS->dict = tmp->u.string; +  add_ref(THIS->dict); +  } +  if (GET_TYPE(INT, "level")) +  { +  THIS->level = tmp->u.integer; +  goto LVL_CHECK; +  } +  } else {    if(TYPEOF(sp[-args]) != T_INT)    Pike_error("Bad argument 1 to gz->create()\n");    THIS->level=sp[-args].u.integer; -  + LVL_CHECK:    if( THIS->level < 0 )    {    wbits = -wbits;    THIS->level = -THIS->level;    }    if(THIS->level < Z_NO_COMPRESSION ||    THIS->level > Z_BEST_COMPRESSION)    { -  Pike_error("Compression level out of range for gz_deflate->create()\n"); +  Pike_error("Compression level out of range for " +  "gz_deflate->create()\n");    }    } -  +  }       if(args>1)    {    if(TYPEOF(sp[1-args]) != T_INT)    Pike_error("Bad argument 2 to gz->create()\n");    strategy=sp[1-args].u.integer;    if(strategy != Z_DEFAULT_STRATEGY &&    strategy != Z_FILTERED &&   #ifdef Z_RLE    strategy != Z_RLE &&
pike.git/src/modules/Gz/zlibmod.c:202:    else if (wbits == 8) wbits = 9;    else break;    continue;    }    break;    } while(1);   /* mt_unlock(& THIS->lock); */    switch(tmp)    {    case Z_OK: +  if (THIS->dict) { +  int err; +  err = deflateSetDictionary(&THIS->gz, (const Bytef*)THIS->dict->str, +  THIS->dict->len); +  if (err != Z_OK) { +  Pike_error("failed to set dictionary in deflate init.\n"); +  } +  }    return;       case Z_VERSION_ERROR:    Pike_error("libz not compatible with zlib.h!!!\n");    break;       case Z_MEM_ERROR:    Pike_error ("Out of memory while initializing Gz.deflate.\n");    break;   
pike.git/src/modules/Gz/zlibmod.c:553:    THIS->state=0;    deflateInit(& THIS->gz, THIS->level = Z_DEFAULT_COMPRESSION);    THIS->epilogue = NULL;   }      static void exit_gz_deflate(struct object *o)   {   /* mt_lock(& THIS->lock); */    deflateEnd(&THIS->gz);    do_free_string(THIS->epilogue); +  do_free_string(THIS->dict); +  THIS->dict = NULL;   /* mt_unlock(& THIS->lock); */    mt_destroy( & THIS->lock );   }      /*! @endclass    */      /*******************************************************************/      /*! @class inflate
pike.git/src/modules/Gz/zlibmod.c:576:    *!    *! @note    *! This program is only available if libz was available and found when    *! Pike was compiled.    *!    *! @seealso    *! @[deflate]    */      /*! @decl void create(int|void window_size) +  *! @decl void create(mapping options) +  *! +  *! If called with a mapping as only argument, @expr{create@} accepts +  *! the entries @expr{window_size@} (described below) and @expr{dictionary@}, +  *! which is a string to be set as dictionary. +  *!    *! The window_size value is passed down to inflateInit2 in zlib.    *!    *! If the argument is negative, no header checks are done, and no    *! verification of the data will be done either. This is needed for    *! uncompressing ZIP-files, as an example. The negative value is then    *! negated, and handled as a positive value.    *!    *! Positive arguments set the maximum dictionary size to an exponent    *! of 2, such that 8 (the minimum) will cause the window size to be    *! 256, and 15 (the maximum, and default value) will cause it to be
pike.git/src/modules/Gz/zlibmod.c:599:    *! It can be used to limit the amount of memory that is used to    *! uncompress files, but 32Kb is not all that much in the great    *! scheme of things.    *!    *! To decompress files compressed with level 9 compression, a 32Kb    *! window size is needed. level 1 compression only requires a 256    *! byte window.    */   static void gz_inflate_create(INT32 args)   { -  int tmp; +  int tmp, *tmp_p = &tmp;    if(THIS->gz.state)    {   /* mt_lock(& THIS->lock); */    inflateEnd(&THIS->gz);   /* mt_unlock(& THIS->lock); */    }          THIS->gz.zalloc=Z_NULL;    THIS->gz.zfree=Z_NULL;    THIS->gz.opaque=(void *)THIS; -  +  if( args && TYPEOF(Pike_sp[-1]) == PIKE_T_MAPPING) +  { +  struct mapping *m = Pike_sp[-1].u.mapping; +  struct svalue *tmp; +  +  if (GET_TYPE(STRING, "dictionary")) { +  if (tmp->u.string->size_shift) +  Pike_error("dictionary cannot be a wide string in " +  "gz_inflate->create().\n"); +  THIS->dict = tmp->u.string; +  add_ref(THIS->dict); +  } +  if (GET_TYPE(INT, "window_size")) +  *tmp_p=inflateInit2(& THIS->gz, tmp->u.integer); +  else +  *tmp_p=inflateInit( &THIS->gz ); +  } +  else +  {    if( args && TYPEOF(Pike_sp[-1]) == PIKE_T_INT )    {    tmp=inflateInit2(& THIS->gz, Pike_sp[-1].u.integer);    }    else    {    tmp=inflateInit( &THIS->gz );    } -  +  }    pop_n_elems(args);      /* mt_lock(& THIS->lock); */   /* mt_unlock(& THIS->lock); */    switch(tmp)    {    case Z_OK: -  + #if 0 /* this apparently works with newer zlibs only. */ +  if (THIS->dict) { +  int err; +  +  err = inflateSetDict(&THIS->gz, (const Bytef*)THIS->dict->str, +  THIS->dict->len); +  +  if (err != Z_OK) +  Pike_error("inflateSetDict on startup failed.\n"); +  } + #endif    return;       case Z_VERSION_ERROR:    Pike_error("libz not compatible with zlib.h!!!\n");    break;       case Z_MEM_ERROR:    Pike_error ("Out of memory while initializing Gz.inflate.\n");    break;   
pike.git/src/modules/Gz/zlibmod.c:699: Inside #if 0
   this->gz.avail_out,    this->gz.avail_in,    ret);   #endif       THREADS_DISALLOW();    low_make_buf_space(-((ptrdiff_t)this->gz.avail_out), buf);       if(ret == Z_BUF_ERROR) ret=Z_OK;    +  if (ret == Z_NEED_DICT && this->dict) +  ret = inflateSetDictionary(&this->gz, +  (const Bytef*)this->dict->str, +  this->dict->len); +     if(ret != Z_OK)    {    fail=ret;    break;    }    } while(!this->gz.avail_out || flush==Z_FINISH || this->gz.avail_in);    }      #ifdef _REENTRANT    CALL_AND_UNSET_ONERROR (uwp);
pike.git/src/modules/Gz/zlibmod.c:924:    inflateInit(&THIS->gz);    inflateEnd(&THIS->gz);    THIS->epilogue = NULL;   }      static void exit_gz_inflate(struct object *o)   {   /* mt_lock(& THIS->lock); */    inflateEnd(& THIS->gz);    do_free_string(THIS->epilogue); +  do_free_string(THIS->dict); +  THIS->dict = NULL;   /* mt_unlock(& THIS->lock); */    mt_destroy( & THIS->lock );   }      /*! @endclass    */      /*! @decl int crc32(string data, void|int start_value)    *!    *! This function calculates the standard ISO3309 Cyclic Redundancy Check.
pike.git/src/modules/Gz/zlibmod.c:979: Inside #if defined(HAVE_ZLIB_H)
  {   #ifdef HAVE_ZLIB_H    struct z_stream_s z; /* Used to detect support for extensions. */    int have_rle = 0;    int have_fixed = 0;       start_new_program();    ADD_STORAGE(struct zipper);       /* function(int|void,int|void:void) */ -  ADD_FUNCTION("create",gz_deflate_create,tFunc(tOr(tInt,tVoid) tOr(tInt,tVoid),tVoid),0); +  ADD_FUNCTION("create",gz_deflate_create,tFunc(tOr(tMapping, tOr(tInt,tVoid)) tOr(tInt,tVoid),tVoid),0);    /* function(string,int|void:string) */    ADD_FUNCTION("deflate",gz_deflate,tFunc(tStr tOr(tInt,tVoid),tStr),0);       add_integer_constant("NO_FLUSH",Z_NO_FLUSH,0);    add_integer_constant("PARTIAL_FLUSH",Z_PARTIAL_FLUSH,0);    add_integer_constant("SYNC_FLUSH",Z_SYNC_FLUSH,0);    add_integer_constant("FINISH",Z_FINISH,0);    add_integer_constant("DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY,0);    add_integer_constant("FILTERED", Z_FILTERED,0);    add_integer_constant("HUFFMAN_ONLY", Z_HUFFMAN_ONLY,0);
pike.git/src/modules/Gz/zlibmod.c:1016: Inside #if defined(HAVE_ZLIB_H)
      set_init_callback(init_gz_deflate);    set_exit_callback(exit_gz_deflate);       end_class("deflate",0);       start_new_program();    ADD_STORAGE(struct zipper);       /* function(int|void:void) */ -  ADD_FUNCTION("create",gz_inflate_create,tFunc(tOr(tInt,tVoid),tVoid),0); +  ADD_FUNCTION("create",gz_inflate_create,tFunc(tOr(tMapping,tOr(tInt,tVoid)),tVoid),0);    /* function(string:string) */    ADD_FUNCTION("inflate",gz_inflate,tFunc(tStr,tStr),0);    /* function(:string) */    ADD_FUNCTION("end_of_stream",gz_end_of_stream,tFunc(tNone,tStr),0);       add_integer_constant("NO_FLUSH",Z_NO_FLUSH,0);    add_integer_constant("PARTIAL_FLUSH",Z_PARTIAL_FLUSH,0);    add_integer_constant("SYNC_FLUSH",Z_SYNC_FLUSH,0);    add_integer_constant("FINISH",Z_FINISH,0);