ab6aec1997-02-11Fredrik Hübinette (Hubbe) /*\ ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License) ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h"
3164751998-04-30Henrik Grubbström (Grubba) RCSID("$Id: zlibmod.c,v 1.20 1998/04/29 23:17:24 grubba Exp $");
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  #include "zlib_machine.h" #if !defined(HAVE_LIBZ) && !defined(HAVE_LIBGZ) #undef HAVE_ZLIB_H #endif #ifdef HAVE_ZLIB_H #include "interpret.h" #include "svalue.h" #include "stralloc.h" #include "array.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
ab6aec1997-02-11Fredrik Hübinette (Hubbe) #include "program.h" #include "stralloc.h" #include "object.h" #include "pike_types.h" #include "threads.h" #include "dynamic_buffer.h" #include <zlib.h> struct zipper { struct z_stream_s gz;
e0c81f1997-03-22Henrik Grubbström (Grubba) #ifdef _REENTRANT
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  DEFINE_MUTEX(lock);
e0c81f1997-03-22Henrik Grubbström (Grubba) #endif /* _REENTRANT */
ab6aec1997-02-11Fredrik Hübinette (Hubbe) };
1d90b91997-11-11Henrik Grubbström (Grubba) #define BUF 32768
d7288e1997-11-11Henrik Grubbström (Grubba) #define MAX_BUF (64*BUF)
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  #define THIS ((struct zipper *)(fp->current_storage)) static void gz_deflate_create(INT32 args) { int level=Z_DEFAULT_COMPRESSION; if(THIS->gz.state) {
7260951997-09-01Per Hedbor /* mt_lock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  deflateEnd(&THIS->gz);
7260951997-09-01Per Hedbor /* mt_unlock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  } if(args) { if(sp[-args].type != T_INT) error("Bad argument 1 to gz->create()\n");
6c61dc1997-07-19Fredrik Hübinette (Hubbe)  level=sp[-args].u.integer; if(level < Z_NO_COMPRESSION || level > Z_BEST_COMPRESSION)
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  { error("Compression level out of range for gz_deflate->create()\n"); } } THIS->gz.zalloc=Z_NULL; THIS->gz.zfree=Z_NULL;
3164751998-04-30Henrik Grubbström (Grubba)  THIS->gz.opaque=(void *)THIS;
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  pop_n_elems(args);
7260951997-09-01Per Hedbor /* mt_lock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  level=deflateInit(&THIS->gz, level);
7260951997-09-01Per Hedbor /* mt_unlock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  switch(level) { case Z_OK: return; case Z_VERSION_ERROR: error("libz not compatible with zlib.h!!!\n"); break; default: if(THIS->gz.msg) error("Failed to initialize gz_deflate: %s\n",THIS->gz.msg); else error("Failed to initialize gz_deflate\n"); } } static int do_deflate(dynamic_buffer *buf, struct zipper *this, int flush) { int fail=0; THREADS_ALLOW(); mt_lock(& this->lock);
00ad361997-10-21Henrik Grubbström (Grubba)  THREADS_DISALLOW();
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  if(!this->gz.state) { fail=Z_STREAM_ERROR; }else{ do
7260951997-09-01Per Hedbor  { char *loc; int ret; loc=low_make_buf_space(BUF,buf); this->gz.next_out=(Bytef *)loc; this->gz.avail_out=BUF;
d7288e1997-11-11Henrik Grubbström (Grubba)  while (1) { THREADS_ALLOW(); ret=deflate(& this->gz, flush); THREADS_DISALLOW(); if ((ret != Z_BUF_ERROR) || (this->gz.avail_out > MAX_BUF)) { break; } low_make_buf_space(BUF, buf); this->gz.avail_out += BUF; }
7260951997-09-01Per Hedbor  low_make_buf_space(-this->gz.avail_out,buf); if(ret != Z_OK)
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  {
7260951997-09-01Per Hedbor  fail=ret; break; } } while(!this->gz.avail_out || flush==Z_FINISH || this->gz.avail_in);
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  } mt_unlock(& this->lock); return fail; } static void gz_deflate(INT32 args) { struct pike_string *data; int flush, fail; struct zipper *this=THIS; dynamic_buffer buf; if(!THIS->gz.state) error("gz_deflate not initialized or destructed\n"); initialize_buf(&buf); if(args<1) error("Too few arguments to gz_deflate->deflate()\n"); if(sp[-args].type != T_STRING) error("Bad argument 1 to gz_deflate->deflate()\n"); data=sp[-args].u.string; if(args>1) { if(sp[1-args].type != T_INT) error("Bad argument 2 to gz_deflate->deflate()\n"); flush=sp[1-args].u.integer; switch(flush) { case Z_PARTIAL_FLUSH: case Z_FINISH: case Z_SYNC_FLUSH: case Z_NO_FLUSH: break;
8d36d51998-02-27Mirar (Pontus Hagland)  default:
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  error("Argument 2 to gz_deflate->deflate() out of range.\n"); } }else{ flush=Z_FINISH; } this->gz.next_in=(Bytef *)data->str; this->gz.avail_in=data->len; fail=do_deflate(&buf,this,flush); pop_n_elems(args); if(fail != Z_OK && fail != Z_STREAM_END) { free(buf.s.str); if(THIS->gz.msg) error("Error in gz_deflate->deflate(): %s\n",THIS->gz.msg); else error("Error in gz_deflate->deflate(): %d\n",fail); } push_string(low_free_buf(&buf)); } static void init_gz_deflate(struct object *o) {
2383021997-02-27Fredrik Hübinette (Hubbe)  mt_init(& THIS->lock);
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  MEMSET(& THIS->gz, 0, sizeof(THIS->gz)); THIS->gz.zalloc=Z_NULL; THIS->gz.zfree=Z_NULL;
3164751998-04-30Henrik Grubbström (Grubba)  THIS->gz.opaque=(void *)THIS;
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  deflateInit(& THIS->gz, Z_DEFAULT_COMPRESSION); } static void exit_gz_deflate(struct object *o) {
7260951997-09-01Per Hedbor /* mt_lock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  deflateEnd(&THIS->gz);
7260951997-09-01Per Hedbor /* mt_unlock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe) } /*******************************************************************/ static void gz_inflate_create(INT32 args) { int tmp; if(THIS->gz.state) {
7260951997-09-01Per Hedbor /* mt_lock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  inflateEnd(&THIS->gz);
7260951997-09-01Per Hedbor /* mt_unlock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  } THIS->gz.zalloc=Z_NULL; THIS->gz.zfree=Z_NULL;
3164751998-04-30Henrik Grubbström (Grubba)  THIS->gz.opaque=(void *)THIS;
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  pop_n_elems(args);
7260951997-09-01Per Hedbor /* mt_lock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  tmp=inflateInit(& THIS->gz);
7260951997-09-01Per Hedbor /* mt_unlock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  switch(tmp) { case Z_OK: return; case Z_VERSION_ERROR: error("libz not compatible with zlib.h!!!\n"); break; default: if(THIS->gz.msg) error("Failed to initialize gz_inflate: %s\n",THIS->gz.msg); else error("Failed to initialize gz_inflate\n"); } } static int do_inflate(dynamic_buffer *buf, struct zipper *this, int flush) { int fail=0; THREADS_ALLOW();
7260951997-09-01Per Hedbor  mt_lock(& this->lock);
cadacf1997-10-21Henrik Grubbström (Grubba)  THREADS_DISALLOW();
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  if(!this->gz.state) { fail=Z_STREAM_ERROR; }else{ do { char *loc; int ret; loc=low_make_buf_space(BUF,buf);
cadacf1997-10-21Henrik Grubbström (Grubba)  THREADS_ALLOW();
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  this->gz.next_out=(Bytef *)loc; this->gz.avail_out=BUF; ret=inflate(& this->gz, flush);
cadacf1997-10-21Henrik Grubbström (Grubba)  THREADS_DISALLOW();
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  low_make_buf_space(-this->gz.avail_out,buf); if(ret != Z_OK)
7260951997-09-01Per Hedbor  { fail=ret; break; }
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  } while(!this->gz.avail_out || flush==Z_FINISH || this->gz.avail_in); }
7260951997-09-01Per Hedbor  mt_unlock(& this->lock);
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  return fail; } static void gz_inflate(INT32 args) { struct pike_string *data; int fail; struct zipper *this=THIS; dynamic_buffer buf; if(!THIS->gz.state) error("gz_inflate not initialized or destructed\n"); initialize_buf(&buf); if(args<1) error("Too few arguments to gz_inflate->inflate()\n"); if(sp[-args].type != T_STRING) error("Bad argument 1 to gz_inflate->inflate()\n"); data=sp[-args].u.string; this->gz.next_in=(Bytef *)data->str; this->gz.avail_in=data->len; fail=do_inflate(&buf,this,Z_PARTIAL_FLUSH); pop_n_elems(args); if(fail != Z_OK && fail != Z_STREAM_END) { free(buf.s.str); if(THIS->gz.msg) error("Error in gz_inflate->inflate(): %s\n",THIS->gz.msg); else error("Error in gz_inflate->inflate(): %d\n",fail); } push_string(low_free_buf(&buf)); if(fail != Z_STREAM_END && fail!=Z_OK && !sp[-1].u.string->len) { pop_stack(); push_int(0); } } static void init_gz_inflate(struct object *o) {
77fe171997-02-27Fredrik Hübinette (Hubbe)  mt_init(& THIS->lock);
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  MEMSET(& THIS->gz, 0, sizeof(THIS->gz)); THIS->gz.zalloc=Z_NULL; THIS->gz.zfree=Z_NULL; THIS->gz.opaque=0; inflateInit(&THIS->gz); inflateEnd(&THIS->gz); } static void exit_gz_inflate(struct object *o) {
7260951997-09-01Per Hedbor /* mt_lock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe)  inflateEnd(& THIS->gz);
7260951997-09-01Per Hedbor /* mt_unlock(& THIS->lock); */
ab6aec1997-02-11Fredrik Hübinette (Hubbe) }
8d36d51998-02-27Mirar (Pontus Hagland)  static void gz_crc32(INT32 args) { unsigned INT32 crc; if (!args || sp[-args].type!=T_STRING) error("Gz.crc32: illegal or missing argument 1 (expected string)\n");
b804b21998-03-24Henrik Grubbström (Grubba)  if (args>1) {
8d36d51998-02-27Mirar (Pontus Hagland)  if (sp[1-args].type!=T_INT) error("Gz.crc32: illegal argument 2 (expected integer)\n"); else crc=(unsigned INT32)sp[1-args].u.integer;
b804b21998-03-24Henrik Grubbström (Grubba)  } else
8d36d51998-02-27Mirar (Pontus Hagland)  crc=0; crc=crc32(crc, (unsigned char*)sp[-args].u.string->str, sp[-args].u.string->len); pop_n_elems(args); push_int((INT32)crc); }
ab6aec1997-02-11Fredrik Hübinette (Hubbe) #endif void pike_module_exit(void) {} void pike_module_init(void) { #ifdef HAVE_ZLIB_H start_new_program(); add_storage(sizeof(struct zipper)); add_function("create",gz_deflate_create,"function(int|void:void)",0); add_function("deflate",gz_deflate,"function(string,int|void:string)",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); set_init_callback(init_gz_deflate); set_exit_callback(exit_gz_deflate); end_class("deflate",0); start_new_program(); add_storage(sizeof(struct zipper)); add_function("create",gz_inflate_create,"function(int|void:void)",0); add_function("inflate",gz_inflate,"function(string:string)",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); set_init_callback(init_gz_inflate); set_exit_callback(exit_gz_inflate); end_class("inflate",0);
2e87841997-04-06Fredrik Hübinette (Hubbe)  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);
8d36d51998-02-27Mirar (Pontus Hagland)  add_function("crc32",gz_crc32, "function(string,void|int:int)", OPT_TRY_OPTIMIZE);
ab6aec1997-02-11Fredrik Hübinette (Hubbe) #endif }
9eed301997-10-26Henrik Grubbström (Grubba) #if defined(HAVE___VTBL__9TYPE_INFO) || defined(HAVE___T_9__NOTHROW)
35d10a1997-10-12Henrik Grubbström (Grubba) /* Super-special kluge for IRIX 6.3 */
9eed301997-10-26Henrik Grubbström (Grubba) #ifdef HAVE___VTBL__9TYPE_INFO
297fff1997-10-14Henrik Grubbström (Grubba) extern void __vtbl__9type_info(void);
9eed301997-10-26Henrik Grubbström (Grubba) #endif /* HAVE___VTBL__9TYPE_INFO */ #ifdef HAVE___T_9__NOTHROW extern void __T_9__nothrow(void); #endif /* HAVE___T_9__NOTHROW */ /* Don't even think of calling this one * Not static, so the compiler can't optimize it away totally. */
297fff1997-10-14Henrik Grubbström (Grubba) void zlibmod_strap_kluge(void)
35d10a1997-10-12Henrik Grubbström (Grubba) {
9eed301997-10-26Henrik Grubbström (Grubba) #ifdef HAVE___VTBL__9TYPE_INFO
35d10a1997-10-12Henrik Grubbström (Grubba)  __vtbl__9type_info(); #endif /* HAVE___VTBL__9TYPE_INFO */
9eed301997-10-26Henrik Grubbström (Grubba) #ifdef HAVE___T_9__NOTHROW __T_9__nothrow(); #endif /* HAVE___T_9__NOTHROW */ } #endif /* HAVE___VTBL__9TYPE_INFO || HAVE___T_9__NOTHROW */