0

I have just recently found Objective Zip Ihave been reading through the instructions to get it set up in my project. However I am not really sure how to use it to decompress some NSData I have that I am wanting to decompress.

I have looked at the example solution and it seems to be performing the unzip on a zip file the code looks roughly like this

ZipFile *unzipFile= [[ZipFile alloc] initWithFileName:filePath mode:ZipFileModeUnzip];

[unzipFile goToFirstFileInZip];
ZipReadStream *read1= [unzipFile readCurrentFileInZip];

give or take some other instructions this is how they show you to use it, their sample code is here

I would like to know how to do the same thing but using NSData? or would I have to convert the NSData into a zipFile? if so how is that performed properly?

The NSData I am trying to unzip if zlib compressed... any example code would be helpful

HurkNburkS
  • 5,492
  • 19
  • 100
  • 183

1 Answers1

3

here it is https://stackoverflow.com/a/6466832/751885

I use the following two methods process NSData

and call

saveToFile 

method write on disk.

[[self compressData:uncompressedData] writeToFile:@"fileName.zip" atomically:YES];

Compress:

-(NSData*) compressData:(NSData* )uncompressedData {
if ([uncompressedData length] == 0) return uncompressedData;

z_stream strm;

strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in=(Bytef *)[uncompressedData bytes];
strm.avail_in = (unsigned int)[uncompressedData length];

// Compresssion Levels:
//   Z_NO_COMPRESSION
//   Z_BEST_SPEED
//   Z_BEST_COMPRESSION
//   Z_DEFAULT_COMPRESSION

if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil;

NSMutableData *compressed = [NSMutableData dataWithLength:16384];  // 16K chunks for expansion

do {

    if (strm.total_out >= [compressed length])
        [compressed increaseLengthBy: 16384];

    strm.next_out = [compressed mutableBytes] + strm.total_out;
    strm.avail_out = (unsigned int)([compressed length] - strm.total_out);

    deflate(&strm, Z_FINISH);  

} while (strm.avail_out == 0);

deflateEnd(&strm);

[compressed setLength: strm.total_out];
return [NSData dataWithData:compressed];
}

Uncompress:

-(NSData*) uncompressGZip:(NSData*) compressedData {
if ([compressedData length] == 0) return compressedData;

NSUInteger full_length = [compressedData length];
NSUInteger half_length = [compressedData length] / 2;

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

z_stream strm;
strm.next_in = (Bytef *)[compressedData bytes];
strm.avail_in = (unsigned int)[compressedData 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 = (unsigned int)([decompressed length] - strm.total_out);

    // Inflate another chunk.
    status = inflate (&strm, Z_SYNC_FLUSH);
    if (status == Z_STREAM_END) {
        done = YES;
    } else if (status != Z_OK) {
        break;
    }
}
if (inflateEnd (&strm) != Z_OK) return nil;

// Set real length.
if (done) {
    [decompressed setLength: strm.total_out];
    return [NSData dataWithData: decompressed];
} else {
    return nil;
}
}
Community
  • 1
  • 1
lumingjing
  • 390
  • 2
  • 10
  • holy moly, so if I have some zlib compressed NSData I just add that bottom method to my .m file then call it from which ever method I need to use it from? When you say call ** saveToFile** what if I just need the returned uncompressed NSData can i use it how ever i like? – HurkNburkS Dec 12 '12 at 03:19
  • I have just added it into my current .m file where I need to use it everything seems okay apart from the z_stream and strm objects.. they are causing errors.. any idea what I might need to do to fix this? – HurkNburkS Dec 12 '12 at 03:42
  • I read the other link you send me but that did not really help as its the same thing you have posted here, any more help would be hugely appreciated. – HurkNburkS Dec 12 '12 at 04:02
  • [[self compressData:oriNSData] writeToFile:@"fileName" atomically:YES] – lumingjing Dec 12 '12 at 06:20
  • okay so i have tried running my zlib encoded NSData through the decompression method and It always returns nil.. I have stepped through it and it returns the break; in the else if (status != Z_OK) do you have any suggestions why that might be? for instance do i need to use gziped NSdata for this method? – HurkNburkS Dec 12 '12 at 21:19
  • Sorry, I cant open my Xcode now. but i found some other resources [NSDataCategory](http://cocoadev.com/wiki/NSDataCategory) maybe help you. an NSData category that support gzip and zlib compression / decompression. – lumingjing Dec 13 '12 at 01:43
  • How can do all that stuff in memory? Also I would to use Swift. It's possible with Kotlin/Java https://stackoverflow.com/questions/55089278/how-can-i-get-zip-from-data-object-and-unzip-first-entry-file-inside-it – user25 Mar 10 '19 at 16:04
  • 1
    if you get z_stream error: add #import – cross_flame Jan 09 '23 at 16:07