【iOS/Objective-c】Gzip圧縮/解凍

うん、そんだけ。
libz.dylibを追加してね。

#import <zlib.h>

+ (NSData *)compressByGzip:(NSData *)source
{
    if (source.length == 0)
        return nil;
    
    z_stream stream = [self initializedStreamBySource:source];
    if (deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY) != Z_OK)
        return nil;
    
    NSMutableData *data = [NSMutableData dataWithCapacity:0];
    while (stream.avail_out == 0) {
        if (stream.total_out >= data.length)
            data.length += 16384;
        
        stream.next_out = data.mutableBytes + stream.total_out;
        stream.avail_out = data.length - stream.total_out;
        deflate(&stream, Z_FINISH);
    }
    deflateEnd(&stream);
    return data;
}

+ (NSData *)uncompressByGzip:(NSData *)source
{
    if (source.length == 0)
        return nil;
    
    z_stream stream = [self initializedStreamBySource:source];
    if (inflateInit2(&stream, 31) != Z_OK)
        return nil;
    
    NSMutableData *data = [NSMutableData dataWithCapacity:0];
    while (stream.avail_out == 0) {
        Bytef buffer[16384];
        stream.next_out = buffer;
        stream.avail_out = sizeof(buffer);
        inflate(&stream, Z_FINISH);
        size_t length = sizeof(buffer) - stream.avail_out;
        if (length > 0)
            [data appendBytes:buffer length:length];
    }
    inflateEnd(&stream);
    return data;
}

+ (z_stream)initializedStreamBySource:(NSData *)source {
    z_stream stream;
    stream.zalloc = Z_NULL;
    stream.zfree = Z_NULL;
    stream.opaque = Z_NULL;
    stream.avail_in = source.length;
    stream.next_in = (Bytef *)source.bytes;
    stream.total_out = 0;
    stream.avail_out = 0;
    return stream;
}