mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
92 lines
2.6 KiB
Objective-C
92 lines
2.6 KiB
Objective-C
#import <MtProtoKit/MTGzip.h>
|
|
|
|
#import <zlib.h>
|
|
|
|
@implementation MTGzip
|
|
|
|
+ (NSData * _Nullable)decompress:(NSData *)data {
|
|
const int kMemoryChunkSize = 1024;
|
|
|
|
NSUInteger length = [data length];
|
|
int windowBits = 15 + 32; //Default + gzip header instead of zlib header
|
|
int retCode;
|
|
unsigned char output[kMemoryChunkSize];
|
|
uInt gotBack;
|
|
NSMutableData *result;
|
|
z_stream stream;
|
|
|
|
if ((length == 0) || (length > UINT_MAX)) //FIXME: Support 64 bit inputs
|
|
return nil;
|
|
|
|
bzero(&stream, sizeof(z_stream));
|
|
stream.avail_in = (uInt)length;
|
|
stream.next_in = (unsigned char*)[data bytes];
|
|
|
|
retCode = inflateInit2(&stream, windowBits);
|
|
if(retCode != Z_OK)
|
|
{
|
|
NSLog(@"%s: inflateInit2() failed with error %i", __PRETTY_FUNCTION__, retCode);
|
|
return nil;
|
|
}
|
|
|
|
result = [NSMutableData dataWithCapacity:(length * 4)];
|
|
do
|
|
{
|
|
stream.avail_out = kMemoryChunkSize;
|
|
stream.next_out = output;
|
|
retCode = inflate(&stream, Z_NO_FLUSH);
|
|
if ((retCode != Z_OK) && (retCode != Z_STREAM_END))
|
|
{
|
|
NSLog(@"%s: inflate() failed with error %i", __PRETTY_FUNCTION__, retCode);
|
|
inflateEnd(&stream);
|
|
return nil;
|
|
}
|
|
gotBack = kMemoryChunkSize - stream.avail_out;
|
|
if (gotBack > 0)
|
|
[result appendBytes:output length:gotBack];
|
|
} while( retCode == Z_OK);
|
|
inflateEnd(&stream);
|
|
|
|
return (retCode == Z_STREAM_END ? result : nil);
|
|
}
|
|
|
|
+ (NSData * _Nullable)compress:(NSData *)data {
|
|
if (data.length == 0) {
|
|
return data;
|
|
}
|
|
|
|
z_stream stream;
|
|
stream.zalloc = Z_NULL;
|
|
stream.zfree = Z_NULL;
|
|
stream.opaque = Z_NULL;
|
|
stream.avail_in = (uint)data.length;
|
|
stream.next_in = (Bytef *)(void *)data.bytes;
|
|
stream.total_out = 0;
|
|
stream.avail_out = 0;
|
|
|
|
static const NSUInteger ChunkSize = 16384;
|
|
|
|
NSMutableData *output = nil;
|
|
int compression = Z_BEST_COMPRESSION;
|
|
if (deflateInit2(&stream, compression, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY) == Z_OK)
|
|
{
|
|
output = [NSMutableData dataWithLength:ChunkSize];
|
|
while (stream.avail_out == 0)
|
|
{
|
|
if (stream.total_out >= output.length)
|
|
{
|
|
output.length += ChunkSize;
|
|
}
|
|
stream.next_out = (uint8_t *)output.mutableBytes + stream.total_out;
|
|
stream.avail_out = (uInt)(output.length - stream.total_out);
|
|
deflate(&stream, Z_FINISH);
|
|
}
|
|
deflateEnd(&stream);
|
|
output.length = stream.total_out;
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
@end
|