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