123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- //
- // NSData+CocoaDevAdditions.m
- // InsideJob
- //
- // Created by Adam Preble on 10/6/10.
- //
- // Source: http://www.cocoadev.com/index.pl?NSDataCategory
- #import "NSData+CocoaDevAdditions.h"
- #import <zlib.h>
- @implementation NSData (CocoaDevAdditions)
- - (NSData *)gzipInflate
- {
- if ([self length] == 0) return self;
-
- unsigned full_length = [self length];
- unsigned half_length = [self length] / 2;
-
- NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
- BOOL done = NO;
- int status;
-
- z_stream strm;
- strm.next_in = (Bytef *)[self bytes];
- strm.avail_in = [self 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);
- 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;
- }
- - (NSData *)gzipDeflate
- {
- if ([self length] == 0) return self;
-
- z_stream strm;
-
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.total_out = 0;
- strm.next_in=(Bytef *)[self bytes];
- strm.avail_in = [self 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 = [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];
- }
- @end
|