objective-c uncompress/inflate a NSData object which contains a gzipped string
Posted
by user141146
on Stack Overflow
See other posts from Stack Overflow
or by user141146
Published on 2010-03-26T21:00:41Z
Indexed on
2010/03/26
21:03 UTC
Read the original article
Hit count: 495
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;
}
© Stack Overflow or respective owner