ios 中gzip与unGzip

工程中添加libz.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"

#import "zlib.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;

            caseZ_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);

        return nil;

    }

    

    

    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;

        

        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;

            caseZ_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);

        

        // 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] / 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 = [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 = [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];

    }

    returnnil;

}

 

 

 

 

 

 

@end

 

 

猜你喜欢

转载自zxs19861202.iteye.com/blog/2066356