Handle situation in where we have multiple buffers to send at the end.
[citadel.git] / libcitadel / lib / stringbuf.c
index 1171e9939840e308c29b52a7985d1f58da6bc738..7b2c663656e08fd874d788250c80a5333acd2877 100644 (file)
@@ -2873,22 +2873,23 @@ void *StrBufNewStreamContext(eStreamType type)
                break;
        case eZLibDecode:
        {
-/*
+
                z_enc_stream *stream;
                int err;
 
                stream = (z_enc_stream *) malloc(sizeof(z_enc_stream));
                memset(stream, 0, sizeof(z_enc_stream));
-               stream->OutBuf.BufSize = 64*SIZ;
+               stream->OutBuf.BufSize = 4*SIZ; /// TODO 64
                stream->OutBuf.buf = (char*)malloc(stream->OutBuf.BufSize);
 
-               err = deflateInit(&stream->zstream,
-                                 ZLibCompressionRatio);
+               err = inflateInit(&stream->zstream);
 
-               if (err != Z_OK)
-                       return NULL;/// tODO cleanup
+               if (err != Z_OK) {
+                       StrBufDestroyStreamContext(type, (void**)&stream);
+                       return NULL;
+               }
                return stream;
-*/
+
        }
        case eZLibEncode:
        {
@@ -2899,27 +2900,25 @@ void *StrBufNewStreamContext(eStreamType type)
                memset(stream, 0, sizeof(z_enc_stream));
                stream->OutBuf.BufSize = 4*SIZ; /// todo 64
                stream->OutBuf.buf = (char*)malloc(stream->OutBuf.BufSize);
-               /* write gzip header * /
+               /* write gzip header */
                stream->OutBuf.BufUsed = snprintf
                        (stream->OutBuf.buf,
                         stream->OutBuf.BufSize, 
                         "%c%c%c%c%c%c%c%c%c%c",
                         gz_magic[0], gz_magic[1], Z_DEFLATED,
-                        0 /*flags * / , 0, 0, 0, 0 /*time * / , 0 /* xflags * / ,
+                        0 /*flags */ , 0, 0, 0, 0 /*time */ , 0 /* xflags */ ,
                         OS_CODE);
-/*
+
                err = deflateInit2(&stream->zstream,
                                   ZLibCompressionRatio,
                                   Z_DEFLATED,
                                   -MAX_WBITS,
                                   DEF_MEM_LEVEL,
                                   Z_DEFAULT_STRATEGY);
-*/
-               err = deflateInit(&stream->zstream,
-                                 ZLibCompressionRatio);
-
-               if (err != Z_OK)
-                       return NULL;/// tODO cleanup
+               if (err != Z_OK) {
+                       StrBufDestroyStreamContext(type, (void**) &stream);
+                       return NULL;
+               }
                return stream;
        }
        case eEmtyCodec:
@@ -2932,6 +2931,9 @@ void *StrBufNewStreamContext(eStreamType type)
 
 void StrBufDestroyStreamContext(eStreamType type, void **vStream)
 {
+       if (*vStream) {
+               return;
+       }
        switch (type)
        {
        case eBase64Encode:
@@ -2940,6 +2942,12 @@ void StrBufDestroyStreamContext(eStreamType type, void **vStream)
                *vStream = NULL;
                break;
        case eZLibDecode:
+       {
+               z_enc_stream *stream = (z_enc_stream *)*vStream;
+               (void)inflateEnd(&stream->zstream);
+               free(stream->OutBuf.buf);
+               free(stream);
+       }
        case eZLibEncode:
        {
                z_enc_stream *stream = (z_enc_stream *)*vStream;
@@ -2954,7 +2962,7 @@ void StrBufDestroyStreamContext(eStreamType type, void **vStream)
        }
 }
 
-void StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, const char* pIn, long pInLen, void *vStream, int LastChunk)
+int StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, const char* pIn, long pInLen, void *vStream, int LastChunk)
 {
 
        switch (type)
@@ -3032,7 +3040,7 @@ void StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, con
                        stream->zstream.next_in = (Bytef *) In->Buf->buf;
                        stream->zstream.avail_in = (uInt) In->Buf->BufUsed;
                }
-
+               
                stream->zstream.next_out = (unsigned char*)stream->OutBuf.buf + stream->OutBuf.BufUsed;
                stream->zstream.avail_out = chunkavail = (uInt) stream->OutBuf.BufSize - stream->OutBuf.BufUsed;
 
@@ -3066,6 +3074,7 @@ void StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, con
                                        (In->Buf->BufUsed - stream->zstream.avail_in);
                        }
                }
+               return (LastChunk && (err != Z_FINISH));
 
        }
        break;
@@ -3074,22 +3083,36 @@ void StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, con
                int org_outbuf_len = stream->zstream.total_out;
                int err;
 
-               if (In->ReadWritePointer != NULL)
-               {
-                       stream->zstream.next_in = (Bytef *) In->ReadWritePointer;
-                       stream->zstream.avail_in = (uInt) In->Buf->BufUsed - 
-                               (In->ReadWritePointer - In->Buf->buf);
-               }
-               else
-               {
-                       stream->zstream.next_in = (Bytef *) In->Buf->buf;
-                       stream->zstream.avail_in = (uInt) In->Buf->BufUsed;
+               if ((stream->zstream.avail_out != 0) && (stream->zstream.next_in != NULL)) {
+                       if (In->ReadWritePointer != NULL)
+                       {
+                               stream->zstream.next_in = (Bytef *) In->ReadWritePointer;
+                               stream->zstream.avail_in = (uInt) In->Buf->BufUsed - 
+                                       (In->ReadWritePointer - In->Buf->buf);
+                       }
+                       else
+                       {
+                               stream->zstream.next_in = (Bytef *) In->Buf->buf;
+                               stream->zstream.avail_in = (uInt) In->Buf->BufUsed;
+                       }
                }
 
                stream->zstream.next_out = (unsigned char*)stream->OutBuf.buf + stream->OutBuf.BufUsed;
                stream->zstream.avail_out = (uInt) stream->OutBuf.BufSize - stream->OutBuf.BufUsed;
 
-               err = deflate(&stream->zstream,  (LastChunk) ? Z_FINISH : Z_NO_FLUSH);
+               err = inflate(&stream->zstream, Z_NO_FLUSH);
+
+               ///assert(ret != Z_STREAM_ERROR);  /* state not clobbered * /
+               switch (err) {
+               case Z_NEED_DICT:
+                       err = Z_DATA_ERROR;     /* and fall through */
+
+               case Z_DATA_ERROR:
+                       fprintf(stderr, "sanoteuh\n");
+               case Z_MEM_ERROR:
+                       (void)inflateEnd(&stream->zstream);
+                       return err;
+               }
 
                stream->OutBuf.BufUsed += stream->zstream.total_out + org_outbuf_len;
 
@@ -3125,6 +3148,7 @@ void StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, con
        }
                break; /// TODO
        }
+       return 0;
 }
 
 /**