azcoastal azcoastal - 6 months ago 47
iOS Question

iOS (objective c) compression_decode_buffer() returns zero

I'm converting a very large json result on my server to a compressed format that I can decompress on my objective c app. I would prefer to use the iOS 9 compression lib if possible (libcompression.tbd), described in apple's CompressionSample/BlockCompression.c sample code.

I'm passing the compressed NSData result to the following method:

#include "compression.h"


...

- (NSData *) getDecompressedData:(NSData *) compressed {
size_t dst_buffer_size = 20000000; //20MB
uint8_t *dst_buffer = malloc(dst_buffer_size);
uint8_t *src_buffer = malloc(compressed.length);
[compressed getBytes:src_buffer length:compressed.length];

size_t decompressedSize = compression_decode_buffer(dst_buffer, dst_buffer_size, src_buffer, compressed.length, nil, COMPRESSION_ZLIB);
NSData *decompressed = [[NSData alloc] initWithBytes:dst_buffer length:decompressedSize];
return decompressed;
}


The
compressed
parameter has a length that matches my server logs, but the result from
compression_decode_buffer
is always zero and
dst_buffer
is not modified. I'm not receiving any errors, and the log has no relevant info.

I've tried ZLIB and LZ4 compression / decompression methods and several libraries on the server side, all with the same result.

What am I doing wrong here? Any guidance would be appreciated!

Answer

After much testing and research, I found that the compression library I was using on my server adds a compression header (1st two bytes), per RFC1950. I skipped those two bytes and compression_decode_buffer works like a champ!

- (NSData *) getDecompressedData:(NSData *) compressed {
    size_t dst_buffer_size = 20000000;   //20MB
    uint8_t *dst_buffer = malloc(dst_buffer_size);
    uint8_t *src_buffer = malloc(compressed.length);
    [compressed getBytes:src_buffer range:NSMakeRange(2, compressed.length - 2)];

    size_t decompressedSize = compression_decode_buffer(dst_buffer, dst_buffer_size, src_buffer, compressed.length - 2, nil, COMPRESSION_ZLIB);
    NSData *decompressed = [[NSData alloc] initWithBytes:dst_buffer length:decompressedSize];
    return decompressed;
}