├── .gitignore ├── .travis.yml ├── BZipCompression.podspec ├── Code ├── BZipCompression.h └── BZipCompression.m ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.md ├── Rakefile └── Tests ├── BZipCompressionTests.m ├── BZipCompressionTests.xcodeproj └── project.pbxproj ├── Fixture.txt ├── Fixture.txt.bz2 ├── OS X Tests-Info.plist ├── Prefix.pch ├── Schemes ├── OS X Tests.xcscheme └── iOS Tests.xcscheme ├── anna_karenina.txt ├── anna_karenina.txt.bz2 └── iOS Tests-Info.plist /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | 20 | Pods 21 | Tests/BZipCompressionTests.xcodeproj/xcshareddata/ 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | script: rake test 3 | -------------------------------------------------------------------------------- /BZipCompression.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'BZipCompression' 3 | s.version = '1.0.2' 4 | s.license = 'Apache2' 5 | s.summary = 'An Objective-C interface for the BZip2 compression algorithm' 6 | s.homepage = 'https://github.com/blakewatters/BZipCompression' 7 | s.authors = { 'Blake Watters' => 'blakewatters@gmail.com' } 8 | s.source = { :git => 'https://github.com/blakewatters/BZipCompression.git', :tag => "v#{s.version}" } 9 | s.source_files = 'Code' 10 | s.requires_arc = true 11 | 12 | s.library = 'bz2' 13 | 14 | s.ios.deployment_target = '5.0' 15 | s.osx.deployment_target = '10.7' 16 | end 17 | -------------------------------------------------------------------------------- /Code/BZipCompression.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZipCompression.h 3 | // BZipCompression 4 | // 5 | // Created by Blake Watters on 9/19/13. 6 | // Copyright (c) 2013 Blake Watters. All rights reserved. 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | // The domain for errors returned by the BZip library. 22 | extern NSString * const BZipErrorDomain; 23 | 24 | typedef NS_ENUM(NSInteger, BZipError) { 25 | // Underlying BZip2 Library Errors 26 | BZipErrorSequence = -1, // BZ_SEQUENCE_ERROR 27 | BZipErrorInvalidParameter = -2, // BZ_PARAM_ERROR 28 | BZipErrorMemoryAllocationFailed = -3, // BZ_MEM_ERROR 29 | BZipErrorDataIntegrity = -4, // BZ_DATA_ERROR 30 | BZipErrorIncorrectMagicData = -5, // BZ_DATA_ERROR_MAGIC 31 | BZipErrorIOFailure = -6, // BZ_IO_ERROR 32 | BZipErrorUnexpectedEOF = -7, // BZ_UNEXPECTED_EOF 33 | BZipErrorOutputBufferFull = -8, // BZ_OUTBUFF_FULL 34 | BZipErrorInvalidConfiguration = -9, // BZ_CONFIG_ERROR 35 | 36 | // BZipCompression Errors 37 | BZipErrorNilInputDataError = 1000, 38 | BZipErrorInvalidSourcePath = 1001, 39 | BZipErrorInvalidDestinationPath = 1002, 40 | BZipErrorUnableToCreateDestinationPath = 1003, 41 | BZipErrorFileManagementFailure = 1004, 42 | BZipErrorOperationCancelled = 1005 43 | }; 44 | 45 | /** 46 | A sensible default block size (of 7) for compression. 47 | */ 48 | extern NSInteger const BZipDefaultBlockSize; 49 | 50 | /** 51 | A sensible default work factor (of 0) for compression. 52 | */ 53 | extern NSInteger const BZipDefaultWorkFactor; 54 | 55 | /** 56 | The `BZipCompression` class provides a static Objective-C interface for the compression and decompression of data using the BZip2 algorithm. 57 | 58 | This code was adapted from a Stack Overflow posting: http://stackoverflow.com/a/11390277/177284 59 | 60 | Learn details about the BZip2 compression algorithm at http://www.bzip.org/ 61 | */ 62 | @interface BZipCompression : NSObject 63 | 64 | //-------------------------- 65 | /// @name Compressing Data 66 | //-------------------------- 67 | 68 | /** 69 | @abstract Returns a representation of the input data compressed with the BZip2 algorithm using the specified work factor. 70 | 71 | @param data The uncompressed source input data that is to be compressed. 72 | @param blockSize A value between 1 and 9 inclusize that specifies the block size used for compression. The actual memory used will be 100000 x this number. A value of 9 gives the best compression, but uses the most memory. If unsure, pass `BZipDefaultBlockSize`. 73 | @param workFactor Specifies how compression behaves when presented with worst case, highly repetitive data. Lower values will result in more aggressive use of a slower fallback compression alogrithm, potentially inflating compression times unnecessarilly. Values range from 0 to 250. Passing `0` instructs the library to use the default value. If unsure, pass `BZipDefaultWorkFactor`. 74 | @error A pointer to an error object that, upon failure, is set to an `NSError` object indicating the nature of the failure. 75 | @return A new `NSData` object encapsulating the compressed representation of the input data or `nil` if compression failed. 76 | */ 77 | + (NSData *)compressedDataWithData:(NSData *)data blockSize:(NSInteger)blockSize workFactor:(NSInteger)workFactor error:(NSError **)error; 78 | 79 | //-------------------------- 80 | /// @name Decompressing Data 81 | //-------------------------- 82 | 83 | /** 84 | @abstract Returns a decompressed representation of the input data, which must be compressed using the BZip2 algorithm. 85 | 86 | @param data The compressed input data that is to be decompressed. 87 | @error A pointer to an error object that, upon failure, is set to an `NSError` object indicating the nature of the failure. 88 | @return A new `NSData` object encapsulating the decompressed representation of the input data or `nil` if decompression failed. 89 | */ 90 | + (NSData *)decompressedDataWithData:(NSData *)data error:(NSError **)error; 91 | 92 | /** 93 | @abstract Decompresses the specified file, whose contents must be data compressed using the BZip2 algorithm, to the specified destination path. 94 | @discussion This method performs decompression using efficient streaming file I/O. It is suitable for use with files of arbitrary size. 95 | 96 | @param sourcePath The source file containing BZip2 compressed data that is to be decompressed. 97 | @param destinationPath The destination path that the decompressed data will be written to. 98 | */ 99 | + (BOOL)decompressDataFromFileAtPath:(NSString *)sourcePath toFileAtPath:(NSString *)destinationPath error:(NSError **)error; 100 | 101 | /** 102 | @abstract Asynchronously decompresses the specified file, whose contents must be data compressed using the BZip2 algorithm, to the specified destination path, optionally reporting progress and invoking a block upon completion. 103 | @discussion This method performs decompression using efficient streaming file I/O. It is suitable for use with files of arbitrary size. 104 | 105 | @param sourcePath The source file containing BZip2 compressed data that is to be decompressed. 106 | @param destinationPath The destination path that the decompressed data will be written to. 107 | @param progress A pointer to an `NSProgress` object that upon return will be set to an object reporting progress on the decompression operation. 108 | @param completion A block to execute upon completion of the decompression operation. The block has no return value and accepts two arguments: a Bpolean value that indicates if the operation was successful and an error describing the nature of the failure if the operation was not successful. 109 | */ 110 | + (void)asynchronouslyDecompressFileAtPath:(NSString *)sourcePath toFileAtPath:(NSString *)destinationPath progress:(NSProgress **)progress completion:(void (^)(BOOL success, NSError *error))completion; 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /Code/BZipCompression.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZipCompression.m 3 | // BZipCompression 4 | // 5 | // Created by Blake Watters on 9/19/13. 6 | // Copyright (c) 2013 Blake Watters. All rights reserved. 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import 22 | #import "BZipCompression.h" 23 | 24 | NSString * const BZipErrorDomain = @"com.blakewatters.BZipCompression"; 25 | static const char *BZipCompressionQueueLabel = "com.blakewatters.BZipCompression.compressionQueue"; 26 | static NSUInteger const BZipCompressionBufferSize = 1024; 27 | NSInteger const BZipDefaultBlockSize = 7; 28 | NSInteger const BZipDefaultWorkFactor = 0; 29 | 30 | @implementation BZipCompression 31 | 32 | + (NSData *)compressedDataWithData:(NSData *)data blockSize:(NSInteger)blockSize workFactor:(NSInteger)workFactor error:(NSError **)error 33 | { 34 | if (!data) { 35 | if (error) { 36 | *error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorNilInputDataError userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Input data cannot be `nil`.", nil) }]; 37 | } 38 | return nil; 39 | } 40 | if ([data length] == 0) return data; 41 | 42 | bz_stream stream; 43 | bzero(&stream, sizeof(stream)); 44 | stream.next_in = (char *)[data bytes]; 45 | stream.avail_in = [data length]; 46 | 47 | NSMutableData *buffer = [NSMutableData dataWithLength:BZipCompressionBufferSize]; 48 | stream.next_out = [buffer mutableBytes]; 49 | stream.avail_out = BZipCompressionBufferSize; 50 | 51 | int bzret; 52 | bzret = BZ2_bzCompressInit(&stream, blockSize, 0, workFactor); 53 | if (bzret != BZ_OK) { 54 | if (error) { 55 | *error = [NSError errorWithDomain:BZipErrorDomain code:bzret userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"`BZ2_bzCompressInit` failed", nil) }]; 56 | } 57 | return nil; 58 | } 59 | 60 | NSMutableData *compressedData = [NSMutableData data]; 61 | do { 62 | bzret = BZ2_bzCompress(&stream, (stream.avail_in) ? BZ_RUN : BZ_FINISH); 63 | if (bzret < BZ_OK) { 64 | if (error) { 65 | *error = [NSError errorWithDomain:BZipErrorDomain code:bzret userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"`BZ2_bzCompress` failed", nil) }]; 66 | } 67 | return nil; 68 | } 69 | 70 | [compressedData appendBytes:[buffer bytes] length:(BZipCompressionBufferSize - stream.avail_out)]; 71 | stream.next_out = [buffer mutableBytes]; 72 | stream.avail_out = BZipCompressionBufferSize; 73 | } while (bzret != BZ_STREAM_END); 74 | 75 | BZ2_bzCompressEnd(&stream); 76 | 77 | return compressedData; 78 | } 79 | 80 | + (NSData *)decompressedDataWithData:(NSData *)data error:(NSError **)error 81 | { 82 | if (!data) { 83 | if (error) { 84 | *error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorNilInputDataError userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Input data cannot be `nil`.", nil) }]; 85 | } 86 | return nil; 87 | } 88 | if ([data length] == 0) return data; 89 | 90 | bz_stream stream; 91 | bzero(&stream, sizeof(stream)); 92 | stream.next_in = (char *)[data bytes]; 93 | stream.avail_in = [data length]; 94 | 95 | NSMutableData *buffer = [NSMutableData dataWithLength:BZipCompressionBufferSize]; 96 | stream.next_out = [buffer mutableBytes]; 97 | stream.avail_out = BZipCompressionBufferSize; 98 | 99 | int bzret; 100 | bzret = BZ2_bzDecompressInit(&stream, 0, NO); 101 | if (bzret != BZ_OK) { 102 | if (error) { 103 | *error = [NSError errorWithDomain:BZipErrorDomain code:bzret userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"`BZ2_bzDecompressInit` failed", nil) }]; 104 | } 105 | return nil; 106 | } 107 | 108 | NSMutableData *decompressedData = [NSMutableData data]; 109 | do { 110 | bzret = BZ2_bzDecompress(&stream); 111 | if (bzret < BZ_OK) { 112 | if (error) { 113 | *error = [NSError errorWithDomain:BZipErrorDomain code:bzret userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"`BZ2_bzDecompress` failed", nil) }]; 114 | } 115 | return nil; 116 | } 117 | 118 | [decompressedData appendBytes:[buffer bytes] length:(BZipCompressionBufferSize - stream.avail_out)]; 119 | stream.next_out = [buffer mutableBytes]; 120 | stream.avail_out = BZipCompressionBufferSize; 121 | } while (bzret != BZ_STREAM_END); 122 | 123 | BZ2_bzDecompressEnd(&stream); 124 | 125 | return decompressedData; 126 | } 127 | 128 | + (BOOL)decompressDataFromFileAtPath:(NSString *)sourcePath toFileAtPath:(NSString *)destinationPath error:(NSError **)error 129 | { 130 | dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 131 | __block BOOL success; 132 | __block NSError *outputError = nil; 133 | [self asynchronouslyDecompressFileAtPath:sourcePath toFileAtPath:destinationPath progress:nil completion:^(BOOL completionSuccess, NSError *completionError) { 134 | success = completionSuccess; 135 | outputError = completionError; 136 | dispatch_semaphore_signal(semaphore); 137 | }]; 138 | dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 139 | if (error) { 140 | *error = outputError; 141 | } 142 | return success; 143 | } 144 | 145 | + (void)asynchronouslyDecompressFileAtPath:(NSString *)sourcePath toFileAtPath:(NSString *)destinationPath progress:(NSProgress **)progress completion:(void (^)(BOOL success, NSError *error))completion 146 | { 147 | __block NSError *error = nil; 148 | BOOL isDirectory; 149 | if (![[NSFileManager defaultManager] fileExistsAtPath:sourcePath isDirectory:&isDirectory]) { 150 | error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorInvalidSourcePath userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because the source path given does not exist.", nil) }]; 151 | if (completion) { 152 | completion(NO, error); 153 | } 154 | return; 155 | } 156 | if (isDirectory) { 157 | error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorInvalidSourcePath userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because the source path given is a directory.", nil) }]; 158 | if (completion) { 159 | completion(NO, error); 160 | } 161 | return; 162 | } 163 | 164 | if ([[NSFileManager defaultManager] fileExistsAtPath:destinationPath isDirectory:&isDirectory]) { 165 | error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorInvalidDestinationPath userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because the destination path given already exists.", nil) }]; 166 | if (completion) { 167 | completion(NO, error); 168 | } 169 | return; 170 | } 171 | if (isDirectory) { 172 | error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorInvalidDestinationPath userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because the destination path given is a directory.", nil) }]; 173 | if (completion) { 174 | completion(NO, error); 175 | } 176 | return; 177 | } 178 | 179 | NSError *attributesError = nil; 180 | NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:sourcePath error:&attributesError]; 181 | if (!attributes) { 182 | error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorFileManagementFailure userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because the size of the source path .", nil), NSUnderlyingErrorKey: attributesError }]; 183 | if (completion) { 184 | completion(NO, error); 185 | } 186 | return; 187 | } 188 | unsigned long long sourceFileSize = [[attributes objectForKey:NSFileSize] unsignedLongLongValue]; 189 | 190 | BOOL success = [[NSFileManager defaultManager] createFileAtPath:destinationPath contents:nil attributes:nil]; 191 | if (!success) { 192 | error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorUnableToCreateDestinationPath userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because the destination path could not be created.", nil) }]; 193 | if (completion) { 194 | completion(NO, error); 195 | } 196 | return; 197 | } 198 | 199 | NSProgress *decompressionProgress = [NSProgress progressWithTotalUnitCount:sourceFileSize]; 200 | decompressionProgress.kind = NSProgressKindFile; 201 | decompressionProgress.cancellable = YES; 202 | decompressionProgress.pausable = NO; 203 | if (progress) { 204 | *progress = decompressionProgress; 205 | } 206 | 207 | dispatch_queue_t decompressionQueue = dispatch_queue_create(BZipCompressionQueueLabel, DISPATCH_QUEUE_SERIAL); 208 | dispatch_async(decompressionQueue, ^{ 209 | unsigned long long totalBytesProcessed = 0; 210 | 211 | bz_stream stream; 212 | bzero(&stream, sizeof(stream)); 213 | NSFileHandle *inputFileHandle = [NSFileHandle fileHandleForReadingAtPath:sourcePath]; 214 | if (!inputFileHandle) { 215 | error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorInvalidSourcePath userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because a readable file handle for the source path could not be created.", nil) }]; 216 | if (completion) { 217 | completion(NO, error); 218 | } 219 | return; 220 | } 221 | 222 | NSFileHandle *outputFileHandle = [NSFileHandle fileHandleForWritingAtPath:destinationPath]; 223 | if (!outputFileHandle) { 224 | error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorInvalidDestinationPath userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because a writable file handle for the destination path could not be created.", nil) }]; 225 | if (completion) { 226 | completion(NO, error); 227 | } 228 | return; 229 | } 230 | 231 | NSMutableData *compressedDataBuffer = [NSMutableData new]; 232 | int bzret = BZ_OK; 233 | bzret = BZ2_bzDecompressInit(&stream, 0, NO); 234 | if (bzret != BZ_OK) { 235 | error = [NSError errorWithDomain:BZipErrorDomain code:bzret userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because `BZ2_bzDecompressInit` returned an error.", nil) }]; 236 | } else { 237 | while (true) { 238 | if (decompressionProgress.isCancelled) { 239 | error = [NSError errorWithDomain:BZipErrorDomain code:BZipErrorOperationCancelled userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because the operation was cancelled.", nil) }]; 240 | break; 241 | } 242 | NSData *inputChunk = [inputFileHandle readDataOfLength:BZipCompressionBufferSize]; 243 | if ([inputChunk length] == 0) { 244 | // No data left to read -- all done 245 | break; 246 | } 247 | [compressedDataBuffer appendData:inputChunk]; 248 | 249 | totalBytesProcessed += [inputChunk length]; 250 | [decompressionProgress setCompletedUnitCount:totalBytesProcessed]; 251 | stream.next_in = (char *)[compressedDataBuffer bytes]; 252 | stream.avail_in = [compressedDataBuffer length]; 253 | 254 | NSMutableData *decompressedDataBuffer = [NSMutableData dataWithLength:BZipCompressionBufferSize]; 255 | while (true) { 256 | stream.next_out = [decompressedDataBuffer mutableBytes]; 257 | stream.avail_out = BZipCompressionBufferSize; 258 | 259 | bzret = BZ2_bzDecompress(&stream); 260 | if (bzret < BZ_OK) { 261 | error = [NSError errorWithDomain:BZipErrorDomain code:bzret userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Decompression failed because `BZ2_bzDecompress` returned an error.", nil) }]; 262 | break; 263 | } 264 | NSData *decompressedData = [NSMutableData dataWithBytes:[decompressedDataBuffer bytes] length:(BZipCompressionBufferSize - stream.avail_out)]; 265 | [outputFileHandle writeData:decompressedData]; 266 | 267 | if ((BZipCompressionBufferSize - stream.avail_out) == 0) { 268 | // Save the remaining bits for the next iteration 269 | [compressedDataBuffer setData:[NSData dataWithBytes:stream.next_in length:stream.avail_in]]; 270 | break; 271 | } 272 | 273 | if (bzret == BZ_STREAM_END) { 274 | break; 275 | } 276 | } 277 | 278 | if (bzret == BZ_STREAM_END || error) { 279 | break; 280 | } 281 | } 282 | 283 | BZ2_bzDecompressEnd(&stream); 284 | } 285 | 286 | [inputFileHandle closeFile]; 287 | [outputFileHandle closeFile]; 288 | 289 | if (error) { 290 | [[NSFileManager defaultManager] removeItemAtPath:destinationPath error:nil]; 291 | } 292 | if (completion) { 293 | completion(error == nil, error); 294 | } 295 | }); 296 | } 297 | 298 | @end 299 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | ruby '2.1.2' 3 | 4 | gem 'rake', '~> 10.3.2' 5 | gem 'cocoapods', '~> 0.35.0' 6 | gem 'xctasks', '~> 0.4.1' 7 | gem 'xcpretty', '~> 0.1.7' 8 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activesupport (4.1.8) 5 | i18n (~> 0.6, >= 0.6.9) 6 | json (~> 1.7, >= 1.7.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.1) 9 | tzinfo (~> 1.1) 10 | claide (0.7.0) 11 | cocoapods (0.35.0) 12 | activesupport (>= 3.2.15) 13 | claide (~> 0.7.0) 14 | cocoapods-core (= 0.35.0) 15 | cocoapods-downloader (~> 0.8.0) 16 | cocoapods-plugins (~> 0.3.1) 17 | cocoapods-trunk (~> 0.4.1) 18 | cocoapods-try (~> 0.4.2) 19 | colored (~> 1.2) 20 | escape (~> 0.0.4) 21 | molinillo (~> 0.1.2) 22 | nap (~> 0.8) 23 | open4 (~> 1.3) 24 | xcodeproj (~> 0.20.2) 25 | cocoapods-core (0.35.0) 26 | activesupport (>= 3.2.15) 27 | fuzzy_match (~> 2.0.4) 28 | nap (~> 0.8.0) 29 | cocoapods-downloader (0.8.0) 30 | cocoapods-plugins (0.3.2) 31 | nap 32 | cocoapods-trunk (0.4.1) 33 | nap (>= 0.8) 34 | netrc (= 0.7.8) 35 | cocoapods-try (0.4.2) 36 | colored (1.2) 37 | escape (0.0.4) 38 | fuzzy_match (2.0.4) 39 | i18n (0.6.11) 40 | json (1.8.1) 41 | mini_portile (0.6.1) 42 | minitest (5.4.3) 43 | molinillo (0.1.2) 44 | nap (0.8.0) 45 | netrc (0.7.8) 46 | nokogiri (1.6.5) 47 | mini_portile (~> 0.6.0) 48 | open4 (1.3.4) 49 | rake (10.3.2) 50 | thread_safe (0.3.4) 51 | tzinfo (1.2.2) 52 | thread_safe (~> 0.1) 53 | xcodeproj (0.20.2) 54 | activesupport (>= 3) 55 | colored (~> 1.2) 56 | xcpretty (0.1.7) 57 | xctasks (0.4.1) 58 | nokogiri (~> 1.6, >= 1.6.3.1) 59 | rake (~> 10.0, >= 10.0.0) 60 | 61 | PLATFORMS 62 | ruby 63 | 64 | DEPENDENCIES 65 | cocoapods (~> 0.35.0) 66 | rake (~> 10.3.2) 67 | xcpretty (~> 0.1.7) 68 | xctasks (~> 0.4.1) 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "[]" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright [yyyy] [name of copyright owner] 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, 7.0 2 | 3 | xcodeproj 'Tests/BZipCompressionTests' 4 | workspace 'BZipCompression' 5 | inhibit_all_warnings! 6 | 7 | def import_pods 8 | pod 'Expecta', '~> 0.3.0' 9 | pod 'BZipCompression', :path => '.' 10 | end 11 | 12 | target :ios do 13 | platform :ios, '7.0' 14 | link_with 'iOS Tests' 15 | import_pods 16 | end 17 | 18 | target :osx do 19 | platform :osx, '10.7' 20 | link_with 'OS X Tests' 21 | import_pods 22 | end 23 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - BZipCompression (1.0.2) 3 | - Expecta (0.3.1) 4 | 5 | DEPENDENCIES: 6 | - BZipCompression (from `.`) 7 | - Expecta (~> 0.3.0) 8 | 9 | EXTERNAL SOURCES: 10 | BZipCompression: 11 | :path: . 12 | 13 | SPEC CHECKSUMS: 14 | BZipCompression: 01a58ec18215e65b7c9231985ba87259b4c18e80 15 | Expecta: 03aabd0a89d8dea843baecb19a7fd7466a69a31d 16 | 17 | COCOAPODS: 0.35.0 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BZipCompression 2 | =============== 3 | 4 | [![Build Status](https://travis-ci.org/blakewatters/BZipCompression.png?branch=master)](https://travis-ci.org/blakewatters/BZipCompression) 5 | [![Pod Version](http://img.shields.io/cocoapods/v/BZipCompression.svg?style=flat)](http://cocoadocs.org/docsets/BZipCompression/) 6 | [![Pod Platform](http://img.shields.io/cocoapods/p/BZipCompression.svg?style=flat)](http://cocoadocs.org/docsets/BZipCompression/) 7 | [![Pod License](http://img.shields.io/cocoapods/l/BZipCompression.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html) 8 | 9 | **An Objective-C interface to the BZip2 compression library** 10 | 11 | [BZip2](http://bzip.org/) is freely available, patent free, high-quality data compressor. It is highly portable and C library implementations are available on all OS X and iOS devices. 12 | 13 | BZipCompression is a simple Objective-C interface to the BZip2 compression library. It wraps the low level interface of the bz2 C library into a straightforward, idiomatic Objective-C class. 14 | 15 | ## Features 16 | 17 | * Decompress `NSData` instances containing data that was compressed with the BZip2 algorithm. 18 | * Compress an `NSData` instance containing arbitrary data into a bzip2 representation. 19 | 20 | ## Usage 21 | 22 | The library is implemented as a static interface with only two public methods: one for compression and one for decompression. 23 | 24 | ### Decompressing Data 25 | 26 | ```objc 27 | NSURL *compressedFileURL = [[NSBundle mainBundle] URLForResource:@"SomeLargeFile" withExtension:@".json.bz2"]; 28 | NSData *compressedData = [NSData dataWithContentsOfURL:compressedFileURL]; 29 | NSError *error = nil; 30 | NSData *decompressedData = [BZipCompression decompressedDataWithData:compressedData error:&error]; 31 | ``` 32 | 33 | ### Compressing Data 34 | 35 | ```objc 36 | NSData *stringData = [@"You probably want to read your data from a file or another data source rather than using string literals." dataUsingEncoding:NSUTF8StringEncoding]; 37 | NSError *error = nil; 38 | NSData *compressedData = [BZipCompression compressedDataWithData:stringData blockSize:BZipDefaultBlockSize workFactor:BZipDefaultWorkFactor error:&error]; 39 | ``` 40 | 41 | ## Installation 42 | 43 | BZipCompression is extremely lightweight and has no direct dependencies outside of the Cocoa Foundation framework and the BZip2 library. As such, the library can be trivially be installed into any Cocoa project by directly adding the source code and linking against libbz2. Despite this fact, we recommend installing via CocoaPods as it provides modularity and easy version management. 44 | 45 | ### Via CocoaPods 46 | 47 | The recommended approach for installing BZipCompression is via the [CocoaPods](http://cocoapods.org/) package manager, as it provides flexible dependency management and dead simple installation. For best results, it is recommended that you install via CocoaPods **>= 0.24.0** using Git **>= 1.8.0** installed via Homebrew. 48 | 49 | Install CocoaPods if not already available: 50 | 51 | ``` bash 52 | $ [sudo] gem install cocoapods 53 | $ pod setup 54 | ``` 55 | 56 | Change to the directory of your Xcode project, and Create and Edit your Podfile and add BZipCompression: 57 | 58 | ``` bash 59 | $ cd /path/to/MyProject 60 | $ touch Podfile 61 | $ edit Podfile 62 | platform :ios, '5.0' 63 | # Or platform :osx, '10.7' 64 | pod 'BZipCompression', '~> 1.0.0' 65 | ``` 66 | 67 | Install into your project: 68 | 69 | ``` bash 70 | $ pod install 71 | ``` 72 | 73 | Open your project in Xcode from the .xcworkspace file (not the usual project file) 74 | 75 | ``` bash 76 | $ open MyProject.xcworkspace 77 | ``` 78 | 79 | ### Via Source Code 80 | 81 | Simply add `BZipCompression.h` and `BZipCompression.m` to your project and `#import "BZipCompression.h"`. 82 | 83 | ## Unit Tests 84 | 85 | BZipCompression is tested using the [Expecta](https://github.com/specta/Expecta) library of unit testing matchers. In order to run the tests, you must do the following: 86 | 87 | 1. Install the dependencies via CocoaPods: `pod install` 88 | 1. Open the workspace: `open BZipCompression.xcworkspace` 89 | 1. Run the specs via the **Product** menu > **Test** 90 | 91 | ## Credits 92 | 93 | Blake Watters 94 | 95 | - http://github.com/blakewatters 96 | - http://twitter.com/blakewatters 97 | - blakewatters@gmail.com 98 | 99 | ## License 100 | 101 | BZipCompression is available under the Apache 2 License. See the LICENSE file for more info. 102 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler' 3 | Bundler.setup 4 | require 'xctasks/test_task' 5 | 6 | XCTasks::TestTask.new(:test) do |t| 7 | t.workspace = 'BZipCompression.xcworkspace' 8 | t.schemes_dir = 'Tests/Schemes' 9 | t.runner = :xcpretty 10 | t.actions = %w{test} 11 | 12 | t.subtask(ios: 'iOS Tests') do |s| 13 | s.sdk = :iphonesimulator 14 | end 15 | 16 | t.subtask(osx: 'OS X Tests') do |s| 17 | s.sdk = :macosx 18 | end 19 | end 20 | 21 | task default: 'test' 22 | -------------------------------------------------------------------------------- /Tests/BZipCompressionTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZipCompressionTests.h 3 | // BZipCompression 4 | // 5 | // Created by Blake Watters on 9/19/13. 6 | // Copyright (c) 2013 Blake Watters. All rights reserved. 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import 22 | #define EXP_SHORTHAND 23 | #import "Expecta.h" 24 | #import "BZipCompression.h" 25 | 26 | @interface BZipCompressionTests : XCTestCase 27 | 28 | @property (nonatomic, readonly) NSBundle *testsBundle; 29 | 30 | @end 31 | 32 | @implementation BZipCompressionTests 33 | 34 | - (void)setUp 35 | { 36 | _testsBundle = [NSBundle bundleForClass:[self class]]; 37 | } 38 | 39 | - (void)testDecompression 40 | { 41 | NSURL *fixtureURL = [self.testsBundle URLForResource:@"Fixture" withExtension:@".txt.bz2"]; 42 | NSData *compressedData = [NSData dataWithContentsOfURL:fixtureURL]; 43 | NSError *error = nil; 44 | NSData *decompressedData = [BZipCompression decompressedDataWithData:compressedData error:&error]; 45 | expect(decompressedData).notTo.beNil(); 46 | NSString *decompressedFileContents = [[NSString alloc] initWithData:decompressedData encoding:NSUTF8StringEncoding]; 47 | expect(decompressedFileContents).to.equal(@"Hello World!\n"); 48 | } 49 | 50 | - (void)testDecompressionFailureWithNonCompressedFile 51 | { 52 | NSURL *fixtureURL = [self.testsBundle URLForResource:@"Fixture" withExtension:@".txt"]; 53 | NSData *compressedData = [NSData dataWithContentsOfURL:fixtureURL]; 54 | NSError *error = nil; 55 | NSData *decompressedData = [BZipCompression decompressedDataWithData:compressedData error:&error]; 56 | expect(decompressedData).to.beNil(); 57 | expect(error).notTo.beNil(); 58 | expect(error.code).to.equal(BZipErrorIncorrectMagicData); 59 | } 60 | 61 | - (void)testDecompressionFailsWithErrorIfGivenNilInputData 62 | { 63 | NSError *error = nil; 64 | NSData *decompressedData = [BZipCompression decompressedDataWithData:nil error:&error]; 65 | expect(decompressedData).to.beNil(); 66 | expect(error).notTo.beNil(); 67 | expect(error.code).to.equal(BZipErrorNilInputDataError); 68 | } 69 | 70 | - (void)testDecompressionToPath 71 | { 72 | NSString *inputPath = [self.testsBundle pathForResource:@"Fixture" ofType:@"txt.bz2"]; 73 | NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%@", [[NSProcessInfo processInfo] globallyUniqueString], @"fixture.txt"]]; 74 | NSError *error = nil; 75 | BOOL success = [BZipCompression decompressDataFromFileAtPath:inputPath toFileAtPath:outputPath error:&error]; 76 | expect(success).to.beTruthy(); 77 | expect(error).to.beNil(); 78 | NSString *decompressedFileContents = [NSString stringWithContentsOfFile:outputPath encoding:NSUTF8StringEncoding error:&error]; 79 | expect(decompressedFileContents).to.equal(@"Hello World!\n"); 80 | } 81 | 82 | - (void)testDecompressionOfLargeFileToPath 83 | { 84 | NSString *inputPath = [self.testsBundle pathForResource:@"anna_karenina" ofType:@"txt.bz2"]; 85 | NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%@", [[NSProcessInfo processInfo] globallyUniqueString], @"anna_karenina.txt"]]; 86 | NSError *error = nil; 87 | BOOL success = [BZipCompression decompressDataFromFileAtPath:inputPath toFileAtPath:outputPath error:&error]; 88 | expect(success).to.beTruthy(); 89 | expect(error).to.beNil(); 90 | 91 | NSString *referenceFile = [self.testsBundle pathForResource:@"anna_karenina" ofType:@"txt"]; 92 | BOOL contentsAreEqual = [[NSFileManager defaultManager] contentsEqualAtPath:outputPath andPath:referenceFile]; 93 | expect(contentsAreEqual).to.beTruthy(); 94 | } 95 | 96 | - (void)testAsyncDecompressonToPath 97 | { 98 | NSString *inputPath = [self.testsBundle pathForResource:@"anna_karenina" ofType:@"txt.bz2"]; 99 | NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%@", [[NSProcessInfo processInfo] globallyUniqueString], @"anna_karenina.txt"]]; 100 | __block BOOL done = NO; 101 | [BZipCompression asynchronouslyDecompressFileAtPath:inputPath toFileAtPath:outputPath progress:nil completion:^(BOOL success, NSError *error) { 102 | expect(success).to.beTruthy(); 103 | expect(error).to.beNil(); 104 | done = YES; 105 | }]; 106 | expect(done).will.beTruthy(); 107 | 108 | NSString *referenceFile = [self.testsBundle pathForResource:@"anna_karenina" ofType:@"txt"]; 109 | BOOL contentsAreEqual = [[NSFileManager defaultManager] contentsEqualAtPath:outputPath andPath:referenceFile]; 110 | expect(contentsAreEqual).to.beTruthy(); 111 | } 112 | 113 | - (void)testMonitoringProgressOfDecompressionOperation 114 | { 115 | NSString *inputPath = [self.testsBundle pathForResource:@"anna_karenina" ofType:@"txt.bz2"]; 116 | NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%@", [[NSProcessInfo processInfo] globallyUniqueString], @"anna_karenina.txt"]]; 117 | __block BOOL done = NO; 118 | NSProgress *progress = nil; 119 | [BZipCompression asynchronouslyDecompressFileAtPath:inputPath toFileAtPath:outputPath progress:&progress completion:^(BOOL success, NSError *error) { 120 | expect(success).to.beTruthy(); 121 | expect(error).to.beNil(); 122 | done = YES; 123 | }]; 124 | expect(progress).notTo.beNil(); 125 | expect(progress.totalUnitCount).to.equal(530241); 126 | [progress addObserver:self 127 | forKeyPath:NSStringFromSelector(@selector(fractionCompleted)) 128 | options:NSKeyValueObservingOptionInitial 129 | context:nil]; 130 | expect(done).will.beTruthy(); 131 | expect(progress.fractionCompleted).to.equal(1.0); 132 | expect(progress.completedUnitCount).to.equal(530241); 133 | } 134 | 135 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 136 | change:(NSDictionary *)change context:(void *)context 137 | { 138 | NSProgress __unused *progress = object; 139 | // NSLog(@"Total unit completed %lld (fraction completed=%f)", progress.completedUnitCount, progress.fractionCompleted); 140 | } 141 | 142 | - (void)testCompression 143 | { 144 | NSData *stringData = [@"God is a mute and there is no 'why?'." dataUsingEncoding:NSUTF8StringEncoding]; 145 | NSError *error = nil; 146 | NSData *compressedData = [BZipCompression compressedDataWithData:stringData blockSize:BZipDefaultBlockSize workFactor:0 error:&error]; 147 | expect(compressedData).notTo.beNil(); 148 | expect(error).to.beNil(); 149 | 150 | NSData *decompressedData = [BZipCompression decompressedDataWithData:compressedData error:&error]; 151 | expect(decompressedData).notTo.beNil(); 152 | NSString *decompressedFileContents = [[NSString alloc] initWithData:decompressedData encoding:NSUTF8StringEncoding]; 153 | expect(decompressedFileContents).to.equal(@"God is a mute and there is no 'why?'."); 154 | } 155 | 156 | - (void)testCompressionFailsWithErrorIfGivenNilInputData 157 | { 158 | NSError *error = nil; 159 | NSData *decompressedData = [BZipCompression compressedDataWithData:nil blockSize:BZipDefaultBlockSize workFactor:0 error:&error]; 160 | expect(decompressedData).to.beNil(); 161 | expect(error).notTo.beNil(); 162 | expect(error.code).to.equal(BZipErrorNilInputDataError); 163 | } 164 | 165 | @end 166 | -------------------------------------------------------------------------------- /Tests/BZipCompressionTests.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 252CB16A1A5622A200F46EF5 /* anna_karenina.txt in Resources */ = {isa = PBXBuildFile; fileRef = 252CB1681A5622A200F46EF5 /* anna_karenina.txt */; }; 11 | 252CB16B1A5622A200F46EF5 /* anna_karenina.txt in Resources */ = {isa = PBXBuildFile; fileRef = 252CB1681A5622A200F46EF5 /* anna_karenina.txt */; }; 12 | 252CB16C1A5622A200F46EF5 /* anna_karenina.txt.bz2 in Resources */ = {isa = PBXBuildFile; fileRef = 252CB1691A5622A200F46EF5 /* anna_karenina.txt.bz2 */; }; 13 | 252CB16D1A5622A200F46EF5 /* anna_karenina.txt.bz2 in Resources */ = {isa = PBXBuildFile; fileRef = 252CB1691A5622A200F46EF5 /* anna_karenina.txt.bz2 */; }; 14 | 256E734D191EEAE200F7BC9B /* Fixture.txt in Resources */ = {isa = PBXBuildFile; fileRef = 251986DE17EB687500699DBA /* Fixture.txt */; }; 15 | 256E734E191EEAE200F7BC9B /* Fixture.txt.bz2 in Resources */ = {isa = PBXBuildFile; fileRef = 2503F66117EB610D003567EF /* Fixture.txt.bz2 */; }; 16 | 256E734F191EEAE200F7BC9B /* Fixture.txt in Resources */ = {isa = PBXBuildFile; fileRef = 251986DE17EB687500699DBA /* Fixture.txt */; }; 17 | 256E7350191EEAE200F7BC9B /* Fixture.txt.bz2 in Resources */ = {isa = PBXBuildFile; fileRef = 2503F66117EB610D003567EF /* Fixture.txt.bz2 */; }; 18 | 25F6B13E191EEA0D00ED71D8 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25F6B13D191EEA0D00ED71D8 /* XCTest.framework */; }; 19 | 25F6B13F191EEA0D00ED71D8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25A0134F17DBC212006C2BD6 /* Foundation.framework */; }; 20 | 25F6B140191EEA0D00ED71D8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25A0134D17DBC212006C2BD6 /* UIKit.framework */; }; 21 | 25F6B152191EEA2000ED71D8 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25F6B13D191EEA0D00ED71D8 /* XCTest.framework */; }; 22 | 25F6B161191EEA7600ED71D8 /* BZipCompressionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2503F65E17EB5E1E003567EF /* BZipCompressionTests.m */; }; 23 | 25F6B162191EEA7A00ED71D8 /* BZipCompressionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2503F65E17EB5E1E003567EF /* BZipCompressionTests.m */; }; 24 | 5B641E9BDBCB4C7FB37682FB /* libPods-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C4355EA794D84F2BB2496AF8 /* libPods-ios.a */; }; 25 | A9204184A70B43CFB0D4E518 /* libPods-osx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 169BB4EE1051441592FCCA22 /* libPods-osx.a */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 0E2BE29A783676C2F4A76043 /* Pods-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.release.xcconfig"; path = "../Pods/Target Support Files/Pods-ios/Pods-ios.release.xcconfig"; sourceTree = ""; }; 30 | 169BB4EE1051441592FCCA22 /* libPods-osx.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-osx.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 176226F33F8218965E6A6EAE /* Pods-osx.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-osx.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-osx/Pods-osx.debug.xcconfig"; sourceTree = ""; }; 32 | 2503F65E17EB5E1E003567EF /* BZipCompressionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZipCompressionTests.m; sourceTree = ""; }; 33 | 2503F66117EB610D003567EF /* Fixture.txt.bz2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = Fixture.txt.bz2; sourceTree = ""; }; 34 | 251986DE17EB687500699DBA /* Fixture.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Fixture.txt; sourceTree = ""; }; 35 | 252CB1681A5622A200F46EF5 /* anna_karenina.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = anna_karenina.txt; sourceTree = ""; }; 36 | 252CB1691A5622A200F46EF5 /* anna_karenina.txt.bz2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = anna_karenina.txt.bz2; sourceTree = ""; }; 37 | 25A0134D17DBC212006C2BD6 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 38 | 25A0134F17DBC212006C2BD6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 39 | 25A0136517DBC225006C2BD6 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 40 | 25A0136817DBC225006C2BD6 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 41 | 25A0136917DBC225006C2BD6 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 42 | 25A0136A17DBC225006C2BD6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 43 | 25F6B13C191EEA0D00ED71D8 /* iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 25F6B13D191EEA0D00ED71D8 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 45 | 25F6B151191EEA2000ED71D8 /* OS X Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "OS X Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | A0C0EB73A9A655B876DE6ECA /* Pods-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-ios/Pods-ios.debug.xcconfig"; sourceTree = ""; }; 47 | B6DF6DD3C6C0407A8FA9E1F2 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | C3101BE74AE22074694E0496 /* Pods-osx.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-osx.release.xcconfig"; path = "../Pods/Target Support Files/Pods-osx/Pods-osx.release.xcconfig"; sourceTree = ""; }; 49 | C4355EA794D84F2BB2496AF8 /* libPods-ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 25F6B139191EEA0D00ED71D8 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 25F6B13E191EEA0D00ED71D8 /* XCTest.framework in Frameworks */, 58 | 25F6B140191EEA0D00ED71D8 /* UIKit.framework in Frameworks */, 59 | 25F6B13F191EEA0D00ED71D8 /* Foundation.framework in Frameworks */, 60 | 5B641E9BDBCB4C7FB37682FB /* libPods-ios.a in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | 25F6B14E191EEA2000ED71D8 /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | 25F6B152191EEA2000ED71D8 /* XCTest.framework in Frameworks */, 69 | A9204184A70B43CFB0D4E518 /* libPods-osx.a in Frameworks */, 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | 25A0133C17DBC1F4006C2BD6 = { 77 | isa = PBXGroup; 78 | children = ( 79 | 252CB1681A5622A200F46EF5 /* anna_karenina.txt */, 80 | 252CB1691A5622A200F46EF5 /* anna_karenina.txt.bz2 */, 81 | 2503F65E17EB5E1E003567EF /* BZipCompressionTests.m */, 82 | 251986DE17EB687500699DBA /* Fixture.txt */, 83 | 2503F66117EB610D003567EF /* Fixture.txt.bz2 */, 84 | 25A0134A17DBC212006C2BD6 /* Frameworks */, 85 | 25A0134917DBC212006C2BD6 /* Products */, 86 | 52A409E53941E07EE2E3E8E0 /* Pods */, 87 | ); 88 | sourceTree = ""; 89 | }; 90 | 25A0134917DBC212006C2BD6 /* Products */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 25F6B13C191EEA0D00ED71D8 /* iOS Tests.xctest */, 94 | 25F6B151191EEA2000ED71D8 /* OS X Tests.xctest */, 95 | ); 96 | name = Products; 97 | sourceTree = ""; 98 | }; 99 | 25A0134A17DBC212006C2BD6 /* Frameworks */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 25A0134D17DBC212006C2BD6 /* UIKit.framework */, 103 | 25A0134F17DBC212006C2BD6 /* Foundation.framework */, 104 | 25A0136517DBC225006C2BD6 /* Cocoa.framework */, 105 | 25F6B13D191EEA0D00ED71D8 /* XCTest.framework */, 106 | 25A0136717DBC225006C2BD6 /* Other Frameworks */, 107 | B6DF6DD3C6C0407A8FA9E1F2 /* libPods.a */, 108 | C4355EA794D84F2BB2496AF8 /* libPods-ios.a */, 109 | 169BB4EE1051441592FCCA22 /* libPods-osx.a */, 110 | ); 111 | name = Frameworks; 112 | sourceTree = ""; 113 | }; 114 | 25A0136717DBC225006C2BD6 /* Other Frameworks */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 25A0136817DBC225006C2BD6 /* AppKit.framework */, 118 | 25A0136917DBC225006C2BD6 /* CoreData.framework */, 119 | 25A0136A17DBC225006C2BD6 /* Foundation.framework */, 120 | ); 121 | name = "Other Frameworks"; 122 | sourceTree = ""; 123 | }; 124 | 52A409E53941E07EE2E3E8E0 /* Pods */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | A0C0EB73A9A655B876DE6ECA /* Pods-ios.debug.xcconfig */, 128 | 0E2BE29A783676C2F4A76043 /* Pods-ios.release.xcconfig */, 129 | 176226F33F8218965E6A6EAE /* Pods-osx.debug.xcconfig */, 130 | C3101BE74AE22074694E0496 /* Pods-osx.release.xcconfig */, 131 | ); 132 | name = Pods; 133 | sourceTree = ""; 134 | }; 135 | /* End PBXGroup section */ 136 | 137 | /* Begin PBXNativeTarget section */ 138 | 25F6B13B191EEA0D00ED71D8 /* iOS Tests */ = { 139 | isa = PBXNativeTarget; 140 | buildConfigurationList = 25F6B14A191EEA0D00ED71D8 /* Build configuration list for PBXNativeTarget "iOS Tests" */; 141 | buildPhases = ( 142 | E7F3E73A191B4C45AD82AC29 /* Check Pods Manifest.lock */, 143 | 25F6B138191EEA0D00ED71D8 /* Sources */, 144 | 25F6B139191EEA0D00ED71D8 /* Frameworks */, 145 | 25F6B13A191EEA0D00ED71D8 /* Resources */, 146 | DDED1006C25446D9B6116E13 /* Copy Pods Resources */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = "iOS Tests"; 153 | productName = "iOS Tests"; 154 | productReference = 25F6B13C191EEA0D00ED71D8 /* iOS Tests.xctest */; 155 | productType = "com.apple.product-type.bundle.unit-test"; 156 | }; 157 | 25F6B150191EEA2000ED71D8 /* OS X Tests */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = 25F6B15E191EEA2000ED71D8 /* Build configuration list for PBXNativeTarget "OS X Tests" */; 160 | buildPhases = ( 161 | FC8E824CAF6847468F8B8776 /* Check Pods Manifest.lock */, 162 | 25F6B14D191EEA2000ED71D8 /* Sources */, 163 | 25F6B14E191EEA2000ED71D8 /* Frameworks */, 164 | 25F6B14F191EEA2000ED71D8 /* Resources */, 165 | 997F43EEE7B54521B5741B49 /* Copy Pods Resources */, 166 | ); 167 | buildRules = ( 168 | ); 169 | dependencies = ( 170 | ); 171 | name = "OS X Tests"; 172 | productName = "OS X Tests"; 173 | productReference = 25F6B151191EEA2000ED71D8 /* OS X Tests.xctest */; 174 | productType = "com.apple.product-type.bundle.unit-test"; 175 | }; 176 | /* End PBXNativeTarget section */ 177 | 178 | /* Begin PBXProject section */ 179 | 25A0133D17DBC1F4006C2BD6 /* Project object */ = { 180 | isa = PBXProject; 181 | attributes = { 182 | LastTestingUpgradeCheck = 0510; 183 | LastUpgradeCheck = 0510; 184 | TargetAttributes = { 185 | 25F6B150191EEA2000ED71D8 = { 186 | TestTargetID = 25F6B13B191EEA0D00ED71D8; 187 | }; 188 | }; 189 | }; 190 | buildConfigurationList = 25A0134017DBC1F4006C2BD6 /* Build configuration list for PBXProject "BZipCompressionTests" */; 191 | compatibilityVersion = "Xcode 3.2"; 192 | developmentRegion = English; 193 | hasScannedForEncodings = 0; 194 | knownRegions = ( 195 | en, 196 | ); 197 | mainGroup = 25A0133C17DBC1F4006C2BD6; 198 | productRefGroup = 25A0134917DBC212006C2BD6 /* Products */; 199 | projectDirPath = ""; 200 | projectRoot = ""; 201 | targets = ( 202 | 25F6B13B191EEA0D00ED71D8 /* iOS Tests */, 203 | 25F6B150191EEA2000ED71D8 /* OS X Tests */, 204 | ); 205 | }; 206 | /* End PBXProject section */ 207 | 208 | /* Begin PBXResourcesBuildPhase section */ 209 | 25F6B13A191EEA0D00ED71D8 /* Resources */ = { 210 | isa = PBXResourcesBuildPhase; 211 | buildActionMask = 2147483647; 212 | files = ( 213 | 256E734E191EEAE200F7BC9B /* Fixture.txt.bz2 in Resources */, 214 | 252CB16C1A5622A200F46EF5 /* anna_karenina.txt.bz2 in Resources */, 215 | 256E734D191EEAE200F7BC9B /* Fixture.txt in Resources */, 216 | 252CB16A1A5622A200F46EF5 /* anna_karenina.txt in Resources */, 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | 25F6B14F191EEA2000ED71D8 /* Resources */ = { 221 | isa = PBXResourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | 256E7350191EEAE200F7BC9B /* Fixture.txt.bz2 in Resources */, 225 | 252CB16D1A5622A200F46EF5 /* anna_karenina.txt.bz2 in Resources */, 226 | 256E734F191EEAE200F7BC9B /* Fixture.txt in Resources */, 227 | 252CB16B1A5622A200F46EF5 /* anna_karenina.txt in Resources */, 228 | ); 229 | runOnlyForDeploymentPostprocessing = 0; 230 | }; 231 | /* End PBXResourcesBuildPhase section */ 232 | 233 | /* Begin PBXShellScriptBuildPhase section */ 234 | 997F43EEE7B54521B5741B49 /* Copy Pods Resources */ = { 235 | isa = PBXShellScriptBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | ); 239 | inputPaths = ( 240 | ); 241 | name = "Copy Pods Resources"; 242 | outputPaths = ( 243 | ); 244 | runOnlyForDeploymentPostprocessing = 0; 245 | shellPath = /bin/sh; 246 | shellScript = "\"${SRCROOT}/../Pods/Target Support Files/Pods-osx/Pods-osx-resources.sh\"\n"; 247 | showEnvVarsInLog = 0; 248 | }; 249 | DDED1006C25446D9B6116E13 /* Copy Pods Resources */ = { 250 | isa = PBXShellScriptBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | ); 254 | inputPaths = ( 255 | ); 256 | name = "Copy Pods Resources"; 257 | outputPaths = ( 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | shellPath = /bin/sh; 261 | shellScript = "\"${SRCROOT}/../Pods/Target Support Files/Pods-ios/Pods-ios-resources.sh\"\n"; 262 | showEnvVarsInLog = 0; 263 | }; 264 | E7F3E73A191B4C45AD82AC29 /* Check Pods Manifest.lock */ = { 265 | isa = PBXShellScriptBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | ); 269 | inputPaths = ( 270 | ); 271 | name = "Check Pods Manifest.lock"; 272 | outputPaths = ( 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | shellPath = /bin/sh; 276 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 277 | showEnvVarsInLog = 0; 278 | }; 279 | FC8E824CAF6847468F8B8776 /* Check Pods Manifest.lock */ = { 280 | isa = PBXShellScriptBuildPhase; 281 | buildActionMask = 2147483647; 282 | files = ( 283 | ); 284 | inputPaths = ( 285 | ); 286 | name = "Check Pods Manifest.lock"; 287 | outputPaths = ( 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | shellPath = /bin/sh; 291 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 292 | showEnvVarsInLog = 0; 293 | }; 294 | /* End PBXShellScriptBuildPhase section */ 295 | 296 | /* Begin PBXSourcesBuildPhase section */ 297 | 25F6B138191EEA0D00ED71D8 /* Sources */ = { 298 | isa = PBXSourcesBuildPhase; 299 | buildActionMask = 2147483647; 300 | files = ( 301 | 25F6B161191EEA7600ED71D8 /* BZipCompressionTests.m in Sources */, 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | 25F6B14D191EEA2000ED71D8 /* Sources */ = { 306 | isa = PBXSourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | 25F6B162191EEA7A00ED71D8 /* BZipCompressionTests.m in Sources */, 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | /* End PBXSourcesBuildPhase section */ 314 | 315 | /* Begin XCBuildConfiguration section */ 316 | 25A0134117DBC1F4006C2BD6 /* Debug */ = { 317 | isa = XCBuildConfiguration; 318 | buildSettings = { 319 | ONLY_ACTIVE_ARCH = YES; 320 | }; 321 | name = Debug; 322 | }; 323 | 25A0134217DBC1F4006C2BD6 /* Release */ = { 324 | isa = XCBuildConfiguration; 325 | buildSettings = { 326 | }; 327 | name = Release; 328 | }; 329 | 25F6B14B191EEA0D00ED71D8 /* Debug */ = { 330 | isa = XCBuildConfiguration; 331 | baseConfigurationReference = A0C0EB73A9A655B876DE6ECA /* Pods-ios.debug.xcconfig */; 332 | buildSettings = { 333 | ALWAYS_SEARCH_USER_PATHS = NO; 334 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 335 | CLANG_CXX_LIBRARY = "libc++"; 336 | CLANG_ENABLE_MODULES = YES; 337 | CLANG_ENABLE_OBJC_ARC = YES; 338 | CLANG_WARN_BOOL_CONVERSION = YES; 339 | CLANG_WARN_CONSTANT_CONVERSION = YES; 340 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 341 | CLANG_WARN_EMPTY_BODY = YES; 342 | CLANG_WARN_ENUM_CONVERSION = YES; 343 | CLANG_WARN_INT_CONVERSION = YES; 344 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 345 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 346 | COPY_PHASE_STRIP = NO; 347 | FRAMEWORK_SEARCH_PATHS = ( 348 | "$(SDKROOT)/Developer/Library/Frameworks", 349 | "$(inherited)", 350 | "$(DEVELOPER_FRAMEWORKS_DIR)", 351 | ); 352 | GCC_C_LANGUAGE_STANDARD = gnu99; 353 | GCC_DYNAMIC_NO_PIC = NO; 354 | GCC_OPTIMIZATION_LEVEL = 0; 355 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 356 | GCC_PREFIX_HEADER = Prefix.pch; 357 | GCC_PREPROCESSOR_DEFINITIONS = ( 358 | "DEBUG=1", 359 | "$(inherited)", 360 | ); 361 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 362 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 363 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 364 | GCC_WARN_UNDECLARED_SELECTOR = YES; 365 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 366 | GCC_WARN_UNUSED_FUNCTION = YES; 367 | GCC_WARN_UNUSED_VARIABLE = YES; 368 | INFOPLIST_FILE = "iOS Tests-Info.plist"; 369 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 370 | PRODUCT_NAME = "$(TARGET_NAME)"; 371 | SDKROOT = iphoneos; 372 | WRAPPER_EXTENSION = xctest; 373 | }; 374 | name = Debug; 375 | }; 376 | 25F6B14C191EEA0D00ED71D8 /* Release */ = { 377 | isa = XCBuildConfiguration; 378 | baseConfigurationReference = 0E2BE29A783676C2F4A76043 /* Pods-ios.release.xcconfig */; 379 | buildSettings = { 380 | ALWAYS_SEARCH_USER_PATHS = NO; 381 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 382 | CLANG_CXX_LIBRARY = "libc++"; 383 | CLANG_ENABLE_MODULES = YES; 384 | CLANG_ENABLE_OBJC_ARC = YES; 385 | CLANG_WARN_BOOL_CONVERSION = YES; 386 | CLANG_WARN_CONSTANT_CONVERSION = YES; 387 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 388 | CLANG_WARN_EMPTY_BODY = YES; 389 | CLANG_WARN_ENUM_CONVERSION = YES; 390 | CLANG_WARN_INT_CONVERSION = YES; 391 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 393 | COPY_PHASE_STRIP = YES; 394 | ENABLE_NS_ASSERTIONS = NO; 395 | FRAMEWORK_SEARCH_PATHS = ( 396 | "$(SDKROOT)/Developer/Library/Frameworks", 397 | "$(inherited)", 398 | "$(DEVELOPER_FRAMEWORKS_DIR)", 399 | ); 400 | GCC_C_LANGUAGE_STANDARD = gnu99; 401 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 402 | GCC_PREFIX_HEADER = Prefix.pch; 403 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 404 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 405 | GCC_WARN_UNDECLARED_SELECTOR = YES; 406 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 407 | GCC_WARN_UNUSED_FUNCTION = YES; 408 | GCC_WARN_UNUSED_VARIABLE = YES; 409 | INFOPLIST_FILE = "iOS Tests-Info.plist"; 410 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 411 | PRODUCT_NAME = "$(TARGET_NAME)"; 412 | SDKROOT = iphoneos; 413 | VALIDATE_PRODUCT = YES; 414 | WRAPPER_EXTENSION = xctest; 415 | }; 416 | name = Release; 417 | }; 418 | 25F6B15F191EEA2000ED71D8 /* Debug */ = { 419 | isa = XCBuildConfiguration; 420 | baseConfigurationReference = 176226F33F8218965E6A6EAE /* Pods-osx.debug.xcconfig */; 421 | buildSettings = { 422 | ALWAYS_SEARCH_USER_PATHS = NO; 423 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 424 | CLANG_CXX_LIBRARY = "libc++"; 425 | CLANG_ENABLE_MODULES = YES; 426 | CLANG_ENABLE_OBJC_ARC = YES; 427 | CLANG_WARN_BOOL_CONVERSION = YES; 428 | CLANG_WARN_CONSTANT_CONVERSION = YES; 429 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 430 | CLANG_WARN_EMPTY_BODY = YES; 431 | CLANG_WARN_ENUM_CONVERSION = YES; 432 | CLANG_WARN_INT_CONVERSION = YES; 433 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 434 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 435 | COPY_PHASE_STRIP = NO; 436 | FRAMEWORK_SEARCH_PATHS = ( 437 | "$(DEVELOPER_FRAMEWORKS_DIR)", 438 | "$(inherited)", 439 | ); 440 | GCC_C_LANGUAGE_STANDARD = gnu99; 441 | GCC_DYNAMIC_NO_PIC = NO; 442 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 443 | GCC_OPTIMIZATION_LEVEL = 0; 444 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 445 | GCC_PREFIX_HEADER = Prefix.pch; 446 | GCC_PREPROCESSOR_DEFINITIONS = ( 447 | "DEBUG=1", 448 | "$(inherited)", 449 | ); 450 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 451 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 452 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 453 | GCC_WARN_UNDECLARED_SELECTOR = YES; 454 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 455 | GCC_WARN_UNUSED_FUNCTION = YES; 456 | GCC_WARN_UNUSED_VARIABLE = YES; 457 | INFOPLIST_FILE = "OS X Tests-Info.plist"; 458 | MACOSX_DEPLOYMENT_TARGET = 10.9; 459 | PRODUCT_NAME = "$(TARGET_NAME)"; 460 | SDKROOT = macosx; 461 | WRAPPER_EXTENSION = xctest; 462 | }; 463 | name = Debug; 464 | }; 465 | 25F6B160191EEA2000ED71D8 /* Release */ = { 466 | isa = XCBuildConfiguration; 467 | baseConfigurationReference = C3101BE74AE22074694E0496 /* Pods-osx.release.xcconfig */; 468 | buildSettings = { 469 | ALWAYS_SEARCH_USER_PATHS = NO; 470 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 471 | CLANG_CXX_LIBRARY = "libc++"; 472 | CLANG_ENABLE_MODULES = YES; 473 | CLANG_ENABLE_OBJC_ARC = YES; 474 | CLANG_WARN_BOOL_CONVERSION = YES; 475 | CLANG_WARN_CONSTANT_CONVERSION = YES; 476 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 477 | CLANG_WARN_EMPTY_BODY = YES; 478 | CLANG_WARN_ENUM_CONVERSION = YES; 479 | CLANG_WARN_INT_CONVERSION = YES; 480 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 481 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 482 | COPY_PHASE_STRIP = YES; 483 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 484 | ENABLE_NS_ASSERTIONS = NO; 485 | FRAMEWORK_SEARCH_PATHS = ( 486 | "$(DEVELOPER_FRAMEWORKS_DIR)", 487 | "$(inherited)", 488 | ); 489 | GCC_C_LANGUAGE_STANDARD = gnu99; 490 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 491 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 492 | GCC_PREFIX_HEADER = Prefix.pch; 493 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 494 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 495 | GCC_WARN_UNDECLARED_SELECTOR = YES; 496 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 497 | GCC_WARN_UNUSED_FUNCTION = YES; 498 | GCC_WARN_UNUSED_VARIABLE = YES; 499 | INFOPLIST_FILE = "OS X Tests-Info.plist"; 500 | MACOSX_DEPLOYMENT_TARGET = 10.9; 501 | PRODUCT_NAME = "$(TARGET_NAME)"; 502 | SDKROOT = macosx; 503 | WRAPPER_EXTENSION = xctest; 504 | }; 505 | name = Release; 506 | }; 507 | /* End XCBuildConfiguration section */ 508 | 509 | /* Begin XCConfigurationList section */ 510 | 25A0134017DBC1F4006C2BD6 /* Build configuration list for PBXProject "BZipCompressionTests" */ = { 511 | isa = XCConfigurationList; 512 | buildConfigurations = ( 513 | 25A0134117DBC1F4006C2BD6 /* Debug */, 514 | 25A0134217DBC1F4006C2BD6 /* Release */, 515 | ); 516 | defaultConfigurationIsVisible = 0; 517 | defaultConfigurationName = Release; 518 | }; 519 | 25F6B14A191EEA0D00ED71D8 /* Build configuration list for PBXNativeTarget "iOS Tests" */ = { 520 | isa = XCConfigurationList; 521 | buildConfigurations = ( 522 | 25F6B14B191EEA0D00ED71D8 /* Debug */, 523 | 25F6B14C191EEA0D00ED71D8 /* Release */, 524 | ); 525 | defaultConfigurationIsVisible = 0; 526 | defaultConfigurationName = Release; 527 | }; 528 | 25F6B15E191EEA2000ED71D8 /* Build configuration list for PBXNativeTarget "OS X Tests" */ = { 529 | isa = XCConfigurationList; 530 | buildConfigurations = ( 531 | 25F6B15F191EEA2000ED71D8 /* Debug */, 532 | 25F6B160191EEA2000ED71D8 /* Release */, 533 | ); 534 | defaultConfigurationIsVisible = 0; 535 | defaultConfigurationName = Release; 536 | }; 537 | /* End XCConfigurationList section */ 538 | }; 539 | rootObject = 25A0133D17DBC1F4006C2BD6 /* Project object */; 540 | } 541 | -------------------------------------------------------------------------------- /Tests/Fixture.txt: -------------------------------------------------------------------------------- 1 | This is a plain text file. 2 | -------------------------------------------------------------------------------- /Tests/Fixture.txt.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blakewatters/BZipCompression/b5825cb1f2695ba1155df8b0f5cb293ff7c40ce6/Tests/Fixture.txt.bz2 -------------------------------------------------------------------------------- /Tests/OS X Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.restkit.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/Prefix.pch: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #if __IPHONE_OS_VERSION_MIN_REQUIRED 4 | #ifndef __IPHONE_3_0 5 | #warning "This project uses features only available in iPhone SDK 3.0 and later." 6 | #endif 7 | 8 | #ifdef __OBJC__ 9 | #import 10 | #import 11 | #endif 12 | #else 13 | #ifdef __OBJC__ 14 | #import 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /Tests/Schemes/OS X Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 52 | 53 | 54 | 55 | 61 | 62 | 64 | 65 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /Tests/Schemes/iOS Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 52 | 53 | 54 | 55 | 61 | 62 | 64 | 65 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /Tests/anna_karenina.txt.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blakewatters/BZipCompression/b5825cb1f2695ba1155df8b0f5cb293ff7c40ce6/Tests/anna_karenina.txt.bz2 -------------------------------------------------------------------------------- /Tests/iOS Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.restkit.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | --------------------------------------------------------------------------------