tags:

views:

341

answers:

2

I am trying to call iPhone zLib to decompress the zlib stream from our HTTP based server, but the code always stop after finishing the first zlib block.

Obviously, iPhone SDK is using the standard open Zlib. My doubt is that the parameter for inflateInit2 is not appropriate here.

I spent lots of time reading the zlib manual, but it isn't that helpful.

Here is the details, your help is appreciated.

(1) the HTTP request:

NSURL *url = [NSURL URLWithString:@"http://192.168.0.98:82/WIC?query=getcontacts&PIN=12345678&compression=Y"]; 

(2) The data I get from server is something like this (if decompressed). The stream was compressed by C# zlib class DeflateStream:

$REC_TYPE=SYS
Status=OK
Message=OK
SetID=
IsLast=Y
StartIndex=0
LastIndex=6
EOR

......

$REC_TYPE=CONTACTSDISTLIST
ID=2
Name=CTU+L%2EA%2E
OnCallEnabled=Y
OnCallMinUsers=1
OnCallEditRight=
OnCallEditDLRight=D
Fields=
CL=
OnCallStatus=
EOR

(3) However, I will only get the first Block. The code for decompression on iPhone (copied from a code piece from somewhere here) is as follow. The loop between Line 23~38 always break the second time execution.

    + (NSData *) uncompress: (NSData*) data
    {
 1    if ([data length] == 0) return nil;
 2   NSInteger length = [data length];
 3    unsigned full_length = length;
 4    unsigned half_length =length/ 2;

 5    NSMutableData *decompressed = [NSMutableData dataWithLength: 5*full_length + half_length];
 6    BOOL done = NO;
 7    int status;

 8   z_stream strm;
 9    length=length-4;
 10    void* bytes= malloc(length);
 11    NSRange range;
 12    range.location=4;
 13   range.length=length;
 14    [data getBytes: bytes range: range];
 15    strm.next_in = bytes;
 16    strm.avail_in = length;
 17    strm.total_out = 0;
 18    strm.zalloc = Z_NULL;
 19   strm.zfree = Z_NULL;
 20    strm.data_type= Z_BINARY;
 21  // if (inflateInit(&strm) != Z_OK) return nil;

 22    if (inflateInit2(&strm, (-15)) != Z_OK) return nil; //It won't work if change -15 to positive numbers.
 23   while (!done)
 24    {
 25     // Make sure we have enough room and reset the lengths.
 26     if (strm.total_out >= [decompressed length])
 27      [decompressed increaseLengthBy: half_length];
 28     strm.next_out = [decompressed mutableBytes] + strm.total_out;
 29     strm.avail_out = [decompressed length] - strm.total_out;
 30     
 31     // Inflate another chunk.
 32     status = inflate (&strm, Z_SYNC_FLUSH); //Z_SYNC_FLUSH-->Z_BLOCK, won't work either 
 33     if (status == Z_STREAM_END){
 34      
 35      done = YES;
 36     }
 37     else if (status != Z_OK) break;
 38    }

 39    if (inflateEnd (&strm) != Z_OK) return nil;

 40    // Set real length.
 41    if (done)
 42    {
 43     [decompressed setLength: strm.total_out];
 44     return [NSData dataWithData: decompressed];
 45    }
 46    else return nil;
 47   }
A: 

Hi , I face the same problem.. You get any luck solving this problem..! If its not working are you using any alternative compression, I am thinking to switch on RLE..! Is it fine, if you have any knowledge about the compression statistics?

Arpan
Hi, Arpan,I haven't found the problem yet. Fortunately, this is not a urgent feature for us, we are going to work without compression.I am not thinking of any other algorithm. Next step, I will probably try to integrate the zLib source code directly, so that I can debug into it. Let me know if you get any progress.
cedric
Lets see, I am still working on it..! If I find something will definitely post it ..!
Arpan
A: 

Hi guys

I had this issue and sorted it out. The code is slightly buggy as it breaks if Z_BUF_ERROR is returned, yet on reading the zlib Documentation it turns out that Z_BUF_ERROR should not be checked on inflation, as it can be thrown even if the resulting output is fine.

Changing the code thus worked:

// Inflate another chunk.
        status = inflate (&strm, Z_SYNC_FLUSH);
        if ( (status == Z_STREAM_END) || (status == Z_BUF_ERROR) )
            done = YES;

Hope this works for you

Carlos

Carlos P
Hi, Carlos,It's very encouraging to see someone finally got it work.However, I made the change you suggested, it doesn't work either. I am afraid my code has other problems.So, can you attach the whole inflation code here?Thanks!Cedric
cedric