std.zlib.Compress / UnCompress are not working

Artem Rebrov ar_other at mail.ru
Mon May 29 14:08:04 PDT 2006


On Fri, 26 May 2006 18:18:56 +0400, Lionello Lunesu  
<lio at lunesu.remove.com> wrote:

> I can't get the Compress and UnCompress classes in std.zlib to work.

There is the old bug in Compress.flush() function. I wrote about it here  
at 04 Oct 2005.

Here is corrected version
------------------------------------------------------------------------------------------
     void[] flush(int mode = Z_FINISH)
     in
     {
	assert(mode == Z_FINISH || mode == Z_SYNC_FLUSH || mode == Z_FULL_FLUSH);
     }
     body
     {
	void[] destbuf, tmpbuf;
	int err;

	if (!inited)
	    return null;


     /*  //old code  Problem : zs.avail_in is set to 0 by deflate in  
previous compress()
     destbuf = new void[zs.avail_in];
     zs.next_out = cast(ubyte*) destbuf;
     zs.avail_out = destbuf.length;
     */

     // new code start
     tmpbuf = new void[zs.avail_out]; // may be  zs.avail_out+<some constnt>
                                      // zs.avail_out is set nonzero by  
deflate in previous compress()
     zs.next_out = cast(ubyte*) tmpbuf;
     zs.avail_out = tmpbuf.length;
     // new code end

     /* //old code
     err = deflate(&zs, mode);
     if (err != Z_STREAM_END)
     {
         delete destbuf;
         if (err == Z_OK)
         err = Z_BUF_ERROR;
         error(err);
     }
     destbuf = cast(void[])((cast(ubyte *)destbuf)[0 .. zs.next_out -  
cast(ubyte*)destbuf]);
     */

     // new code start
     while( (err = deflate(&zs, mode)) != Z_STREAM_END)
         {
         if(err == Z_OK)
             {
             if(zs.avail_out != 0 && mode != Z_FINISH)
                 break;
             else if(zs.avail_out == 0)
                 {
                 destbuf ~= tmpbuf;
                 zs.next_out = cast(ubyte*) tmpbuf;
                 zs.avail_out = tmpbuf.length;
                 continue;
                 }
             err = Z_BUF_ERROR;
             }
         delete destbuf;
         error(err);
         }
     destbuf ~= tmpbuf[0..(tmpbuf.length-zs.avail_out)];
     // new code end

     if (mode == Z_FINISH)
     {
         err = deflateEnd(&zs);
         inited = 0;
         if (err)
         error(err);
     }
     return destbuf;
     }
  ---------------------------------------------------------------------------
Additionally I've changed at the end of Compress.compress() and  
UnCompress.uncompress()

destbuf.length = zs.total_out;
to
destbuf.length = destbuf.length - zs.avail_out;

Now just concatenate buffers from sequential calls of [un]compress() and  
flush()


-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/



More information about the Digitalmars-d-bugs mailing list