diff --git a/src/modules/Gz/zlibmod.c b/src/modules/Gz/zlibmod.c index 06d41fe8ee24e0293e4b2b54b3a39c4d8659d394..8b989b18662d72110b874e10fc60937680f0d5a6 100644 --- a/src/modules/Gz/zlibmod.c +++ b/src/modules/Gz/zlibmod.c @@ -2,7 +2,7 @@ || 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. -|| $Id: zlibmod.c,v 1.72 2006/07/26 18:02:30 nilsson Exp $ +|| $Id: zlibmod.c,v 1.73 2006/08/02 16:19:08 nilsson Exp $ */ #include "global.h" @@ -174,6 +174,7 @@ static void gz_deflate_create(INT32 args) } } + static int do_deflate(dynamic_buffer *buf, struct zipper *this, int flush) @@ -211,6 +212,99 @@ static int do_deflate(dynamic_buffer *buf, return ret; } +static void free_pack(struct zipper *z) +{ + deflateEnd(&z->gz); + mt_destroy(&z->lock); + toss_buffer((dynamic_buffer *)z->gz.opaque); +} + +static void pack(struct pike_string *data, dynamic_buffer *buf, + int level, int strategy, int wbits) +{ + struct zipper z; + ONERROR err; + int ret; + + if(level < Z_NO_COMPRESSION || + level > Z_BEST_COMPRESSION) + Pike_error("Compression level out of range for pack. %d %d %d\n", + Z_DEFAULT_COMPRESSION, Z_NO_COMPRESSION, Z_BEST_COMPRESSION); + + if(strategy != Z_DEFAULT_STRATEGY && + strategy != Z_FILTERED && +#ifdef Z_RLE + strategy != Z_RLE && +#endif +#ifdef Z_FIXED + strategy != Z_FIXED && +#endif + strategy != Z_HUFFMAN_ONLY) + Pike_error("Invalid compression strategy %d for pack.\n", strategy); + + if( wbits!=15 && wbits!=-15 ) + Pike_error("Invalid wbits value %d for pack.\n", wbits); + + MEMSET(&z, 0, sizeof(z)); + z.gz.zalloc = Z_NULL; + z.gz.zfree = Z_NULL; + ret = deflateInit2(&z.gz, level, Z_DEFLATED, wbits, 9, strategy); + + switch(ret) + { + case Z_OK: + break; + + case Z_VERSION_ERROR: + Pike_error("libz not compatible with zlib.h!!!\n"); + break; + + default: + if(THIS->gz.msg) + Pike_error("Failed to initialize gz: %s\n",THIS->gz.msg); + else + Pike_error("Failed to initialize gz\n"); + } + + z.gz.next_in = (Bytef *)data->str; + z.gz.avail_in = (unsigned INT32)(data->len); + + initialize_buf(buf); + z.gz.opaque = buf; + mt_init(&z.lock); + + SET_ONERROR(err,free_pack,&z); + ret = do_deflate(buf, &z, Z_FINISH); + UNSET_ONERROR(err); + + deflateEnd(&z.gz); + mt_destroy(&z.lock); +} + +/* @decl string pack(string data, void|int(0..1) raw, void|int level,@ + * void|int strategy) + */ +static void gz_pack(INT32 args) +{ + struct pike_string *data; + dynamic_buffer buf; + + int wbits = 15; + int raw = 0; + int level = 8; + int strategy = Z_DEFAULT_STRATEGY; + + get_all_args("pack", args, "%n.%d%d%d", &data, &raw, &level, &strategy); + + if( raw ) + wbits = -wbits; + + pack(data, &buf, level, strategy, wbits); + + pop_n_elems(args); + push_string(low_free_buf(&buf)); +} + /*! @decl string deflate(string data, int|void flush) *! *! This function performs gzip style compression on a string @[data] and @@ -694,10 +788,13 @@ PIKE_MODULE_INIT #endif /* function(string,void|int:int) */ - ADD_FUNCTION("crc32",gz_crc32,tFunc(tStr tOr(tVoid,tInt),tInt), - OPT_TRY_OPTIMIZE); + ADD_FUNCTION("crc32",gz_crc32,tFunc(tStr tOr(tVoid,tInt),tInt),0); + + /* function(string,void|int(0..1),void|int,void|int:string) */ + ADD_FUNCTION("pack",gz_pack,tFunc(tStr tOr(tVoid,tInt01) tOr(tVoid,tInt) tOr(tVoid,tInt),tStr),0); PIKE_MODULE_EXPORT(Gz, crc32); + PIKE_MODULE_EXPORT(Gz, pack); #else if(!TEST_COMPAT(7,6)) HIDE_MODULE();