FROM : Andrew Merenbach
DATE : Tue Aug 29 16:46:42 2006
I've not used NSAssert() much, but might there not be a memory leak
if it raises an NSInternalInconsistencyException (which, according
the docs, it does)? Your [compData release] call occurs only after
the block in which NSAssert() is called.
Perhaps an exception block with @finally would prove useful here?
Besides that (which is possibly moot, anyway, for as I say, I have
not used NSAssert() much), this is a really useful example to have!
Cheers,
Andrew
On Aug 29, 2006, at 3:01 AM, Fredrik Olsson wrote:
> Benjámin Salánki skrev:
>> Hey there,
>>
>> I'm looking for a way to compress my NSData before writing it to
>> file and then of course decompress it after reading it from file.
>>
>> I looked at zlib, but to tell you the truth I couldn't get it to
>> work.
>>
>> Is there a sample code snippet that I can take a look at? Can
>> anyone suggest a way to do this?
>>
> You can have mine, I have added compression and decompression as a
> category to NSData, do not forget to link with zlib by adding -lz
> to other linker flags. Change the AUTORELEASE and RELEASE macros to
> normal release and autorelease messages if you need to, I jusy use
> these macros not to forget to set pointers to nil for unused objects.
>
> - (NSData *) compressedData
> {
> NSData *result = nil;
> unsigned int srcLength = [self length];
> if (srcLength > 0) {
> uLong buffLength = srcLength * 1.001 + 12;
> NSMutableData *compData = [[NSMutableData alloc]
> initWithCapacity:buffLength];
> [compData increaseLengthBy:buffLength];
> int error = compress([compData mutableBytes], &buffLength,
> [self bytes], srcLength);
> switch( error ) {
> case Z_OK:
> [compData setLength: buffLength];
> COPY(result, compData);
> break;
> default:
> NSAssert(NO, @"Error compressing: Memory Error!");
> break;
> }
> RELEASE(compData);
> }
> AUTORELEASE(result);
> return result;
> }
>
> - (NSData *) decompressedData
> {
> if ([self length] == 0) return self;
> unsigned full_length = [self length];
> unsigned half_length = [self length] / 2;
> NSMutableData *decompressed = [NSMutableData dataWithLength:
> full_length + half_length];
> BOOL done = NO;
> int status;
> z_stream strm;
> strm.next_in = (Bytef *)[self bytes];
> strm.avail_in = [self length];
> strm.total_out = 0;
> strm.zalloc = Z_NULL;
> strm.zfree = Z_NULL;
> strm.opaque = Z_NULL;
> if (inflateInit(&strm) != Z_OK) {
> return nil;
> }
> while (!done) {
> // Make sure we have enough room and reset the lengths.
> if (strm.total_out >= [decompressed length]) {
> [decompressed increaseLengthBy: half_length];
> }
> strm.next_out = [decompressed mutableBytes] + strm.total_out;
> strm.avail_out = [decompressed length] - strm.total_out;
> // Inflate another chunk.
> status = inflate (&strm, Z_SYNC_FLUSH);
> if (status == Z_STREAM_END) {
> done = YES;
> } else if (status != Z_OK) {
> break;
> }
> }
> if (inflateEnd (&strm) != Z_OK) {
> return nil;
> }
> // Set real length.
> if (done) {
> [decompressed setLength: strm.total_out];
> return [NSData dataWithData: decompressed];
> } else {
> return nil;
> }
> }
>
> // Fredrik Olsson
>> Thanks,
>> Ben
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Cocoa-dev mailing list (<email_removed>)
>> Help/Unsubscribe/Update your Subscription:
>> http://lists.apple.com/mailman/options/cocoa-dev/fredrik.olsson%
>> 40kmstudio.se
>>
>> This email sent to fredrik.<email_removed>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Cocoa-dev mailing list (<email_removed>)
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/andrew.merenbach%
> 40ucla.edu
>
> This email sent to andrew.<email_removed>
DATE : Tue Aug 29 16:46:42 2006
I've not used NSAssert() much, but might there not be a memory leak
if it raises an NSInternalInconsistencyException (which, according
the docs, it does)? Your [compData release] call occurs only after
the block in which NSAssert() is called.
Perhaps an exception block with @finally would prove useful here?
Besides that (which is possibly moot, anyway, for as I say, I have
not used NSAssert() much), this is a really useful example to have!
Cheers,
Andrew
On Aug 29, 2006, at 3:01 AM, Fredrik Olsson wrote:
> Benjámin Salánki skrev:
>> Hey there,
>>
>> I'm looking for a way to compress my NSData before writing it to
>> file and then of course decompress it after reading it from file.
>>
>> I looked at zlib, but to tell you the truth I couldn't get it to
>> work.
>>
>> Is there a sample code snippet that I can take a look at? Can
>> anyone suggest a way to do this?
>>
> You can have mine, I have added compression and decompression as a
> category to NSData, do not forget to link with zlib by adding -lz
> to other linker flags. Change the AUTORELEASE and RELEASE macros to
> normal release and autorelease messages if you need to, I jusy use
> these macros not to forget to set pointers to nil for unused objects.
>
> - (NSData *) compressedData
> {
> NSData *result = nil;
> unsigned int srcLength = [self length];
> if (srcLength > 0) {
> uLong buffLength = srcLength * 1.001 + 12;
> NSMutableData *compData = [[NSMutableData alloc]
> initWithCapacity:buffLength];
> [compData increaseLengthBy:buffLength];
> int error = compress([compData mutableBytes], &buffLength,
> [self bytes], srcLength);
> switch( error ) {
> case Z_OK:
> [compData setLength: buffLength];
> COPY(result, compData);
> break;
> default:
> NSAssert(NO, @"Error compressing: Memory Error!");
> break;
> }
> RELEASE(compData);
> }
> AUTORELEASE(result);
> return result;
> }
>
> - (NSData *) decompressedData
> {
> if ([self length] == 0) return self;
> unsigned full_length = [self length];
> unsigned half_length = [self length] / 2;
> NSMutableData *decompressed = [NSMutableData dataWithLength:
> full_length + half_length];
> BOOL done = NO;
> int status;
> z_stream strm;
> strm.next_in = (Bytef *)[self bytes];
> strm.avail_in = [self length];
> strm.total_out = 0;
> strm.zalloc = Z_NULL;
> strm.zfree = Z_NULL;
> strm.opaque = Z_NULL;
> if (inflateInit(&strm) != Z_OK) {
> return nil;
> }
> while (!done) {
> // Make sure we have enough room and reset the lengths.
> if (strm.total_out >= [decompressed length]) {
> [decompressed increaseLengthBy: half_length];
> }
> strm.next_out = [decompressed mutableBytes] + strm.total_out;
> strm.avail_out = [decompressed length] - strm.total_out;
> // Inflate another chunk.
> status = inflate (&strm, Z_SYNC_FLUSH);
> if (status == Z_STREAM_END) {
> done = YES;
> } else if (status != Z_OK) {
> break;
> }
> }
> if (inflateEnd (&strm) != Z_OK) {
> return nil;
> }
> // Set real length.
> if (done) {
> [decompressed setLength: strm.total_out];
> return [NSData dataWithData: decompressed];
> } else {
> return nil;
> }
> }
>
> // Fredrik Olsson
>> Thanks,
>> Ben
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Cocoa-dev mailing list (<email_removed>)
>> Help/Unsubscribe/Update your Subscription:
>> http://lists.apple.com/mailman/options/cocoa-dev/fredrik.olsson%
>> 40kmstudio.se
>>
>> This email sent to fredrik.<email_removed>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Cocoa-dev mailing list (<email_removed>)
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/andrew.merenbach%
> 40ucla.edu
>
> This email sent to andrew.<email_removed>
| Related mails | Author | Date |
|---|---|---|
| Benjámin Salánki | Aug 28, 20:35 | |
| I. Savant | Aug 28, 20:40 | |
| Fredrik Olsson | Aug 29, 12:01 | |
| Benjámin Salánki | Aug 29, 15:55 | |
| Andrew Merenbach | Aug 29, 16:46 | |
| Fredrik Olsson | Aug 29, 18:14 |






Cocoa mail archive

