#import "DDGzip.h"
@implementationDDGzip+(NSData*)compress:(NSData*)data{if(!data||[datalength]==0){NSLog(@"%s:Error:Can't compress an empty or null NSData object.",__func__);returnnil;}z_streamzlibStreamStruct;zlibStreamStruct.zalloc=Z_NULL;zlibStreamStruct.zfree=Z_NULL;zlibStreamStruct.opaque=Z_NULL;zlibStreamStruct.total_out=0;zlibStreamStruct.next_in=(Bytef*)[databytes];zlibStreamStruct.avail_in=(int)[datalength];intinitError=deflateInit2(&zlibStreamStruct,Z_DEFAULT_COMPRESSION,Z_DEFLATED,(15+16),8,Z_DEFAULT_STRATEGY);if(initError!=Z_OK){NSString*errMsg=nil;switch(initError){caseZ_STREAM_ERROR:errMsg=@"Invalid parameter passed in to function.";break;caseZ_MEM_ERROR:errMsg=@"Insufficient memory.";break;caseZ_VERSION_ERROR:errMsg=@"The version of zlib.h and the version of the library linked do not match.";break;default:errMsg=@"Unknown error code.";break;}NSLog(@"%s:deflateInit2()Error:[%@] Message:[%s]",__func__,errMsg,zlibStreamStruct.msg);returnnil;}NSMutableData*compressedData=[NSMutableDatadataWithLength:[datalength]*1.01+12];intdeflateStatus;do{zlibStreamStruct.next_out=[compressedDatamutableBytes]+zlibStreamStruct.total_out;zlibStreamStruct.avail_out=(unsignedint)[compressedDatalength]-(unsignedint)zlibStreamStruct.total_out;deflateStatus=deflate(&zlibStreamStruct,Z_FINISH);}while(deflateStatus==Z_OK);if(deflateStatus!=Z_STREAM_END){NSString*errorMsg=nil;switch(deflateStatus){caseZ_ERRNO:errorMsg=@"Error occured while reading file.";break;caseZ_STREAM_ERROR:errorMsg=@"The stream state was inconsistent (e.g., next_in or next_out was NULL).";break;caseZ_DATA_ERROR:errorMsg=@"The deflate data was invalid or incomplete.";break;caseZ_MEM_ERROR:errorMsg=@"Memory could not be allocated for processing.";break;caseZ_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);deflateEnd(&zlibStreamStruct);returnnil;}deflateEnd(&zlibStreamStruct);[compressedDatasetLength:zlibStreamStruct.total_out];returncompressedData;}+(NSData*)decompress:(NSData*)data{z_streamzStream;zStream.zalloc=Z_NULL;zStream.zfree=Z_NULL;zStream.opaque=Z_NULL;zStream.avail_in=0;zStream.next_in=0;intstatus=inflateInit2(&zStream,(15+32));if(status!=Z_OK){returnnil;}Bytef*bytes=(Bytef*)[databytes];NSUIntegerlength=[datalength];NSUIntegerhalfLength=length/2;NSMutableData*uncompressedData=[NSMutableDatadataWithLength:length+halfLength];zStream.next_in=bytes;zStream.avail_in=(unsignedint)length;zStream.avail_out=0;NSIntegerbytesProcessedAlready=zStream.total_out;while(zStream.avail_in!=0){if(zStream.total_out-bytesProcessedAlready>=[uncompressedDatalength]){[uncompressedDataincreaseLengthBy:halfLength];}zStream.next_out=(Bytef*)[uncompressedDatamutableBytes]+zStream.total_out-bytesProcessedAlready;zStream.avail_out=(unsignedint)([uncompressedDatalength]-(zStream.total_out-bytesProcessedAlready));status=inflate(&zStream,Z_NO_FLUSH);if(status==Z_STREAM_END){break;}elseif(status!=Z_OK){returnnil;}}status=inflateEnd(&zStream);if(status!=Z_OK){returnnil;}[uncompressedDatasetLength:zStream.total_out-bytesProcessedAlready];// Set real length
returnuncompressedData;}@end