pike.git
/
src
/
modules
/
zlibmod
/
zlibmod.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/modules/zlibmod/zlibmod.c:1:
+
/*\
+
||| 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"
+
RCSID("$Id: zlibmod.c,v 1.1 1996/11/16 05:17:15 hubbe Exp $");
-
+
#include "zlib_machine.h"
+
#include "types.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"
+
#include "macros.h"
+
#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;
+
DEFINE_MUTEX(lock);
+
};
+
+
#define BUF 16384
+
+
#define THIS ((struct zipper *)(fp->current_storage))
+
+
static void gz_deflate_create(INT32 args)
+
{
+
int level=Z_DEFAULT_COMPRESSION;
+
+
if(THIS->gz.state)
+
{
+
mt_lock(& this->lock);
+
deflateEnd(&THIS->gz);
+
mt_unlock(& this->lock);
+
}
+
+
if(args)
+
{
+
if(sp[-args].type != T_INT)
+
error("Bad argument 1 to gz->create()\n");
+
if(sp[-args].u.integer < Z_NO_COMPRESSION ||
+
sp[-args].u.integer > Z_BEST_COMPRESSION)
+
{
+
error("Compression level out of range for gz_deflate->create()\n");
+
}
+
}
+
+
THIS->gz.zalloc=Z_NULL;
+
THIS->gz.zfree=Z_NULL;
+
THIS->gz.opaque=THIS;
+
+
pop_n_elems(args);
+
mt_lock(& THIS->lock);
+
level=deflateInit(&THIS->gz, level);
+
mt_unlock(& THIS->lock);
+
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);
+
if(!this->gz.state)
+
{
+
fail=Z_STREAM_ERROR;
+
}else{
+
do
+
{
+
char *loc;
+
int ret;
+
loc=low_make_buf_space(BUF,buf);
+
this->gz.next_out=(Bytef *)loc;
+
this->gz.avail_out=BUF;
+
ret=deflate(& this->gz, flush);
+
low_make_buf_space(-this->gz.avail_out,buf);
+
if(ret != Z_OK)
+
{
+
fail=ret;
+
break;
+
}
+
} while(!this->gz.avail_out || flush==Z_FINISH || this->gz.avail_in);
+
}
+
+
mt_unlock(& this->lock);
+
THREADS_DISALLOW();
+
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;
+
+
defualt:
+
error("Argument 2 to gz_deflate->deflate() out of range.\n");
+
}
+
}else{
+
flush=Z_NO_FLUSH;
+
}
+
+
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)
+
{
+
mt_init(& THIS->locked);
+
MEMSET(& THIS->gz, 0, sizeof(THIS->gz));
+
THIS->gz.zalloc=Z_NULL;
+
THIS->gz.zfree=Z_NULL;
+
THIS->gz.opaque=THIS;
+
deflateInit(& THIS->gz, Z_DEFAULT_COMPRESSION);
+
}
+
+
static void exit_gz_deflate(struct object *o)
+
{
+
mt_lock(& THIS->lock);
+
deflateEnd(&THIS->gz);
+
mt_unlock(& THIS->lock);
+
}
+
+
/*******************************************************************/
+
+
+
static void gz_inflate_create(INT32 args)
+
{
+
int level;
+
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=THIS;
+
+
pop_n_elems(args);
+
mt_lock(THIS->lock);
+
level=inflateInit(& THIS->gz);
+
mt_unlock(THIS->lock);
+
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_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();
+
mt_lock(this->lock);
+
if(!this->gz.state)
+
{
+
fail=Z_STREAM_ERROR;
+
}else{
+
do
+
{
+
char *loc;
+
int ret;
+
loc=low_make_buf_space(BUF,buf);
+
this->gz.next_out=(Bytef *)loc;
+
this->gz.avail_out=BUF;
+
ret=inflate(& this->gz, flush);
+
low_make_buf_space(-this->gz.avail_out,buf);
+
if(ret != Z_OK)
+
{
+
fail=ret;
+
break;
+
}
+
} while(!this->gz.avail_out || flush==Z_FINISH || this->gz.avail_in);
+
}
+
mt_unlock(this->lock);
+
THREADS_DISALLOW();
+
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 && !sp[-1].u.string->len)
+
{
+
pop_stack();
+
push_int(0);
+
}
+
}
+
+
static void init_gz_inflate(struct object *o)
+
{
+
mt_init(THIS->locked);
+
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)
+
{
+
mt_lock(& THIS->lock);
+
inflateEnd(& THIS->gz);
+
mt_unlock(& THIS->lock);
+
}
+
+
#endif
+
+
void init_zlibmod_efuns(void) {}
+
void exit_zlibmod(void) { }
+
+
void init_zlibmod_programs(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_c_program("/precompiled/gz_deflate");
+
+
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_c_program("/precompiled/gz_inflate");
+
#endif
+
}
+
Newline at end of file added.