ios-gzip压缩和解压缩

来源:互联网 发布:mysql 主死了 编辑:程序博客网 时间:2024/05/17 10:41

/*

压缩和解压缩函数

数据压缩参考:

http://www.clintharris.net/2009/how-to-gzip-data-in-memory-using-objective-c/

数据解压缩参考:

ASIHttpRequest库的文件:ASIDataDecompressor.m

*/

添加 libbz2.1.0.dylib

头文件 .h文件

#import <Foundation/Foundation.h>#import "zlib.h" @interface LFCGzipUtility : NSObject{ } +(NSData*) gzipData:(NSData*)pUncompressedData;  //压缩+(NSData*) ungzipData:(NSData *)compressedData;  //解压缩 @end

.m文件

#import "LFCGzipUtility.h" @implementation LFCGzipUtility +(NSData*) gzipData: (NSData*)pUncompressedData{    if (!pUncompressedData || [pUncompressedData length] == 0)    {        NSLog(@"%s: Error: Can't compress an empty or null NSData object.", __func__);        return nil;    }     z_stream zlibStreamStruct;    zlibStreamStruct.zalloc    = Z_NULL; // Set zalloc, zfree, and opaque to Z_NULL so    zlibStreamStruct.zfree     = Z_NULL; // that when we call deflateInit2 they will be    zlibStreamStruct.opaque    = Z_NULL; // updated to use default allocation functions.    zlibStreamStruct.total_out = 0; // Total number of output bytes produced so far    zlibStreamStruct.next_in   = (Bytef*)[pUncompressedData bytes]; // Pointer to input bytes    zlibStreamStruct.avail_in  = [pUncompressedData length]; // Number of input bytes left to process     int initError = deflateInit2(&zlibStreamStruct, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY);    if (initError != Z_OK)    {        NSString *errorMsg = nil;        switch (initError)        {            case Z_STREAM_ERROR:                errorMsg = @"Invalid parameter passed in to function.";                break;            case Z_MEM_ERROR:                errorMsg = @"Insufficient memory.";                break;            case Z_VERSION_ERROR:                errorMsg = @"The version of zlib.h and the version of the library linked do not match.";                break;            default:                errorMsg = @"Unknown error code.";                break;        }        NSLog(@"%s: deflateInit2() Error: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg);        [errorMsg release];        return nil;    }     // Create output memory buffer for compressed data. The zlib documentation states that    // destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes.    NSMutableData *compressedData = [NSMutableData dataWithLength:[pUncompressedData length] * 1.01 + 12]int deflateStatus;    do    {        // Store location where next byte should be put in next_out        zlibStreamStruct.next_out = [compressedData mutableBytes] + zlibStreamStruct.total_out;         // Calculate the amount of remaining free space in the output buffer        // by subtracting the number of bytes that have been written so far        // from the buffer's total capacity        zlibStreamStruct.avail_out = [compressedData length] - zlibStreamStruct.total_out;        deflateStatus = deflate(&zlibStreamStruct, Z_FINISH)} while ( deflateStatus == Z_OK )// Check for zlib error and convert code to usable error message if appropriate    if (deflateStatus != Z_STREAM_END)    {        NSString *errorMsg = nil;        switch (deflateStatus)        {            case Z_ERRNO:                errorMsg = @"Error occured while reading file.";                break;            case Z_STREAM_ERROR:                errorMsg = @"The stream state was inconsistent (e.g., next_in or next_out was NULL).";                break;            case Z_DATA_ERROR:                errorMsg = @"The deflate data was invalid or incomplete.";                break;            case Z_MEM_ERROR:                errorMsg = @"Memory could not be allocated for processing.";                break;            case Z_BUF_ERROR:                errorMsg = @"Ran out of output buffer for writing compressed bytes.";                break;            case Z_VERSION_ERROR:                errorMsg = @"The version of zlib.h and the version of the library linked do not match.";                break;            default:                errorMsg = @"Unknown error code.";                break;        }        NSLog(@"%s: zlib error while attempting compression: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg);        [errorMsg release]// Free data structures that were dynamically created for the stream.        deflateEnd(&zlibStreamStruct)return nil;    }    // Free data structures that were dynamically created for the stream.    deflateEnd(&zlibStreamStruct);    [compressedData setLength: zlibStreamStruct.total_out];    NSLog(@"%s: Compressed file from %d KB to %d KB", __func__, [pUncompressedData length]/1024, [compressedData length]/1024)return compressedData;} +(NSData *)ungzipData:(NSData *)compressedData{    if ([compressedData length] == 0)        return compressedData;     unsigned full_length = [compressedData length];    unsigned half_length = [compressedData length] / 2NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];    BOOL done = NO;    int status;     z_stream strm;    strm.next_in = (Bytef *)[compressedData bytes];    strm.avail_in = [compressedData length];    strm.total_out = 0;    strm.zalloc = Z_NULL;    strm.zfree = Z_NULL;    if (inflateInit2(&strm, (15+32)) != Z_OK)        return nilwhile (!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];    }    return nil;} @end
0 0