├── LFCGzipUtility.h ├── README.md └── LFCGzipUtility.m /LFCGzipUtility.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "zlib.h" 3 | 4 | @interface LFCGzipUtility : NSObject 5 | 6 | +(NSData*) gzipData:(NSData*)pUncompressedData; //压缩 7 | +(NSData*) ungzipData:(NSData *)compressedData; //解压缩 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LFCGzipUtility 2 | An OC GZip Library saved for backup easy-to-use 3 | 4 | # How to Use 5 | ``` 6 | + (NSData *)gzipData:(NSData*)pUncompressedData; //压缩 7 | 8 | + (NSData *)ungzipData:(NSData *)compressedData; //解压缩 9 | 10 | ``` 11 | 12 | # Improts 13 | 14 | libz.dylib / libz.tbd ( for iOS9.0 or later ) 15 | 16 | 17 | -------------------------------------------------------------------------------- /LFCGzipUtility.m: -------------------------------------------------------------------------------- 1 | #import "LFCGzipUtility.h" 2 | 3 | @implementation LFCGzipUtility 4 | 5 | + (NSData *)gzipData:(NSData*)pUncompressedData { 6 | if (!pUncompressedData || [pUncompressedData length] == 0) { 7 | NSLog(@"%s: Error: Can't compress an empty or null NSData object.", __func__); 8 | return nil; 9 | } 10 | 11 | z_stream zlibStreamStruct; 12 | zlibStreamStruct.zalloc = Z_NULL; 13 | zlibStreamStruct.zfree = Z_NULL; 14 | zlibStreamStruct.opaque = Z_NULL; 15 | zlibStreamStruct.total_out = 0; 16 | zlibStreamStruct.next_in = (Bytef*)[pUncompressedData bytes]; 17 | zlibStreamStruct.avail_in = [pUncompressedData length]; 18 | 19 | int initError = deflateInit2(&zlibStreamStruct, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); 20 | if (initError != Z_OK) { 21 | NSString *errorMsg = nil; 22 | switch (initError) { 23 | case Z_STREAM_ERROR: 24 | errorMsg = @"Invalid parameter passed in to function."; 25 | break; 26 | case Z_MEM_ERROR: 27 | errorMsg = @"Insufficient memory."; 28 | break; 29 | case Z_VERSION_ERROR: 30 | errorMsg = @"The version of zlib.h and the version of the library linked do not match."; 31 | break; 32 | default: 33 | errorMsg = @"Unknown error code."; 34 | break; 35 | } 36 | NSLog(@"%s: deflateInit2() Error: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg); 37 | return nil; 38 | } 39 | 40 | // Create output memory buffer for compressed data. The zlib documentation states that 41 | // destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes. 42 | NSMutableData *compressedData = [NSMutableData dataWithLength:[pUncompressedData length] * 1.01 + 12]; 43 | 44 | int deflateStatus; 45 | do { 46 | zlibStreamStruct.next_out = [compressedData mutableBytes] + zlibStreamStruct.total_out; 47 | zlibStreamStruct.avail_out = [compressedData length] - zlibStreamStruct.total_out; 48 | deflateStatus = deflate(&zlibStreamStruct, Z_FINISH); 49 | 50 | } while ( deflateStatus == Z_OK ); 51 | 52 | // Check for zlib error and convert code to usable error message if appropriate 53 | if (deflateStatus != Z_STREAM_END) { 54 | // NSString *errorMsg = nil; 55 | // switch (deflateStatus) { 56 | // case Z_ERRNO: 57 | // errorMsg = @"Error occured while reading file."; 58 | // break; 59 | // case Z_STREAM_ERROR: 60 | // errorMsg = @"The stream state was inconsistent (e.g., next_in or next_out was NULL)."; 61 | // break; 62 | // case Z_DATA_ERROR: 63 | // errorMsg = @"The deflate data was invalid or incomplete."; 64 | // break; 65 | // case Z_MEM_ERROR: 66 | // errorMsg = @"Memory could not be allocated for processing."; 67 | // break; 68 | // case Z_BUF_ERROR: 69 | // errorMsg = @"Ran out of output buffer for writing compressed bytes."; 70 | // break; 71 | // case Z_VERSION_ERROR: 72 | // errorMsg = @"The version of zlib.h and the version of the library linked do not match."; 73 | // break; 74 | // default: 75 | // errorMsg = @"Unknown error code."; 76 | // break; 77 | // } 78 | //NSLog(@"%s: zlib error while attempting compression: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg); 79 | 80 | deflateEnd(&zlibStreamStruct); 81 | 82 | return nil; 83 | } 84 | 85 | deflateEnd(&zlibStreamStruct); 86 | 87 | [compressedData setLength: zlibStreamStruct.total_out]; 88 | 89 | NSLog(@"%s: Compressed file from %d KB to %d KB", __func__, [pUncompressedData length]/1024, [compressedData length]/1024); 90 | return compressedData; 91 | } 92 | 93 | + (NSData *)ungzipData:(NSData *)compressedData { 94 | if ([compressedData length] == 0) { 95 | return compressedData; 96 | } 97 | 98 | unsigned full_length = [compressedData length]; 99 | unsigned half_length = [compressedData length] / 2; 100 | 101 | NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length]; 102 | BOOL done = NO; 103 | int status; 104 | 105 | z_stream strm; 106 | strm.next_in = (Bytef *)[compressedData bytes]; 107 | strm.avail_in = [compressedData length]; 108 | strm.total_out = 0; 109 | strm.zalloc = Z_NULL; 110 | strm.zfree = Z_NULL; 111 | if (inflateInit2(&strm, (15+32)) != Z_OK) 112 | return nil; 113 | 114 | while (!done) { 115 | if (strm.total_out >= [decompressed length]) { 116 | [decompressed increaseLengthBy: half_length]; 117 | } 118 | strm.next_out = [decompressed mutableBytes] + strm.total_out; 119 | strm.avail_out = [decompressed length] - strm.total_out; 120 | // Inflate another chunk. 121 | status = inflate (&strm, Z_SYNC_FLUSH); 122 | if (status == Z_STREAM_END) { 123 | done = YES; 124 | } else if (status != Z_OK) { 125 | break; 126 | } 127 | } 128 | 129 | if (inflateEnd (&strm) != Z_OK) { 130 | return nil; 131 | } 132 | if (done) { 133 | [decompressed setLength:strm.total_out]; 134 | return [NSData dataWithData: decompressed]; 135 | } 136 | return nil; 137 | } 138 | 139 | @end 140 | --------------------------------------------------------------------------------