I am just updating one of my applications and I have an error with my decompression method.
This is the warning I am experiencing
Implicit conversion loses integer precision: 'unsigned long' to 'unit' (aka 'unsigned int')
this is the line of code its happening on
stream.avail_in = len - stream.total_in;
And this is what the whole method looks like
#pragma mark - ZLib Compression Methods
// Returns the decompressed version if the zlib compressed input data or nil if there was an error
- (NSData*) dataByDecompressingData:(NSData*)data {
NSLog(@"%lu", (unsigned long)data.length);
Byte* bytes = (Byte*)[data bytes];
NSInteger len = [data length];
NSMutableData *decompressedData = [[NSMutableData alloc] initWithCapacity:COMPRESSION_BLOCK];
Byte* decompressedBytes = (Byte*) malloc(COMPRESSION_BLOCK);
z_stream stream;
int err;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
stream.next_in = bytes;
err = inflateInit(&stream);
CHECK_ERR(err, @"inflateInit");
while (true) {
stream.avail_in = len - stream.total_in;
stream.next_out = decompressedBytes;
stream.avail_out = COMPRESSION_BLOCK;
err = inflate(&stream, Z_NO_FLUSH);
[decompressedData appendBytes:decompressedBytes length:(stream.total_out-[decompressedData length])];
if(err == Z_STREAM_END)
break;
CHECK_ERR(err, @"inflate");
}
err = inflateEnd(&stream);
CHECK_ERR(err, @"inflateEnd");
free(decompressedBytes);
return decompressedData;
}
First off, you should not use
stream.total_in
. It may or may not be a large enough type for your application. It is alwaysunsigned long
. Use your own total input counter sized for your application and ignorestream.total_in
.Second, I'm guessing that your
CHECK_ERR()
aborts somehow. You should not abort in the event of aZ_BUF_ERROR
. In that case, you can continue by simply providing more input and/or more output space.Third, the problem here is that you need to pick a
stream.avail_in
that is assured to fit inunsigned
. You should be comparing the amount of remaining input to the largest value ofunsigned
, e.g.UINT_MAX
or(unsigned)0 - 1
. If the remaining data is larger, use the max value and deduct that from the remaining input. If smaller or equal, use all of it and set the remaining input to zero.