diff options
author | 2012-02-27 22:30:11 +0000 | |
---|---|---|
committer | 2012-02-27 22:30:11 +0000 | |
commit | ba4b222bea6694d654ab6b89bcd452dd5a67e42f (patch) | |
tree | fb18483777e0b68a17a979f8c20e0dd17726c983 | |
parent | ed21e9bab5c58a051274f957f1de79bb87a21a7e (diff) |
[Author: thomasvl]
Add support for raw inflate/deflate without a header.
R=dmaclach
DELTA=416 (327 added, 69 deleted, 20 changed)
-rw-r--r-- | Foundation/GTMNSData+zlib.h | 50 | ||||
-rw-r--r-- | Foundation/GTMNSData+zlib.m | 240 | ||||
-rw-r--r-- | Foundation/GTMNSData+zlibTest.m | 146 |
3 files changed, 347 insertions, 89 deletions
diff --git a/Foundation/GTMNSData+zlib.h b/Foundation/GTMNSData+zlib.h index 3ea7db8..08fbb9a 100644 --- a/Foundation/GTMNSData+zlib.h +++ b/Foundation/GTMNSData+zlib.h @@ -26,6 +26,8 @@ // return nil when given such data. To handle data of that size you really // should be streaming it rather then doing it all in memory. +#pragma mark Gzip Compression + /// Return an autoreleased NSData w/ the result of gzipping the bytes. // // Uses the default compression level. @@ -48,6 +50,8 @@ + (NSData *)gtm_dataByGzippingData:(NSData *)data compressionLevel:(int)level; +#pragma mark Zlib "Stream" Compression + // NOTE: deflate is *NOT* gzip. deflate is a "zlib" stream. pick which one // you really want to create. (the inflate api will handle either) @@ -73,6 +77,7 @@ + (NSData *)gtm_dataByDeflatingData:(NSData *)data compressionLevel:(int)level; +#pragma mark Uncompress of Gzip or Zlib /// Return an autoreleased NSData w/ the result of decompressing the bytes. // @@ -85,4 +90,49 @@ // The data to decompress can be zlib or gzip payloads. + (NSData *)gtm_dataByInflatingData:(NSData *)data; + +#pragma mark "Raw" Compression Support + +// NOTE: raw deflate is *NOT* gzip or deflate. it does not include a header +// of any form and should only be used within streams here an external crc/etc. +// is done to validate the data. The RawInflate apis can be used on data +// processed like this. + +/// Return an autoreleased NSData w/ the result of *raw* deflating the bytes. +// +// Uses the default compression level. +// *No* header is added to the resulting data. ++ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes + length:(NSUInteger)length; + +/// Return an autoreleased NSData w/ the result of *raw* deflating the payload of |data|. +// +// Uses the default compression level. +// *No* header is added to the resulting data. ++ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data; + +/// Return an autoreleased NSData w/ the result of *raw* deflating the bytes using |level| compression level. +// +// |level| can be 1-9, any other values will be clipped to that range. +// *No* header is added to the resulting data. ++ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level; + +/// Return an autoreleased NSData w/ the result of *raw* deflating the payload of |data| using |level| compression level. +// *No* header is added to the resulting data. ++ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data + compressionLevel:(int)level; + +/// Return an autoreleased NSData w/ the result of *raw* decompressing the bytes. +// +// The data to decompress, it should *not* have any header (zlib nor gzip). ++ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes + length:(NSUInteger)length; + +/// Return an autoreleased NSData w/ the result of *raw* decompressing the payload of |data|. +// +// The data to decompress, it should *not* have any header (zlib nor gzip). ++ (NSData *)gtm_dataByRawInflatingData:(NSData *)data; + @end diff --git a/Foundation/GTMNSData+zlib.m b/Foundation/GTMNSData+zlib.m index 9183334..6abfafb 100644 --- a/Foundation/GTMNSData+zlib.m +++ b/Foundation/GTMNSData+zlib.m @@ -22,18 +22,28 @@ #define kChunkSize 1024 +typedef enum { + CompressionModeZlib, + CompressionModeGzip, + CompressionModeRaw, +} CompressionMode; + @interface NSData (GTMZlibAdditionsPrivate) + (NSData *)gtm_dataByCompressingBytes:(const void *)bytes length:(NSUInteger)length compressionLevel:(int)level - useGzip:(BOOL)useGzip; + mode:(CompressionMode)mode; ++ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes + length:(NSUInteger)length + isRawData:(BOOL)isRawData; @end @implementation NSData (GTMZlibAdditionsPrivate) + + (NSData *)gtm_dataByCompressingBytes:(const void *)bytes length:(NSUInteger)length compressionLevel:(int)level - useGzip:(BOOL)useGzip { + mode:(CompressionMode)mode { if (!bytes || !length) { return nil; } @@ -57,10 +67,20 @@ z_stream strm; bzero(&strm, sizeof(z_stream)); - int windowBits = 15; // the default int memLevel = 8; // the default - if (useGzip) { - windowBits += 16; // enable gzip header instead of zlib header + int windowBits = 15; // the default + switch (mode) { + case CompressionModeZlib: + // nothing to do + break; + + case CompressionModeGzip: + windowBits += 16; // enable gzip header instead of zlib header + break; + + case CompressionModeRaw: + windowBits *= -1; // Negative to mean no header. + break; } int retCode; if ((retCode = deflateInit2(&strm, level, Z_DEFLATED, windowBits, @@ -119,78 +139,9 @@ return result; } // gtm_dataByCompressingBytes:length:compressionLevel:useGzip: - -@end - - -@implementation NSData (GTMZLibAdditions) - -+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes - length:(NSUInteger)length { - return [self gtm_dataByCompressingBytes:bytes - length:length - compressionLevel:Z_DEFAULT_COMPRESSION - useGzip:YES]; -} // gtm_dataByGzippingBytes:length: - -+ (NSData *)gtm_dataByGzippingData:(NSData *)data { - return [self gtm_dataByCompressingBytes:[data bytes] - length:[data length] - compressionLevel:Z_DEFAULT_COMPRESSION - useGzip:YES]; -} // gtm_dataByGzippingData: - -+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes - length:(NSUInteger)length - compressionLevel:(int)level { - return [self gtm_dataByCompressingBytes:bytes - length:length - compressionLevel:level - useGzip:YES]; -} // gtm_dataByGzippingBytes:length:level: - -+ (NSData *)gtm_dataByGzippingData:(NSData *)data - compressionLevel:(int)level { - return [self gtm_dataByCompressingBytes:[data bytes] - length:[data length] - compressionLevel:level - useGzip:YES]; -} // gtm_dataByGzippingData:level: - -+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes - length:(NSUInteger)length { - return [self gtm_dataByCompressingBytes:bytes - length:length - compressionLevel:Z_DEFAULT_COMPRESSION - useGzip:NO]; -} // gtm_dataByDeflatingBytes:length: - -+ (NSData *)gtm_dataByDeflatingData:(NSData *)data { - return [self gtm_dataByCompressingBytes:[data bytes] - length:[data length] - compressionLevel:Z_DEFAULT_COMPRESSION - useGzip:NO]; -} // gtm_dataByDeflatingData: - -+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes - length:(NSUInteger)length - compressionLevel:(int)level { - return [self gtm_dataByCompressingBytes:bytes - length:length - compressionLevel:level - useGzip:NO]; -} // gtm_dataByDeflatingBytes:length:level: - -+ (NSData *)gtm_dataByDeflatingData:(NSData *)data - compressionLevel:(int)level { - return [self gtm_dataByCompressingBytes:[data bytes] - length:[data length] - compressionLevel:level - useGzip:NO]; -} // gtm_dataByDeflatingData:level: - + (NSData *)gtm_dataByInflatingBytes:(const void *)bytes - length:(NSUInteger)length { + length:(NSUInteger)length + isRawData:(BOOL)isRawData { if (!bytes || !length) { return nil; } @@ -210,7 +161,12 @@ strm.next_in = (unsigned char*)bytes; int windowBits = 15; // 15 to enable any window size - windowBits += 32; // and +32 to enable zlib or gzip header detection. + if (isRawData) { + windowBits *= -1; // make it negative to signal no header. + } else { + windowBits += 32; // and +32 to enable zlib or gzip header detection. + } + int retCode; if ((retCode = inflateInit2(&strm, windowBits)) != Z_OK) { // COV_NF_START - no real way to force this in a unittest (we guard all args) @@ -259,11 +215,139 @@ inflateEnd(&strm); return result; +} // gtm_dataByInflatingBytes:length:windowBits: + +@end + + +@implementation NSData (GTMZLibAdditions) + ++ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes + length:(NSUInteger)length { + return [self gtm_dataByCompressingBytes:bytes + length:length + compressionLevel:Z_DEFAULT_COMPRESSION + mode:CompressionModeGzip]; +} // gtm_dataByGzippingBytes:length: + ++ (NSData *)gtm_dataByGzippingData:(NSData *)data { + return [self gtm_dataByCompressingBytes:[data bytes] + length:[data length] + compressionLevel:Z_DEFAULT_COMPRESSION + mode:CompressionModeGzip]; +} // gtm_dataByGzippingData: + ++ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level { + return [self gtm_dataByCompressingBytes:bytes + length:length + compressionLevel:level + mode:CompressionModeGzip]; +} // gtm_dataByGzippingBytes:length:level: + ++ (NSData *)gtm_dataByGzippingData:(NSData *)data + compressionLevel:(int)level { + return [self gtm_dataByCompressingBytes:[data bytes] + length:[data length] + compressionLevel:level + mode:CompressionModeGzip]; +} // gtm_dataByGzippingData:level: + +#pragma mark - + ++ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes + length:(NSUInteger)length { + return [self gtm_dataByCompressingBytes:bytes + length:length + compressionLevel:Z_DEFAULT_COMPRESSION + mode:CompressionModeZlib]; +} // gtm_dataByDeflatingBytes:length: + ++ (NSData *)gtm_dataByDeflatingData:(NSData *)data { + return [self gtm_dataByCompressingBytes:[data bytes] + length:[data length] + compressionLevel:Z_DEFAULT_COMPRESSION + mode:CompressionModeZlib]; +} // gtm_dataByDeflatingData: + ++ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level { + return [self gtm_dataByCompressingBytes:bytes + length:length + compressionLevel:level + mode:CompressionModeZlib]; +} // gtm_dataByDeflatingBytes:length:level: + ++ (NSData *)gtm_dataByDeflatingData:(NSData *)data + compressionLevel:(int)level { + return [self gtm_dataByCompressingBytes:[data bytes] + length:[data length] + compressionLevel:level + mode:CompressionModeZlib]; +} // gtm_dataByDeflatingData:level: + +#pragma mark - + ++ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes + length:(NSUInteger)length { + return [self gtm_dataByInflatingBytes:bytes + length:length + isRawData:NO]; } // gtm_dataByInflatingBytes:length: + (NSData *)gtm_dataByInflatingData:(NSData *)data { return [self gtm_dataByInflatingBytes:[data bytes] - length:[data length]]; + length:[data length] + isRawData:NO]; } // gtm_dataByInflatingData: +#pragma mark - + ++ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes + length:(NSUInteger)length { + return [self gtm_dataByCompressingBytes:bytes + length:length + compressionLevel:Z_DEFAULT_COMPRESSION + mode:CompressionModeRaw]; +} // gtm_dataByRawDeflatingBytes:length: + ++ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data { + return [self gtm_dataByCompressingBytes:[data bytes] + length:[data length] + compressionLevel:Z_DEFAULT_COMPRESSION + mode:CompressionModeRaw]; +} // gtm_dataByRawDeflatingData: + ++ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level { + return [self gtm_dataByCompressingBytes:bytes + length:length + compressionLevel:level + mode:CompressionModeRaw]; +} // gtm_dataByRawDeflatingBytes:length:compressionLevel: + ++ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data + compressionLevel:(int)level { + return [self gtm_dataByCompressingBytes:[data bytes] + length:[data length] + compressionLevel:level + mode:CompressionModeRaw]; +} // gtm_dataByRawDeflatingData:compressionLevel: + ++ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes + length:(NSUInteger)length { + return [self gtm_dataByInflatingBytes:bytes + length:length + isRawData:YES]; +} // gtm_dataByRawInflatingBytes:length: + ++ (NSData *)gtm_dataByRawInflatingData:(NSData *)data { + return [self gtm_dataByInflatingBytes:[data bytes] + length:[data length] + isRawData:YES]; +} // gtm_dataByRawInflatingData: + @end diff --git a/Foundation/GTMNSData+zlibTest.m b/Foundation/GTMNSData+zlibTest.m index 966c1ae..b598f1d 100644 --- a/Foundation/GTMNSData+zlibTest.m +++ b/Foundation/GTMNSData+zlibTest.m @@ -110,6 +110,12 @@ static BOOL HasGzipHeader(NSData *data) { STAssertNil([NSData gtm_dataByInflatingData:nil], nil); STAssertNil([NSData gtm_dataByInflatingBytes:nil length:666], nil); STAssertNil([NSData gtm_dataByInflatingBytes:[data bytes] length:0], nil); + STAssertNil([NSData gtm_dataByRawDeflatingData:nil], nil); + STAssertNil([NSData gtm_dataByRawDeflatingBytes:nil length:666], nil); + STAssertNil([NSData gtm_dataByRawDeflatingBytes:[data bytes] length:0], nil); + STAssertNil([NSData gtm_dataByRawInflatingData:nil], nil); + STAssertNil([NSData gtm_dataByRawInflatingBytes:nil length:666], nil); + STAssertNil([NSData gtm_dataByRawInflatingBytes:[data bytes] length:0], nil); // test deflate w/ compression levels out of range NSData *deflated = [NSData gtm_dataByDeflatingData:data @@ -143,15 +149,31 @@ static BOOL HasGzipHeader(NSData *data) { STAssertNotNil(dataPrime, nil); STAssertEqualObjects(data, dataPrime, nil); + // test raw deflate w/ compression levels out of range + NSData *rawDeflated = [NSData gtm_dataByRawDeflatingData:data + compressionLevel:-4]; + STAssertNotNil(rawDeflated, nil); + STAssertFalse(HasGzipHeader(rawDeflated), nil); + dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated]; + STAssertNotNil(dataPrime, nil); + STAssertEqualObjects(data, dataPrime, nil); + rawDeflated = [NSData gtm_dataByRawDeflatingData:data + compressionLevel:20]; + STAssertNotNil(rawDeflated, nil); + STAssertFalse(HasGzipHeader(rawDeflated), nil); + dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated]; + STAssertNotNil(dataPrime, nil); + STAssertEqualObjects(data, dataPrime, nil); + // test non-compressed data data itself [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - "payload, error -3"]; + @"payload, error -3"]; STAssertNil([NSData gtm_dataByInflatingData:data], nil); // test deflated data runs that end before they are done [GTMUnitTestDevLog expect:([deflated length] / 11) + 1 casesOfString:@"Error trying to inflate some of the payload, " - "error -5"]; + @"error -5"]; for (NSUInteger x = 1 ; x < [deflated length] ; x += 11) { STAssertNil([NSData gtm_dataByInflatingBytes:[deflated bytes] length:x], nil); @@ -160,12 +182,23 @@ static BOOL HasGzipHeader(NSData *data) { // test gzipped data runs that end before they are done [GTMUnitTestDevLog expect:([gzipped length] / 11) + 1 casesOfString:@"Error trying to inflate some of the payload, " - "error -5"]; + @"error -5"]; for (NSUInteger x = 1 ; x < [gzipped length] ; x += 11) { STAssertNil([NSData gtm_dataByInflatingBytes:[gzipped bytes] length:x], nil); } + // test raw deflated data runs that end before they are done + [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " + @"payload, error -5"]; + [GTMUnitTestDevLog expect:([rawDeflated length] / 11) - 1 + casesOfString:@"Error trying to inflate some of the payload, " + @"error -3"]; + for (NSUInteger x = 1 ; x < [rawDeflated length] ; x += 11) { + STAssertNil([NSData gtm_dataByInflatingBytes:[rawDeflated bytes] + length:x], nil); + } + // test extra data before the deflated/gzipped data (just to make sure we // don't seek to the "real" data) NSMutableData *prefixedDeflated = @@ -173,10 +206,10 @@ static BOOL HasGzipHeader(NSData *data) { STAssertNotNil(prefixedDeflated, @"failed to alloc data block"); [prefixedDeflated appendData:deflated]; [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - "payload, error -3"]; + @"payload, error -3"]; STAssertNil([NSData gtm_dataByInflatingData:prefixedDeflated], nil); [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - "payload, error -3"]; + @"payload, error -3"]; STAssertNil([NSData gtm_dataByInflatingBytes:[prefixedDeflated bytes] length:[prefixedDeflated length]], nil); @@ -185,13 +218,25 @@ static BOOL HasGzipHeader(NSData *data) { STAssertNotNil(prefixedDeflated, @"failed to alloc data block"); [prefixedGzipped appendData:gzipped]; [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - "payload, error -3"]; + @"payload, error -3"]; STAssertNil([NSData gtm_dataByInflatingData:prefixedGzipped], nil); [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - "payload, error -3"]; + @"payload, error -3"]; STAssertNil([NSData gtm_dataByInflatingBytes:[prefixedGzipped bytes] length:[prefixedGzipped length]], nil); + NSMutableData *prefixedRawDeflated = + [NSMutableData dataWithBytes:randomDataSmall length:sizeof(randomDataSmall)]; + STAssertNotNil(prefixedRawDeflated, @"failed to alloc data block"); + [prefixedRawDeflated appendData:rawDeflated]; + [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " + @"payload, error -3"]; + STAssertNil([NSData gtm_dataByRawInflatingData:prefixedRawDeflated], nil); + [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " + @"payload, error -3"]; + STAssertNil([NSData gtm_dataByRawInflatingBytes:[prefixedRawDeflated bytes] + length:[prefixedRawDeflated length]], + nil); // test extra data after the deflated/gzipped data (just to make sure we // don't ignore some of the data) @@ -200,10 +245,10 @@ static BOOL HasGzipHeader(NSData *data) { [suffixedDeflated appendData:deflated]; [suffixedDeflated appendBytes:[data bytes] length:20]; [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - "all input, 20 bytes left"]; + @"all input, 20 bytes left"]; STAssertNil([NSData gtm_dataByInflatingData:suffixedDeflated], nil); [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - "all input, 20 bytes left"]; + @"all input, 20 bytes left"]; STAssertNil([NSData gtm_dataByInflatingBytes:[suffixedDeflated bytes] length:[suffixedDeflated length]], nil); @@ -212,13 +257,25 @@ static BOOL HasGzipHeader(NSData *data) { [suffixedGZipped appendData:gzipped]; [suffixedGZipped appendBytes:[data bytes] length:20]; [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - "all input, 20 bytes left"]; + @"all input, 20 bytes left"]; STAssertNil([NSData gtm_dataByInflatingData:suffixedGZipped], nil); [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - "all input, 20 bytes left"]; + @"all input, 20 bytes left"]; STAssertNil([NSData gtm_dataByInflatingBytes:[suffixedGZipped bytes] length:[suffixedGZipped length]], nil); + NSMutableData *suffixedRawDeflated = [NSMutableData data]; + STAssertNotNil(suffixedRawDeflated, @"failed to alloc data block"); + [suffixedRawDeflated appendData:rawDeflated]; + [suffixedRawDeflated appendBytes:[data bytes] length:20]; + [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " + @"all input, 20 bytes left"]; + STAssertNil([NSData gtm_dataByRawInflatingData:suffixedRawDeflated], nil); + [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " + @"all input, 20 bytes left"]; + STAssertNil([NSData gtm_dataByRawInflatingBytes:[suffixedRawDeflated bytes] + length:[suffixedRawDeflated length]], + nil); } - (void)testInflateDeflate { @@ -357,6 +414,73 @@ static BOOL HasGzipHeader(NSData *data) { } } +- (void)tesRawtInflateRawDeflate { + NSData *data = [NSData dataWithBytes:randomDataLarge + length:sizeof(randomDataLarge)]; + STAssertNotNil(data, @"failed to alloc data block"); + + // w/ *Bytes apis, default level + NSData *rawDeflated = [NSData gtm_dataByRawDeflatingBytes:[data bytes] + length:[data length]]; + STAssertNotNil(rawDeflated, @"failed to raw deflate data block"); + STAssertGreaterThan([rawDeflated length], + (NSUInteger)0, @"failed to raw deflate data block"); + STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + NSData *dataPrime = [NSData gtm_dataByRawInflatingBytes:[rawDeflated bytes] + length:[rawDeflated length]]; + STAssertNotNil(dataPrime, @"failed to raw inflate data block"); + STAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to raw inflate data block"); + STAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Bytes apis"); + + // w/ *Data apis, default level + rawDeflated = [NSData gtm_dataByRawDeflatingData:data]; + STAssertNotNil(rawDeflated, @"failed to raw deflate data block"); + STAssertGreaterThan([rawDeflated length], + (NSUInteger)0, @"failed to raw deflate data block"); + STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated]; + STAssertNotNil(dataPrime, @"failed to raw inflate data block"); + STAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to raw inflate data block"); + STAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Data apis"); + + // loop over the compression levels + for (int level = 1 ; level < 9 ; ++level) { + // w/ *Bytes apis, using our level + rawDeflated = [NSData gtm_dataByRawDeflatingBytes:[data bytes] + length:[data length] + compressionLevel:level]; + STAssertNotNil(rawDeflated, @"failed to rawDeflate data block"); + STAssertGreaterThan([rawDeflated length], + (NSUInteger)0, @"failed to raw deflate data block"); + STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + dataPrime = [NSData gtm_dataByRawInflatingBytes:[rawDeflated bytes] + length:[rawDeflated length]]; + STAssertNotNil(dataPrime, @"failed to raw inflate data block"); + STAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to raw inflate data block"); + STAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Bytes apis"); + + // w/ *Data apis, using our level + rawDeflated = [NSData gtm_dataByRawDeflatingData:data + compressionLevel:level]; + STAssertNotNil(rawDeflated, @"failed to deflate data block"); + STAssertGreaterThan([rawDeflated length], + (NSUInteger)0, @"failed to raw deflate data block"); + STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated]; + STAssertNotNil(dataPrime, @"failed to raw inflate data block"); + STAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to raw inflate data block"); + STAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Data apis"); + } +} + - (void)testLargeData { // Generate some large data out of the random chunk by xoring over it // to make sure it changes and isn't too repeated. |