2009-07-20 Gonzalo Paniagua Javier <gonzalo@novell.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Tue, 21 Jul 2009 02:25:00 +0000 (02:25 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Tue, 21 Jul 2009 02:25:00 +0000 (02:25 -0000)
* Makefile.am: replaced zlib_macros.c with zlib-helper.c
* zlib_macros.c: Removed file.
* zlib-helper.c: new interface for DeflateStream. Flush() actually
does something.

svn path=/trunk/mono/; revision=138254

support/ChangeLog
support/Makefile.am
support/zlib-helper.c [new file with mode: 0644]
support/zlib_macros.c [deleted file]

index 3fc254cfc6b7079cfc290513e9c7f049bc376812..74284e404c1ebe3874a8f018f4991c23854b62e0 100644 (file)
@@ -1,3 +1,10 @@
+2009-07-20 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * Makefile.am: replaced zlib_macros.c with zlib-helper.c
+       * zlib_macros.c: Removed file.
+       * zlib-helper.c: new interface for DeflateStream. Flush() actually
+       does something.
+
 2009-04-13  Jonathan Pryor  <jpryor@novell.com>
 
        * sys-time.c: Properly set the modification time, instead of using the
index f53fe0b14c2364d3d428795fc6cff9587b3fffa2..9b6bc74b64e49260a2567b398325b5e7bdc1ed77 100644 (file)
@@ -91,10 +91,10 @@ ZLIB_SOURCES = \
        zutil.h
 
 if HAVE_ZLIB
-Z_SOURCE = zlib_macros.c 
+Z_SOURCE = zlib-helper.c
 Z_LIBS= -lz
 else
-Z_SOURCE = zlib_macros.c $(ZLIB_SOURCES)
+Z_SOURCE = zlib-helper.c $(ZLIB_SOURCES)
 Z_LIBS=
 endif
 
diff --git a/support/zlib-helper.c b/support/zlib-helper.c
new file mode 100644 (file)
index 0000000..d01716a
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Used by System.IO.Compression.DeflateStream
+ *
+ * Author:
+ *   Gonzalo Paniagua Javier (gonzalo@novell.com)
+ *
+ * (c) Copyright 2009 Novell, Inc.
+ */
+#include <config.h>
+#if defined (HAVE_ZLIB)
+#include <zlib.h>
+#else
+#include "zlib.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef TRUE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#define BUFFER_SIZE 4096
+#define ARGUMENT_ERROR -10
+#define IO_ERROR -11
+
+typedef int (*read_write_func) (unsigned char *buffer, int length);
+struct _ZStream {
+       z_stream *stream;
+       unsigned char *buffer;
+       read_write_func func;
+       unsigned char compress;
+       unsigned char eof;
+};
+typedef struct _ZStream ZStream;
+
+ZStream *CreateZStream (int compress, unsigned char gzip, read_write_func func);
+int CloseZStream (ZStream *zstream);
+int Flush (ZStream *stream);
+int ReadZStream (ZStream *stream, unsigned char *buffer, int length);
+int WriteZStream (ZStream *stream, unsigned char *buffer, int length);
+
+
+ZStream *
+CreateZStream (int compress, unsigned char gzip, read_write_func func)
+{
+       z_stream *z;
+       int retval;
+       ZStream *result;
+
+       if (func == NULL)
+               return NULL;
+
+#if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204)
+       /* Older versions of zlib do not support raw deflate or gzip */
+       return NULL;
+#endif
+
+       z = (z_stream *) malloc (sizeof (z_stream));
+       if (z == NULL)
+               return NULL;
+       memset (z, 0, sizeof (z_stream));
+       if (compress) {
+               retval = deflateInit2 (z, Z_DEFAULT_COMPRESSION, Z_DEFLATED, gzip ? 31 : -15, 8, Z_DEFAULT_STRATEGY);
+       } else {
+               retval = inflateInit2 (z, gzip ? 31 : -15);
+       }
+
+       if (retval != Z_OK) {
+               free (z);
+               return NULL;
+       }
+       result = malloc (sizeof (ZStream));
+       memset (result, 0, sizeof (ZStream));
+       result->stream = z;
+       result->func = func;
+       result->compress = compress;
+       result->buffer = (unsigned char *) malloc (BUFFER_SIZE);
+       if (result->buffer == NULL) {
+               free (result);
+               if (compress) {
+                       deflateEnd (z);
+               } else {
+                       inflateEnd (z);
+               }
+               free (z);
+               return NULL;
+       }
+       memset (result->buffer, 0, BUFFER_SIZE);
+       return result;
+}
+
+int
+CloseZStream (ZStream *zstream)
+{
+       int status;
+       int flush_status;
+
+       if (zstream == NULL)
+               return ARGUMENT_ERROR;
+
+       status = 0;
+       if (zstream->compress) {
+               status = deflate (zstream->stream, Z_FINISH);
+               flush_status = Flush (zstream);
+               if (status == Z_OK || status == Z_STREAM_END)
+                       status = flush_status;
+               deflateEnd (zstream->stream);
+       } else {
+               inflateEnd (zstream->stream);
+       }
+       free (zstream->stream);
+       memset (zstream, 0, sizeof (ZStream));
+       free (zstream);
+       return status;
+}
+
+static int
+write_to_managed (ZStream *stream)
+{
+       int n;
+       z_stream *zs;
+
+       zs = stream->stream;
+       if (zs->avail_out != BUFFER_SIZE) {
+               n = stream->func (stream->buffer, BUFFER_SIZE - zs->avail_out);
+               zs->next_out = stream->buffer;
+               zs->avail_out =  BUFFER_SIZE;
+               if (n < 0)
+                       return IO_ERROR;
+       }
+       return 0;
+}
+
+int
+Flush (ZStream *stream)
+{
+       if (!stream->compress)
+               return 0;
+
+       return write_to_managed (stream);
+}
+
+int
+ReadZStream (ZStream *stream, unsigned char *buffer, int length)
+{
+       int n;
+       int status;
+       z_stream *zs;
+
+       if (stream == NULL || buffer == NULL || length < 0)
+               return ARGUMENT_ERROR;
+
+       if (stream->eof)
+               return 0;
+
+       zs = stream->stream;
+       zs->next_out = buffer;
+       zs->avail_out = length;
+       while (zs->avail_out > 0) {
+               if (zs->avail_in == 0) {
+                       n = stream->func (stream->buffer, BUFFER_SIZE);
+                       if (n <= 0) {
+                               stream->eof = TRUE;
+                               break;
+                       }
+                       zs->next_in = stream->buffer;
+                       zs->avail_in = n;
+               }
+
+               status = inflate (stream->stream, Z_SYNC_FLUSH);
+               if (status != Z_OK && status != Z_STREAM_END)
+                       return status;
+       }
+       return length - zs->avail_out;
+}
+
+int
+WriteZStream (ZStream *stream, unsigned char *buffer, int length)
+{
+       int n;
+       int status;
+       z_stream *zs;
+
+       if (stream == NULL || buffer == NULL || length < 0)
+               return ARGUMENT_ERROR;
+
+       if (stream->eof)
+               return IO_ERROR;
+
+       zs = stream->stream;
+       zs->next_in = buffer;
+       zs->avail_in = length;
+       while (zs->avail_in > 0) {
+               if (zs->avail_out == 0) {
+                       zs->next_out = stream->buffer;
+                       zs->avail_out = BUFFER_SIZE;
+               }
+               status = deflate (stream->stream, Z_SYNC_FLUSH);
+               if (status != Z_OK && status != Z_STREAM_END)
+                       return status;
+
+               if (zs->avail_out == 0) {
+                       n = write_to_managed (stream);
+                       if (n < 0)
+                               return n;
+               }
+       }
+       return length;
+}
+
diff --git a/support/zlib_macros.c b/support/zlib_macros.c
deleted file mode 100644 (file)
index d022e04..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Helper routines to use Zlib
- *
- * Author:
- *   Christopher Lahey (clahey@ximian.co)
- *
- * (C) 2004 Novell, Inc.
- */
-#include <config.h>
-#if defined (HAVE_ZLIB)
-#include <zlib.h>
-#else
-#include "zlib.h"
-#endif
-
-#include <stdlib.h>
-
-z_stream *
-create_z_stream(int compress, unsigned char gzip)
-{
-       z_stream *z;
-       int retval;
-
-#if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204)
-       /* Older versions of zlib do not support raw deflate or gzip */
-       return NULL;
-#endif
-
-       z = malloc (sizeof (z_stream));
-       z->next_in = Z_NULL;
-       z->avail_in = 0;
-       z->next_out = Z_NULL;
-       z->avail_out = 0;
-       z->zalloc = Z_NULL;
-       z->zfree = Z_NULL;
-       z->opaque = NULL;
-       if (compress) {
-               retval = deflateInit2 (z, Z_DEFAULT_COMPRESSION, Z_DEFLATED, gzip ? 31 : -15, 8, Z_DEFAULT_STRATEGY);
-       } else {
-               retval = inflateInit2 (z, gzip ? 31 : -15);
-       }
-
-       if (retval == Z_OK)
-               return z;
-
-       free (z);
-       return NULL;
-}
-
-void
-free_z_stream(z_stream *z, int compress)
-{
-       if (compress) {
-               deflateEnd (z);
-       } else {
-               inflateEnd (z);
-       }
-       free (z);
-}
-
-void
-z_stream_set_next_in(z_stream *z, unsigned char *next_in)
-{
-       z->next_in = next_in;
-}
-
-void
-z_stream_set_avail_in(z_stream *z, int avail_in)
-{
-       z->avail_in = avail_in;
-}
-
-int
-z_stream_get_avail_in(z_stream *z)
-{
-       return z->avail_in;
-}
-
-void
-z_stream_set_next_out(z_stream *z, unsigned char *next_out)
-{
-       z->next_out = next_out;
-}
-
-void
-z_stream_set_avail_out(z_stream *z, int avail_out)
-{
-       z->avail_out = avail_out;
-}
-
-int
-z_stream_deflate (z_stream *z, int flush, unsigned char *next_out, int *avail_out)
-{
-       int ret_val;
-
-       z->next_out = next_out;
-       z->avail_out = *avail_out;
-
-       ret_val = deflate (z, flush);
-
-       *avail_out = z->avail_out;
-
-       return ret_val;
-}
-
-int
-z_stream_inflate (z_stream *z, int *avail_out)
-{
-       int ret_val;
-
-       z->avail_out = *avail_out;
-
-       ret_val = inflate (z, Z_NO_FLUSH);
-
-       *avail_out = z->avail_out;
-
-       return ret_val;
-}