objective-c uncompress/inflate a NSData object which contains a gzipped string
- by user141146
Hi,
I'm using objective-c (iPhone) to read a sqlite table that contains blob data. The blob data is actually a gzipped string.
The blob data is read into memory as an NSData object I then use a method (gzipInflate) which I grabbed from here (http://www.cocoadev.com/index.pl?NSDataCategory) -- see method below.
However, the gzipInflate method is returning nil. If I step through the gzipInflate method, I can see that the status returned near the bottom of the method is -3, which I assume is some type of error (Z_STREAM_END = 1 and Z_OK = 0, but I don't know precisely what a status of -3 is).
Consequently, the function returns nil even though the input NSData is 841 bytes in length.
Any thoughts on what I'm doing wrong?
Is there something wrong with the
method?
Something wrong with how I'm using
the method?
Any thoughts on how to test this?
Thanks for any help!
- (NSData *)gzipInflate
{
// NSData *compressed_data = [self.description dataUsingEncoding: NSUTF16StringEncoding];
NSData *compressed_data = self.description;
if ([compressed_data length] == 0) return compressed_data;
unsigned full_length = [compressed_data length];
unsigned half_length = [compressed_data length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[compressed_data bytes];
strm.avail_in = [compressed_data length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
while (!done)
{
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length])
[decompressed increaseLengthBy: half_length];
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] - strm.total_out;
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
NSLog(@"zstreamend = %d", Z_STREAM_END);
if (status == Z_STREAM_END) done = YES;
else if (status != Z_OK) break; //status here actually is -3
}
if (inflateEnd (&strm) != Z_OK) return nil;
// Set real length.
if (done)
{
[decompressed setLength: strm.total_out];
return [NSData dataWithData: decompressed];
}
else return nil;
}