PageRenderTime 168ms CodeModel.GetById 7ms app.highlight 155ms RepoModel.GetById 0ms app.codeStats 1ms

/core/externals/update-engine/externals/google-toolbox-for-mac/Foundation/GTMNSData+zlibTest.m

http://macfuse.googlecode.com/
Objective C | 526 lines | 426 code | 41 blank | 59 comment | 11 complexity | bab536d0d57d3e9c02972132f3e9f2a1 MD5 | raw file
  1//
  2//  GTMNSData+zlibTest.m
  3//
  4//  Copyright 2007-2008 Google Inc.
  5//
  6//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7//  use this file except in compliance with the License.  You may obtain a copy
  8//  of the License at
  9//
 10//  http://www.apache.org/licenses/LICENSE-2.0
 11//
 12//  Unless required by applicable law or agreed to in writing, software
 13//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 14//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 15//  License for the specific language governing permissions and limitations under
 16//  the License.
 17//
 18
 19#import "GTMSenTestCase.h"
 20#import "GTMUnitTestDevLog.h"
 21#import "GTMNSData+zlib.h"
 22#import <stdlib.h> // for randiom/srandomdev
 23#import <zlib.h>
 24
 25@interface GTMNSData_zlibTest : GTMTestCase
 26@end
 27
 28// NOTE: we don't need to test the actually compressor/inflation (we're using
 29// zlib, it works), we just need to test our wrapper.  So we can use canned
 30// data, etc. (and yes, when using random data, things once failed because
 31// we generated a random block of data that was valid compressed data?!)
 32
 33static unsigned char randomDataLarge[] = {
 34  // openssl rand -rand /dev/random 512 | xxd -i
 35  0xe1, 0xa6, 0xe2, 0xa2, 0x0b, 0xf7, 0x8d, 0x6b, 0x31, 0xfe, 0xaa, 0x64,
 36  0x50, 0xbe, 0x52, 0x7e, 0x83, 0x74, 0x00, 0x8f, 0x62, 0x96, 0xc7, 0xe9,
 37  0x20, 0x59, 0x78, 0xc6, 0xea, 0x10, 0xd5, 0xdb, 0x3f, 0x6b, 0x13, 0xd9,
 38  0x44, 0x18, 0x24, 0x17, 0x63, 0xc8, 0x74, 0xa5, 0x37, 0x6c, 0x9c, 0x00,
 39  0xe5, 0xcf, 0x0a, 0xdf, 0xb9, 0x66, 0xb1, 0xbd, 0x04, 0x8f, 0x55, 0x9e,
 40  0xb0, 0x24, 0x4e, 0xf0, 0xc4, 0x69, 0x2c, 0x1f, 0x63, 0x9f, 0x41, 0xa8,
 41  0x89, 0x9b, 0x98, 0x00, 0xb6, 0x78, 0xf7, 0xe4, 0x4c, 0x72, 0x14, 0x84,
 42  0xaa, 0x3d, 0xc1, 0x42, 0x9f, 0x12, 0x85, 0xdd, 0x16, 0x8b, 0x8f, 0x67,
 43  0xe0, 0x26, 0x5b, 0x5e, 0xaa, 0xe7, 0xd3, 0x67, 0xfe, 0x21, 0x77, 0xa6,
 44  0x52, 0xde, 0x33, 0x8b, 0x96, 0x49, 0x6a, 0xd6, 0x58, 0x58, 0x36, 0x00,
 45  0x23, 0xd2, 0x45, 0x13, 0x9f, 0xd9, 0xc7, 0x2d, 0x55, 0x12, 0xb4, 0xfe,
 46  0x53, 0x27, 0x1f, 0x14, 0x71, 0x9b, 0x7e, 0xcc, 0x5e, 0x8c, 0x59, 0xef,
 47  0x80, 0xac, 0x89, 0xf4, 0x45, 0x8d, 0x98, 0x6d, 0x97, 0xfd, 0x53, 0x5f,
 48  0x19, 0xd6, 0x11, 0xf7, 0xcb, 0x5d, 0xca, 0xab, 0xe1, 0x01, 0xf1, 0xe9,
 49  0x1f, 0x1f, 0xf3, 0x53, 0x76, 0xa2, 0x59, 0x8e, 0xb3, 0x91, 0xff, 0xe8,
 50  0x1b, 0xc0, 0xc0, 0xda, 0xdd, 0x93, 0xb5, 0x9d, 0x62, 0x13, 0xb8, 0x07,
 51  0xf2, 0xf5, 0xb9, 0x4b, 0xe1, 0x09, 0xed, 0xdb, 0xe6, 0xd9, 0x2d, 0xc4,
 52  0x0d, 0xb6, 0xbd, 0xfc, 0xdb, 0x5c, 0xcc, 0xf6, 0x53, 0x4e, 0x01, 0xa4,
 53  0x03, 0x95, 0x4a, 0xa4, 0xaa, 0x4f, 0x45, 0xaf, 0xbf, 0xf1, 0x7e, 0x60,
 54  0x1d, 0x86, 0x93, 0x65, 0x7b, 0x24, 0x0c, 0x09, 0xe0, 0xd1, 0xd8, 0x60,
 55  0xd9, 0xd9, 0x55, 0x2a, 0xec, 0xd5, 0xdc, 0xd0, 0xc6, 0x5e, 0x2c, 0x22,
 56  0xf5, 0x19, 0x0b, 0xc3, 0xa1, 0x38, 0x11, 0x67, 0x6f, 0x6c, 0x0e, 0x34,
 57  0x44, 0x83, 0xee, 0xd3, 0xf2, 0x4b, 0x7b, 0x03, 0x68, 0xfe, 0xc5, 0x76,
 58  0xb2, 0x2e, 0x26, 0xeb, 0x1f, 0x66, 0x02, 0xa4, 0xd9, 0xda, 0x28, 0x3a,
 59  0xc3, 0x94, 0x03, 0xe8, 0x29, 0x7e, 0xfe, 0x3d, 0xc8, 0xc1, 0x0a, 0x74,
 60  0xc7, 0xaf, 0xa6, 0x84, 0x86, 0x85, 0xc3, 0x8c, 0x00, 0x38, 0xd4, 0xb5,
 61  0xb2, 0xe0, 0xf0, 0xc4, 0x8d, 0x10, 0x0d, 0xf1, 0xcd, 0x05, 0xdb, 0xd0,
 62  0xcf, 0x17, 0x4f, 0xa8, 0xe5, 0xf0, 0x53, 0x55, 0x62, 0xc7, 0x55, 0xe5,
 63  0xbe, 0x18, 0x2f, 0xda, 0x48, 0xf1, 0xaa, 0x85, 0x46, 0x80, 0x15, 0x70,
 64  0x82, 0xd2, 0xa6, 0xb0, 0x3d, 0x31, 0xb5, 0xcc, 0x23, 0x95, 0x5e, 0x15,
 65  0x35, 0x32, 0xd0, 0x86, 0xd1, 0x6e, 0x2d, 0xc0, 0xfe, 0x45, 0xae, 0x28,
 66  0x24, 0xa7, 0x14, 0xf4, 0xe9, 0xb5, 0x6f, 0xac, 0x25, 0xf9, 0x88, 0xf6,
 67  0x60, 0x5d, 0x6b, 0x5c, 0xf2, 0x38, 0xe8, 0xdc, 0xbd, 0xa6, 0x13, 0xc0,
 68  0xa4, 0xc8, 0xe9, 0x7a, 0xc6, 0xb6, 0x88, 0x26, 0x98, 0x9f, 0xe3, 0x9a,
 69  0xd9, 0x5b, 0xd4, 0xd0, 0x02, 0x1f, 0x55, 0x30, 0xbe, 0xde, 0x9c, 0xd1,
 70  0x53, 0x93, 0x72, 0xe6, 0x19, 0x79, 0xe9, 0xf1, 0x70, 0x78, 0x92, 0x31,
 71  0xf6, 0x17, 0xc0, 0xdd, 0x99, 0xc8, 0x97, 0x67, 0xdc, 0xf6, 0x67, 0x6b,
 72  0x9b, 0x1c, 0x90, 0xea, 0x1a, 0x9e, 0x26, 0x68, 0xc2, 0x13, 0x94, 0x3a,
 73  0x3e, 0x73, 0x61, 0x4e, 0x37, 0xa8, 0xa1, 0xfa, 0xf8, 0x22, 0xdd, 0x20,
 74  0x40, 0xc6, 0x52, 0x27, 0x47, 0x1a, 0x79, 0xfa, 0x40, 0xa6, 0x62, 0x6b,
 75  0xe6, 0xc7, 0x67, 0xb7, 0xa8, 0x2d, 0xd1, 0x9f, 0x17, 0xb8, 0x77, 0x5e,
 76  0x97, 0x1e, 0x92, 0xd7, 0xd2, 0x25, 0x04, 0x92, 0xf9, 0x41, 0x70, 0x93,
 77  0xe1, 0x13, 0x07, 0x94, 0x8e, 0x0b, 0x82, 0x98
 78};
 79
 80static unsigned char randomDataSmall[] = {
 81  // openssl rand -rand /dev/random 24 | xxd -i
 82  0xd1, 0xec, 0x35, 0xc3, 0xa0, 0x4c, 0x73, 0x37, 0x2f, 0x5a, 0x12, 0x44,
 83  0xee, 0xe4, 0x22, 0x07, 0x29, 0xa8, 0x4a, 0xde, 0xc8, 0xbb, 0xe7, 0xdb
 84};
 85
 86
 87static BOOL HasGzipHeader(NSData *data) {
 88  // very simple check
 89  const unsigned char *bytes = [data bytes];
 90  return ([data length] > 2) &&
 91         ((bytes[0] == 0x1f) && (bytes[1] == 0x8b));
 92}
 93
 94
 95@implementation GTMNSData_zlibTest
 96
 97- (void)testBoundryValues {
 98  // build some test data
 99  NSData *data = [NSData dataWithBytes:randomDataLarge
100                                length:sizeof(randomDataLarge)];
101  STAssertNotNil(data, @"failed to alloc data block");
102
103  // bogus args to start
104  STAssertNil([NSData gtm_dataByDeflatingData:nil], nil);
105  STAssertNil([NSData gtm_dataByDeflatingBytes:nil length:666], nil);
106  STAssertNil([NSData gtm_dataByDeflatingBytes:[data bytes] length:0], nil);
107  STAssertNil([NSData gtm_dataByGzippingData:nil], nil);
108  STAssertNil([NSData gtm_dataByGzippingBytes:nil length:666], nil);
109  STAssertNil([NSData gtm_dataByGzippingBytes:[data bytes] length:0], nil);
110  STAssertNil([NSData gtm_dataByInflatingData:nil], nil);
111  STAssertNil([NSData gtm_dataByInflatingBytes:nil length:666], nil);
112  STAssertNil([NSData gtm_dataByInflatingBytes:[data bytes] length:0], nil);
113  STAssertNil([NSData gtm_dataByRawDeflatingData:nil], nil);
114  STAssertNil([NSData gtm_dataByRawDeflatingBytes:nil length:666], nil);
115  STAssertNil([NSData gtm_dataByRawDeflatingBytes:[data bytes] length:0], nil);
116  STAssertNil([NSData gtm_dataByRawInflatingData:nil], nil);
117  STAssertNil([NSData gtm_dataByRawInflatingBytes:nil length:666], nil);
118  STAssertNil([NSData gtm_dataByRawInflatingBytes:[data bytes] length:0], nil);
119
120  // test deflate w/ compression levels out of range
121  NSData *deflated = [NSData gtm_dataByDeflatingData:data
122                                    compressionLevel:-4];
123  STAssertNotNil(deflated, nil);
124  STAssertFalse(HasGzipHeader(deflated), nil);
125  NSData *dataPrime = [NSData gtm_dataByInflatingData:deflated];
126  STAssertNotNil(dataPrime, nil);
127  STAssertEqualObjects(data, dataPrime, nil);
128  deflated = [NSData gtm_dataByDeflatingData:data
129                             compressionLevel:20];
130  STAssertNotNil(deflated, nil);
131  STAssertFalse(HasGzipHeader(deflated), nil);
132  dataPrime = [NSData gtm_dataByInflatingData:deflated];
133  STAssertNotNil(dataPrime, nil);
134  STAssertEqualObjects(data, dataPrime, nil);
135
136  // test gzip w/ compression levels out of range
137  NSData *gzipped = [NSData gtm_dataByGzippingData:data
138                                   compressionLevel:-4];
139  STAssertNotNil(gzipped, nil);
140  STAssertTrue(HasGzipHeader(gzipped), nil);
141  dataPrime = [NSData gtm_dataByInflatingData:gzipped];
142  STAssertNotNil(dataPrime, nil);
143  STAssertEqualObjects(data, dataPrime, nil);
144  gzipped = [NSData gtm_dataByGzippingData:data
145                           compressionLevel:20];
146  STAssertNotNil(gzipped, nil);
147  STAssertTrue(HasGzipHeader(gzipped), nil);
148  dataPrime = [NSData gtm_dataByInflatingData:gzipped];
149  STAssertNotNil(dataPrime, nil);
150  STAssertEqualObjects(data, dataPrime, nil);
151
152  // test raw deflate w/ compression levels out of range
153  NSData *rawDeflated = [NSData gtm_dataByRawDeflatingData:data
154                                          compressionLevel:-4];
155  STAssertNotNil(rawDeflated, nil);
156  STAssertFalse(HasGzipHeader(rawDeflated), nil);
157  dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated];
158  STAssertNotNil(dataPrime, nil);
159  STAssertEqualObjects(data, dataPrime, nil);
160  rawDeflated = [NSData gtm_dataByRawDeflatingData:data
161                                  compressionLevel:20];
162  STAssertNotNil(rawDeflated, nil);
163  STAssertFalse(HasGzipHeader(rawDeflated), nil);
164  dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated];
165  STAssertNotNil(dataPrime, nil);
166  STAssertEqualObjects(data, dataPrime, nil);
167
168  // test non-compressed data data itself
169  [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the "
170   @"payload, error -3: incorrect header check"];
171  STAssertNil([NSData gtm_dataByInflatingData:data], nil);
172
173  // test deflated data runs that end before they are done
174  [GTMUnitTestDevLog expect:([deflated length] / 11) + 1
175              casesOfString:@"Error trying to inflate some of the payload, "
176   @"error -5: (null)"];
177  for (NSUInteger x = 1 ; x < [deflated length] ; x += 11) {
178    STAssertNil([NSData gtm_dataByInflatingBytes:[deflated bytes]
179                                          length:x], nil);
180  }
181
182  // test gzipped data runs that end before they are done
183  [GTMUnitTestDevLog expect:([gzipped length] / 11) + 1
184              casesOfString:@"Error trying to inflate some of the payload, "
185   @"error -5: (null)"];
186  for (NSUInteger x = 1 ; x < [gzipped length] ; x += 11) {
187    STAssertNil([NSData gtm_dataByInflatingBytes:[gzipped bytes]
188                                          length:x], nil);
189  }
190
191  // test raw deflated data runs that end before they are done
192  [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the "
193   @"payload, error -5: (null)"];
194  [GTMUnitTestDevLog expect:([rawDeflated length] / 11) - 1
195              casesOfString:@"Error trying to inflate some of the payload, "
196   @"error -3: incorrect header check"];
197  for (NSUInteger x = 1 ; x < [rawDeflated length] ; x += 11) {
198    STAssertNil([NSData gtm_dataByInflatingBytes:[rawDeflated bytes]
199                                          length:x], nil);
200  }
201
202  // test extra data before the deflated/gzipped data (just to make sure we
203  // don't seek to the "real" data)
204  NSMutableData *prefixedDeflated =
205    [NSMutableData dataWithBytes:randomDataSmall length:sizeof(randomDataSmall)];
206  STAssertNotNil(prefixedDeflated, @"failed to alloc data block");
207  [prefixedDeflated appendData:deflated];
208  [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the "
209   @"payload, error -3: incorrect header check"];
210  STAssertNil([NSData gtm_dataByInflatingData:prefixedDeflated], nil);
211  [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the "
212   @"payload, error -3: incorrect header check"];
213  STAssertNil([NSData gtm_dataByInflatingBytes:[prefixedDeflated bytes]
214                                        length:[prefixedDeflated length]],
215              nil);
216  NSMutableData *prefixedGzipped =
217    [NSMutableData dataWithBytes:randomDataSmall length:sizeof(randomDataSmall)];
218  STAssertNotNil(prefixedDeflated, @"failed to alloc data block");
219  [prefixedGzipped appendData:gzipped];
220  [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the "
221   @"payload, error -3: incorrect header check"];
222  STAssertNil([NSData gtm_dataByInflatingData:prefixedGzipped], nil);
223  [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the "
224   @"payload, error -3: incorrect header check"];
225  STAssertNil([NSData gtm_dataByInflatingBytes:[prefixedGzipped bytes]
226                                        length:[prefixedGzipped length]],
227              nil);
228  NSMutableData *prefixedRawDeflated =
229    [NSMutableData dataWithBytes:randomDataSmall length:sizeof(randomDataSmall)];
230  STAssertNotNil(prefixedRawDeflated, @"failed to alloc data block");
231  [prefixedRawDeflated appendData:rawDeflated];
232  [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the "
233   @"payload, error -3: invalid stored block lengths"];
234  STAssertNil([NSData gtm_dataByRawInflatingData:prefixedRawDeflated], nil);
235  [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the "
236   @"payload, error -3: invalid stored block lengths"];
237  STAssertNil([NSData gtm_dataByRawInflatingBytes:[prefixedRawDeflated bytes]
238                                           length:[prefixedRawDeflated length]],
239              nil);
240
241  // test extra data after the deflated/gzipped data (just to make sure we
242  // don't ignore some of the data)
243  NSMutableData *suffixedDeflated = [NSMutableData data];
244  STAssertNotNil(suffixedDeflated, @"failed to alloc data block");
245  [suffixedDeflated appendData:deflated];
246  [suffixedDeflated appendBytes:[data bytes] length:20];
247  [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using "
248   @"all input, 20 bytes left"];
249  STAssertNil([NSData gtm_dataByInflatingData:suffixedDeflated], nil);
250  [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using "
251   @"all input, 20 bytes left"];
252  STAssertNil([NSData gtm_dataByInflatingBytes:[suffixedDeflated bytes]
253                                        length:[suffixedDeflated length]],
254              nil);
255  NSMutableData *suffixedGZipped = [NSMutableData data];
256  STAssertNotNil(suffixedGZipped, @"failed to alloc data block");
257  [suffixedGZipped appendData:gzipped];
258  [suffixedGZipped appendBytes:[data bytes] length:20];
259  [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using "
260   @"all input, 20 bytes left"];
261  STAssertNil([NSData gtm_dataByInflatingData:suffixedGZipped], nil);
262  [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using "
263   @"all input, 20 bytes left"];
264  STAssertNil([NSData gtm_dataByInflatingBytes:[suffixedGZipped bytes]
265                                        length:[suffixedGZipped length]],
266              nil);
267  NSMutableData *suffixedRawDeflated = [NSMutableData data];
268  STAssertNotNil(suffixedRawDeflated, @"failed to alloc data block");
269  [suffixedRawDeflated appendData:rawDeflated];
270  [suffixedRawDeflated appendBytes:[data bytes] length:20];
271  [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using "
272   @"all input, 20 bytes left"];
273  STAssertNil([NSData gtm_dataByRawInflatingData:suffixedRawDeflated], nil);
274  [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using "
275   @"all input, 20 bytes left"];
276  STAssertNil([NSData gtm_dataByRawInflatingBytes:[suffixedRawDeflated bytes]
277                                           length:[suffixedRawDeflated length]],
278              nil);
279}
280
281- (void)testInflateDeflate {
282  NSData *data = [NSData dataWithBytes:randomDataLarge
283                                length:sizeof(randomDataLarge)];
284  STAssertNotNil(data, @"failed to alloc data block");
285
286  // w/ *Bytes apis, default level
287  NSData *deflated = [NSData gtm_dataByDeflatingBytes:[data bytes]
288                                               length:[data length]];
289  STAssertNotNil(deflated, @"failed to deflate data block");
290  STAssertGreaterThan([deflated length],
291                      (NSUInteger)0, @"failed to deflate data block");
292  STAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data");
293  NSData *dataPrime = [NSData gtm_dataByInflatingBytes:[deflated bytes]
294                                                length:[deflated length]];
295  STAssertNotNil(dataPrime, @"failed to inflate data block");
296  STAssertGreaterThan([dataPrime length],
297                      (NSUInteger)0, @"failed to inflate data block");
298  STAssertEqualObjects(data,
299                       dataPrime, @"failed to round trip via *Bytes apis");
300
301  // w/ *Data apis, default level
302  deflated = [NSData gtm_dataByDeflatingData:data];
303  STAssertNotNil(deflated, @"failed to deflate data block");
304  STAssertGreaterThan([deflated length],
305                      (NSUInteger)0, @"failed to deflate data block");
306  STAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data");
307  dataPrime = [NSData gtm_dataByInflatingData:deflated];
308  STAssertNotNil(dataPrime, @"failed to inflate data block");
309  STAssertGreaterThan([dataPrime length],
310                      (NSUInteger)0, @"failed to inflate data block");
311  STAssertEqualObjects(data,
312                       dataPrime, @"failed to round trip via *Data apis");
313
314  // loop over the compression levels
315  for (int level = 1 ; level <= 9 ; ++level) {
316    // w/ *Bytes apis, using our level
317    deflated = [NSData gtm_dataByDeflatingBytes:[data bytes]
318                                         length:[data length]
319                               compressionLevel:level];
320    STAssertNotNil(deflated, @"failed to deflate data block");
321    STAssertGreaterThan([deflated length],
322                        (NSUInteger)0, @"failed to deflate data block");
323    STAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data");
324    dataPrime = [NSData gtm_dataByInflatingBytes:[deflated bytes]
325                                          length:[deflated length]];
326    STAssertNotNil(dataPrime, @"failed to inflate data block");
327    STAssertGreaterThan([dataPrime length],
328                        (NSUInteger)0, @"failed to inflate data block");
329    STAssertEqualObjects(data,
330                         dataPrime, @"failed to round trip via *Bytes apis");
331
332    // w/ *Data apis, using our level
333    deflated = [NSData gtm_dataByDeflatingData:data compressionLevel:level];
334    STAssertNotNil(deflated, @"failed to deflate data block");
335    STAssertGreaterThan([deflated length],
336                        (NSUInteger)0, @"failed to deflate data block");
337    STAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data");
338    dataPrime = [NSData gtm_dataByInflatingData:deflated];
339    STAssertNotNil(dataPrime, @"failed to inflate data block");
340    STAssertGreaterThan([dataPrime length],
341                        (NSUInteger)0, @"failed to inflate data block");
342    STAssertEqualObjects(data,
343                         dataPrime, @"failed to round trip via *Data apis");
344  }
345}
346
347- (void)testInflateGzip {
348  NSData *data = [NSData dataWithBytes:randomDataLarge
349                                length:sizeof(randomDataLarge)];
350  STAssertNotNil(data, @"failed to alloc data block");
351
352  // w/ *Bytes apis, default level
353  NSData *gzipped = [NSData gtm_dataByGzippingBytes:[data bytes]
354                                             length:[data length]];
355  STAssertNotNil(gzipped, @"failed to gzip data block");
356  STAssertGreaterThan([gzipped length],
357                      (NSUInteger)0, @"failed to gzip data block");
358  STAssertTrue(HasGzipHeader(gzipped),
359               @"doesn't have gzip header on gzipped data");
360  NSData *dataPrime = [NSData gtm_dataByInflatingBytes:[gzipped bytes]
361                                                length:[gzipped length]];
362  STAssertNotNil(dataPrime, @"failed to inflate data block");
363  STAssertGreaterThan([dataPrime length],
364                      (NSUInteger)0, @"failed to inflate data block");
365  STAssertEqualObjects(data,
366                       dataPrime, @"failed to round trip via *Bytes apis");
367
368  // w/ *Data apis, default level
369  gzipped = [NSData gtm_dataByGzippingData:data];
370  STAssertNotNil(gzipped, @"failed to gzip data block");
371  STAssertGreaterThan([gzipped length],
372                      (NSUInteger)0, @"failed to gzip data block");
373  STAssertTrue(HasGzipHeader(gzipped),
374               @"doesn't have gzip header on gzipped data");
375  dataPrime = [NSData gtm_dataByInflatingData:gzipped];
376  STAssertNotNil(dataPrime, @"failed to inflate data block");
377  STAssertGreaterThan([dataPrime length],
378                      (NSUInteger)0, @"failed to inflate data block");
379  STAssertEqualObjects(data, dataPrime,
380                       @"failed to round trip via *Data apis");
381
382  // loop over the compression levels
383  for (int level = 1 ; level <= 9 ; ++level) {
384    // w/ *Bytes apis, using our level
385    gzipped = [NSData gtm_dataByGzippingBytes:[data bytes]
386                                       length:[data length]
387                             compressionLevel:level];
388    STAssertNotNil(gzipped, @"failed to gzip data block");
389    STAssertGreaterThan([gzipped length],
390                        (NSUInteger)0, @"failed to gzip data block");
391    STAssertTrue(HasGzipHeader(gzipped),
392                 @"doesn't have gzip header on gzipped data");
393    dataPrime = [NSData gtm_dataByInflatingBytes:[gzipped bytes]
394                                          length:[gzipped length]];
395    STAssertNotNil(dataPrime, @"failed to inflate data block");
396    STAssertGreaterThan([dataPrime length],
397                        (NSUInteger)0, @"failed to inflate data block");
398    STAssertEqualObjects(data, dataPrime,
399                         @"failed to round trip via *Bytes apis");
400
401    // w/ *Data apis, using our level
402    gzipped = [NSData gtm_dataByGzippingData:data compressionLevel:level];
403    STAssertNotNil(gzipped, @"failed to gzip data block");
404    STAssertGreaterThan([gzipped length],
405                        (NSUInteger)0, @"failed to gzip data block");
406    STAssertTrue(HasGzipHeader(gzipped),
407                 @"doesn't have gzip header on gzipped data");
408    dataPrime = [NSData gtm_dataByInflatingData:gzipped];
409    STAssertNotNil(dataPrime, @"failed to inflate data block");
410    STAssertGreaterThan([dataPrime length],
411                        (NSUInteger)0, @"failed to inflate data block");
412    STAssertEqualObjects(data,
413                         dataPrime, @"failed to round trip via *Data apis");
414  }
415}
416
417- (void)testRawtInflateRawDeflate {
418  NSData *data = [NSData dataWithBytes:randomDataLarge
419                                length:sizeof(randomDataLarge)];
420  STAssertNotNil(data, @"failed to alloc data block");
421
422  // w/ *Bytes apis, default level
423  NSData *rawDeflated = [NSData gtm_dataByRawDeflatingBytes:[data bytes]
424                                                     length:[data length]];
425  STAssertNotNil(rawDeflated, @"failed to raw deflate data block");
426  STAssertGreaterThan([rawDeflated length],
427                      (NSUInteger)0, @"failed to raw deflate data block");
428  STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data");
429  NSData *dataPrime = [NSData gtm_dataByRawInflatingBytes:[rawDeflated bytes]
430                                                   length:[rawDeflated length]];
431  STAssertNotNil(dataPrime, @"failed to raw inflate data block");
432  STAssertGreaterThan([dataPrime length],
433                      (NSUInteger)0, @"failed to raw inflate data block");
434  STAssertEqualObjects(data,
435                       dataPrime, @"failed to round trip via *Bytes apis");
436
437  // w/ *Data apis, default level
438  rawDeflated = [NSData gtm_dataByRawDeflatingData:data];
439  STAssertNotNil(rawDeflated, @"failed to raw deflate data block");
440  STAssertGreaterThan([rawDeflated length],
441                      (NSUInteger)0, @"failed to raw deflate data block");
442  STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data");
443  dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated];
444  STAssertNotNil(dataPrime, @"failed to raw inflate data block");
445  STAssertGreaterThan([dataPrime length],
446                      (NSUInteger)0, @"failed to raw inflate data block");
447  STAssertEqualObjects(data,
448                       dataPrime, @"failed to round trip via *Data apis");
449
450  // loop over the compression levels
451  for (int level = 1 ; level <= 9 ; ++level) {
452    // w/ *Bytes apis, using our level
453    rawDeflated = [NSData gtm_dataByRawDeflatingBytes:[data bytes]
454                                               length:[data length]
455                                     compressionLevel:level];
456    STAssertNotNil(rawDeflated, @"failed to rawDeflate data block");
457    STAssertGreaterThan([rawDeflated length],
458                        (NSUInteger)0, @"failed to raw deflate data block");
459    STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data");
460    dataPrime = [NSData gtm_dataByRawInflatingBytes:[rawDeflated bytes]
461                                             length:[rawDeflated length]];
462    STAssertNotNil(dataPrime, @"failed to raw inflate data block");
463    STAssertGreaterThan([dataPrime length],
464                        (NSUInteger)0, @"failed to raw inflate data block");
465    STAssertEqualObjects(data,
466                         dataPrime, @"failed to round trip via *Bytes apis");
467
468    // w/ *Data apis, using our level
469    rawDeflated = [NSData gtm_dataByRawDeflatingData:data
470                                    compressionLevel:level];
471    STAssertNotNil(rawDeflated, @"failed to deflate data block");
472    STAssertGreaterThan([rawDeflated length],
473                        (NSUInteger)0, @"failed to raw deflate data block");
474    STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data");
475    dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated];
476    STAssertNotNil(dataPrime, @"failed to raw inflate data block");
477    STAssertGreaterThan([dataPrime length],
478                        (NSUInteger)0, @"failed to raw inflate data block");
479    STAssertEqualObjects(data,
480                         dataPrime, @"failed to round trip via *Data apis");
481  }
482}
483
484- (void)testLargeData {
485  // Generate some large data out of the random chunk by xoring over it
486  // to make sure it changes and isn't too repeated.
487  NSData *data = [NSData dataWithBytes:randomDataLarge
488                                length:sizeof(randomDataLarge)];
489  STAssertNotNil(data, @"failed to alloc data block");
490  const uint8_t *dataBytes = [data bytes];
491  NSMutableData *scratch = [NSMutableData dataWithLength:[data length]];
492  STAssertNotNil(scratch, @"failed to alloc data block");
493  uint8_t *scratchBytes = [scratch mutableBytes];
494  NSMutableData *input = [NSMutableData dataWithCapacity:200 * [data length]];
495  for (NSUInteger i = 0; i < 200; ++i) {
496    for (NSUInteger j = 0; j < [data length]; ++j) {
497      scratchBytes[j] = dataBytes[j] ^ i;
498    }
499    [input appendData:scratch];
500  }
501
502  // The internal buffer size for GTM's deflate/inflate is 1024.
503  NSUInteger internalBufferSize = 1024;
504
505  // Should deflate to more then one buffer size to make sure the internal loop
506  // is working.
507  NSData *compressed = [NSData gtm_dataByDeflatingData:input
508                                      compressionLevel:9];
509  STAssertNotNil(compressed, @"failed to deflate");
510  STAssertGreaterThan([compressed length], internalBufferSize,
511                      @"should have been more then %d bytes",
512                      (int)internalBufferSize);
513
514  // Should inflate to more then one buffer size to make sure the internal loop
515  // is working.
516  NSData *uncompressed = [NSData gtm_dataByInflatingData:compressed];
517  STAssertNotNil(uncompressed, @"fail to inflate");
518  STAssertGreaterThan([uncompressed length], internalBufferSize,
519                      @"should have been more then %d bytes",
520                      (int)internalBufferSize);
521
522  STAssertEqualObjects(uncompressed, input,
523                       @"didn't get the same thing back");
524}
525
526@end