Objective-C
zlib

zlibを使ってNSDataに圧縮/展開機能を追加する

More than 3 years have passed since last update.

NSDataと言えばバイト配列を扱うデータホルダー的なクラスです。

データホルダーなら、保持するデータを圧縮する機能があっても良いはず。

ということでNSDataを拡張してzlib機能を追加してみましょう。

まずはインタフェース。


NSDataExt.h

#import <Foundation/Foundation.h>


@interface NSData (NSDataZlibExtension)
- (id)deflate:(int)compressionLevel;
- (id)inflate;
@end

そして実装です。


NSDataExt.m

#import "NSDataZlib.h"

#import <zlib.h>

@implementation NSData (NSDataZlibExtension)
- (z_stream)initialized_zStream {
z_stream zStream;
zStream.zalloc = Z_NULL;
zStream.zfree = Z_NULL;
zStream.opaque = Z_NULL;
return zStream;
}

- (id)deflate:(int)compressionLevel {
z_stream zStream = [self initialized_zStream];
Bytef buffer[131072];
deflateInit(&zStream, compressionLevel);
zStream.next_in = (Bytef *)self.bytes;
zStream.avail_in = (UInt)self.length;
int retval = Z_OK;
NSMutableData *ret = [NSMutableData dataWithCapacity:0];
do {
zStream.next_out = buffer;
zStream.avail_out = sizeof(buffer);
retval = deflate(&zStream, Z_FINISH);
size_t length = sizeof(buffer) - zStream.avail_out;
if (length > 0)
[ret appendBytes:buffer length:length];
} while (zStream.avail_out != sizeof(buffer));
deflateEnd(&zStream);
return ret;
}

- (id)inflate {
z_stream zStream = [self initialized_zStream];
Bytef buffer[131072];
inflateInit(&zStream);
zStream.next_in = (Bytef *)self.bytes;
zStream.avail_in = (UInt)self.length;
int retval = Z_OK;
NSMutableData *ret = [NSMutableData dataWithCapacity:0];
do {
zStream.next_out = buffer;
zStream.avail_out = sizeof(buffer);
retval = inflate(&zStream, Z_FINISH);
size_t length = sizeof(buffer) - zStream.avail_out;
if (length > 0)
[ret appendBytes:buffer length:length];
} while (zStream.avail_out != sizeof(buffer));
inflateEnd(&zStream);
return ret;
}
@end