Check-in [db7ab5ff29]
Overview
Comment:Began adding zlib to KitDLL
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:db7ab5ff29077dacdb6ee01e1cc2a232bbf34a27
User & Date: rkeene on 2010-10-05 16:58:51
Other Links: manifest | tags
Context
2010-10-05
17:49
Added zlib support to KitDLL (fixing test 13-zip for KitDLL) check-in: 966a87d8d1 user: rkeene tags: trunk
16:58
Began adding zlib to KitDLL check-in: db7ab5ff29 user: rkeene tags: trunk
16:58
Added zip test that involves doing zlib decompression check-in: 7971c09bf4 user: rkeene tags: trunk
Changes

Added kitdll/buildsrc/kitdll-0.0/zlib.c version [d3ecfd237b].

            1  +/* Written by Jean-Claude Wippler, as part of Tclkit.
            2  + * March 2003 - placed in the public domain by the author.
            3  + *
            4  + * Interface to the "zlib" compression library
            5  + */
            6  +
            7  +#include <tcl.h>
            8  +#if 10 * TCL_MAJOR_VERSION + TCL_MINOR_VERSION < 86
            9  +#include "zlib.h"
           10  +
           11  +typedef struct {
           12  +  z_stream stream;
           13  +  Tcl_Obj *indata;
           14  +} zlibstream;
           15  +
           16  +static int
           17  +zstreamincmd(ClientData cd, Tcl_Interp *ip, int objc, Tcl_Obj *CONST objv[])
           18  +{
           19  +  zlibstream *zp = (zlibstream*) cd;
           20  +  int count = 0;
           21  +  int e, index;
           22  +  Tcl_Obj *obj;
           23  +
           24  +  static CONST84 char* cmds[] = { "fill", "drain", NULL, };
           25  +
           26  +  if (Tcl_GetIndexFromObj(ip, objv[1], cmds, "option", 0, &index) != TCL_OK)
           27  +    return TCL_ERROR;
           28  +
           29  +  switch (index) {
           30  +
           31  +    case 0: /* fill ?data? */
           32  +      if (objc >= 3) {
           33  +	Tcl_IncrRefCount(objv[2]);
           34  +	Tcl_DecrRefCount(zp->indata);
           35  +	zp->indata = objv[2];
           36  +	zp->stream.next_in = Tcl_GetByteArrayFromObj(zp->indata,
           37  +						  (int*) &zp->stream.avail_in);
           38  +      }
           39  +      Tcl_SetObjResult(ip, Tcl_NewIntObj(zp->stream.avail_in));
           40  +      break;
           41  +
           42  +    case 1: /* drain count */
           43  +      if (objc != 3) {
           44  +	Tcl_WrongNumArgs(ip, 2, objv, "count");
           45  +	return TCL_ERROR;
           46  +      }
           47  +      if (Tcl_GetIntFromObj(ip, objv[2], &count) != TCL_OK)
           48  +	return TCL_ERROR;
           49  +      obj = Tcl_GetObjResult(ip);
           50  +      Tcl_SetByteArrayLength(obj, count);
           51  +      zp->stream.next_out = Tcl_GetByteArrayFromObj(obj,
           52  +						  (int*) &zp->stream.avail_out);
           53  +      e = inflate(&zp->stream, Z_NO_FLUSH);
           54  +      if (e != 0 && e != Z_STREAM_END) {
           55  +	Tcl_SetResult(ip, (char*) zError(e), TCL_STATIC);
           56  +	return TCL_ERROR;
           57  +      }
           58  +      Tcl_SetByteArrayLength(obj, count - zp->stream.avail_out);
           59  +      break;
           60  +  }
           61  +  return TCL_OK;
           62  +}
           63  +
           64  +void zstreamdelproc(ClientData cd)
           65  +{
           66  +  zlibstream *zp = (zlibstream*) cd;
           67  +  inflateEnd(&zp->stream);
           68  +  Tcl_DecrRefCount(zp->indata);
           69  +  Tcl_Free((void*) zp);
           70  +}
           71  +
           72  +static int
           73  +ZlibCmd(ClientData dummy, Tcl_Interp *ip, int objc, Tcl_Obj *CONST objv[])
           74  +{
           75  +  int e = TCL_OK, index, dlen, wbits = -MAX_WBITS;
           76  +  long flag;
           77  +  Byte *data;
           78  +  z_stream stream;
           79  +  Tcl_Obj *obj = Tcl_GetObjResult(ip);
           80  +
           81  +  static CONST84 char* cmds[] = {
           82  +    "adler32", "crc32", "compress", "deflate", "decompress", "inflate", 
           83  +    "sdecompress", "sinflate", NULL,
           84  +  };
           85  +
           86  +  if (objc < 3 || objc > 4) {
           87  +    Tcl_WrongNumArgs(ip, 1, objv, "option data ?...?");
           88  +    return TCL_ERROR;
           89  +  }
           90  +
           91  +  if (Tcl_GetIndexFromObj(ip, objv[1], cmds, "option", 0, &index) != TCL_OK ||
           92  +      objc > 3 && Tcl_GetLongFromObj(ip, objv[3], &flag) != TCL_OK)
           93  +    return TCL_ERROR;
           94  +
           95  +  data = Tcl_GetByteArrayFromObj(objv[2], &dlen);
           96  +
           97  +  switch (index) {
           98  +
           99  +    case 0: /* adler32 str ?start? -> checksum */
          100  +      if (objc < 4)
          101  +	flag = (long) adler32(0, 0, 0);
          102  +      Tcl_SetLongObj(obj, (long) adler32((uLong) flag, data, dlen));
          103  +      return TCL_OK;
          104  +
          105  +    case 1: /* crc32 str ?start? -> checksum */
          106  +      if (objc < 4)
          107  +	flag = (long) crc32(0, 0, 0);
          108  +      Tcl_SetLongObj(obj, (long) crc32((uLong) flag, data, dlen));
          109  +      return TCL_OK;
          110  +      
          111  +    case 2: /* compress data ?level? -> data */
          112  +      wbits = MAX_WBITS;
          113  +    case 3: /* deflate data ?level? -> data */
          114  +      if (objc < 4)
          115  +	flag = Z_DEFAULT_COMPRESSION;
          116  +
          117  +      stream.avail_in = (uInt) dlen;
          118  +      stream.next_in = data;
          119  +
          120  +      stream.avail_out = (uInt) dlen + dlen / 1000 + 12;
          121  +      Tcl_SetByteArrayLength(obj, stream.avail_out);
          122  +      stream.next_out = Tcl_GetByteArrayFromObj(obj, NULL);
          123  +
          124  +      stream.zalloc = 0;
          125  +      stream.zfree = 0;
          126  +      stream.opaque = 0;
          127  +
          128  +      e = deflateInit2(&stream, (int) flag, Z_DEFLATED, wbits,
          129  +			      MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
          130  +      if (e != Z_OK)
          131  +	break;
          132  +
          133  +      e = deflate(&stream, Z_FINISH);
          134  +      if (e != Z_STREAM_END) {
          135  +	deflateEnd(&stream);
          136  +	if (e == Z_OK) e = Z_BUF_ERROR;
          137  +      } else
          138  +	e = deflateEnd(&stream);
          139  +      break;
          140  +      
          141  +    case 4: /* decompress data ?bufsize? -> data */
          142  +      wbits = MAX_WBITS;
          143  +    case 5: /* inflate data ?bufsize? -> data */
          144  +    {
          145  +      if (objc < 4)
          146  +	flag = 16 * 1024;
          147  +
          148  +      for (;;) {
          149  +	stream.zalloc = 0;
          150  +	stream.zfree = 0;
          151  +
          152  +	/* +1 because ZLIB can "over-request" input (but ignore it) */
          153  +	stream.avail_in = (uInt) dlen +  1;
          154  +	stream.next_in = data;
          155  +
          156  +	stream.avail_out = (uInt) flag;
          157  +	Tcl_SetByteArrayLength(obj, stream.avail_out);
          158  +	stream.next_out = Tcl_GetByteArrayFromObj(obj, NULL);
          159  +
          160  +	/* Negative value suppresses ZLIB header */
          161  +	e = inflateInit2(&stream, wbits);
          162  +	if (e == Z_OK) {
          163  +	  e = inflate(&stream, Z_FINISH);
          164  +	  if (e != Z_STREAM_END) {
          165  +	    inflateEnd(&stream);
          166  +	    if (e == Z_OK) e = Z_BUF_ERROR;
          167  +	  } else
          168  +	    e = inflateEnd(&stream);
          169  +	}
          170  +
          171  +	if (e == Z_OK || e != Z_BUF_ERROR) break;
          172  +
          173  +	Tcl_SetByteArrayLength(obj, 0);
          174  +	flag *= 2;
          175  +      }
          176  +
          177  +      break;
          178  +    }
          179  +      
          180  +    case 6: /* sdecompress cmdname -> */
          181  +      wbits = MAX_WBITS;
          182  +    case 7: /* sinflate cmdname -> */
          183  +    {
          184  +      zlibstream *zp = (zlibstream*) Tcl_Alloc(sizeof (zlibstream));
          185  +      zp->indata = Tcl_NewObj();
          186  +      Tcl_IncrRefCount(zp->indata);
          187  +      zp->stream.zalloc = 0;
          188  +      zp->stream.zfree = 0;
          189  +      zp->stream.opaque = 0;
          190  +      zp->stream.next_in = 0;
          191  +      zp->stream.avail_in = 0;
          192  +      inflateInit2(&zp->stream, wbits);
          193  +      Tcl_CreateObjCommand(ip, Tcl_GetStringFromObj(objv[2], 0), zstreamincmd,
          194  +      				(ClientData) zp, zstreamdelproc);
          195  +      return TCL_OK;
          196  +    }
          197  +  }
          198  +
          199  +  if (e != Z_OK) {
          200  +    Tcl_SetResult(ip, (char*) zError(e), TCL_STATIC);
          201  +    return TCL_ERROR;
          202  +  }
          203  +
          204  +  Tcl_SetByteArrayLength(obj, stream.total_out);
          205  +  return TCL_OK;
          206  +}
          207  +
          208  +int Zlib_Init(Tcl_Interp *interp)
          209  +{
          210  +    Tcl_CreateObjCommand(interp, "zlib", ZlibCmd, 0, 0);
          211  +    return Tcl_PkgProvide( interp, "zlib", "1.1");
          212  +}
          213  +#endif /* Tcl version less than 8.6 */