Thread overview
std.zlib.Compress / UnCompress are not working
May 26, 2006
Lionello Lunesu
May 29, 2006
Walter Bright
May 30, 2006
Lionello Lunesu
May 29, 2006
Artem Rebrov
May 26, 2006
I can't get the Compress and UnCompress classes in std.zlib to work. I've checked the source and noticed they have no unittest.

Should the following code work? If so, please add it to the std.zlib in a unittest {...}..

import std.zlib;

void main()
{
	Compress cmp = new Compress;
	UnCompress decmp = new UnCompress;

	void[] input;
	input = "tesatdffadf";

	void[] buf = cmp.compress(input);
	buf ~= cmp.flush();
	void[] output = decmp.uncompress(buf);

	assert( output[] == input[] );
}

L.
May 29, 2006
Try this:

void arrayPrint(ubyte[] array)
{
    //printf("array %p,%d\n", (void*)array, array.length);
    for (int i = 0; i < array.length; i++)
    {
        printf("%02x ", array[i]);
        if (((i + 1) & 15) == 0)
            printf("\n");
    }
    printf("\n\n");
}

void testzlib()
{
    ubyte[] src = cast(ubyte[])
"the quick brown fox jumps over the lazy dog\r
the quick brown fox jumps over the lazy dog\r
";
    ubyte[] dst;

    arrayPrint(src);
    dst = cast(ubyte[])std.zlib.compress(cast(void[])src);
    arrayPrint(dst);
    src = cast(ubyte[])std.zlib.uncompress(cast(void[])dst);
    arrayPrint(src);
}
May 29, 2006
On Fri, 26 May 2006 18:18:56 +0400, Lionello Lunesu <lio@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/
May 30, 2006
Walter Bright wrote:

<snip>

Walter, compress() and uncompress() are working fine, but the two classes, Compress and UnCompress, are not working the way they should.

L.