/* bzip2 decompression and compression Original Source: (See copyright notice at ) */ /*" decompress the file to the given path. Returns 0 or greater if OK; negative is an error code. You will need to link against libbz2.a, either the one included in Jaguar, or wrapped and linked into your framework/application bundle. "*/ #import "bzlib.h" - (int) decompressBzip2ToPath:(NSString *)inPath; { // First, create all the sub-directories as needed NSArray *components = [inPath pathComponents]; int i; int theCount = [components count]; for (i = 1 ; i < theCount ; i++ ) // DO ALL BUT THE LAST COMPONENT, USE < NOT <= { NSArray *subComponents = [components subarrayWithRange: NSMakeRange(0,i)]; NSString *subPath = [NSString pathWithComponents:subComponents]; BOOL isDir; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:subPath isDirectory:&isDir]; if (!exists) { BOOL ok = [[NSFileManager defaultManager] createDirectoryAtPath:subPath attributes:nil]; if (!ok) { return BZ_IO_ERROR; } } } int verbosity = 0; int small = 0; // don't use small-memory model int bufferSize = 10240; // How many bytes to write out at a time char *buf = malloc(bufferSize); const char *pathName = [[NSFileManager defaultManager] fileSystemRepresentationWithPath:inPath]; FILE* f = fopen ( pathName, "w" ); if (nil == f) { return BZ_IO_ERROR; } // use trio BZ2_bzDecompressInit, BZ2_bzDecompress and BZ2_bzDecompressEnd for decompression. int ret = BZ_OK; bz_stream strm; strm.bzalloc = NULL; strm.bzfree = NULL; strm.opaque = NULL; ret = BZ2_bzDecompressInit ( &strm, verbosity, small ); if (ret != BZ_OK) return ret; strm.next_in = (char *)[self bytes]; // the compressed data strm.avail_in = [self length]; // how much to read while (BZ_OK == ret) { strm.next_out = buf; // buffer to write into strm.avail_out = bufferSize; // how much is available in buffer ret = BZ2_bzDecompress ( &strm ); // Write out the bufs if we had no error. if (BZ_OK == ret || BZ_STREAM_END == ret) { size_t written = fwrite(buf, sizeof(char), strm.next_out - buf, f); if (0 == written) { NSLog(@"Wrote zero bytes"); } } } fclose(f); free (buf); BZ2_bzDecompressEnd ( &strm ); return ret; } /* Compress data. NOT ACTUALLY EVER TESTED; PLEASE SEND FEEDBACK ON THIS! */ - (NSData *) compressBzip2 { NSData *result = nil; int blockSize100k = 5; // NOT SURE WHAT BEST VALUE IS. int verbosity = 0; // SHOULD BE ZERO TO BE QUIET. int workFactor = 0; // 0 = USE THE DEFAULT VALUE unsigned int sourceLength = [self length]; unsigned int destLength = 1.01 * sourceLength + 600; // Official formula, Big enough to hold output. Will change to real size. char *dest = malloc(destLength); char *source = (char *) [self bytes]; int returnCode = BZ2_bzBuffToBuffCompress( dest, &destLength, source, sourceLength, blockSize100k, verbosity, workFactor ); if (BZ_OK == returnCode) { result = [NSData dataWithBytesNoCopy:dest length:destLength]; // Do not free bytes; NSData now owns it. } else { NSLog(@"-[NSData decompressBzip2]: error %d returned",returnCode); free(dest); } return result; } // BZIP DOCUMENTATION: ftp://sources.redhat.com/pub/bzip2/docs/manual_3.html