|
10 | 10 | #import "RCTUtils.h" |
11 | 11 |
|
12 | 12 | #import <mach/mach_time.h> |
13 | | -#import <objc/runtime.h> |
| 13 | +#import <objc/message.h> |
14 | 14 |
|
15 | 15 | #import <UIKit/UIKit.h> |
16 | 16 |
|
17 | 17 | #import <CommonCrypto/CommonCrypto.h> |
18 | 18 |
|
| 19 | +#import <zlib.h> |
| 20 | +#import <dlfcn.h> |
| 21 | + |
19 | 22 | #import "RCTLog.h" |
20 | 23 |
|
21 | 24 | NSString *RCTJSONStringify(id jsonObject, NSError **error) |
@@ -305,3 +308,51 @@ id RCTNilIfNull(id value) |
305 | 308 | [data base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0]]]; |
306 | 309 | } |
307 | 310 |
|
| 311 | +static BOOL RCTIsGzippedData(NSData *data) |
| 312 | +{ |
| 313 | + UInt8 *bytes = (UInt8 *)data.bytes; |
| 314 | + return (data.length >= 2 && bytes[0] == 0x1f && bytes[1] == 0x8b); |
| 315 | +} |
| 316 | + |
| 317 | +NSData *RCTGzipData(NSData *input, float level) |
| 318 | +{ |
| 319 | + if (input.length == 0 || RCTIsGzippedData(input)) { |
| 320 | + return input; |
| 321 | + } |
| 322 | + |
| 323 | + void *libz = dlopen("libz.dylib", RTLD_NOW); |
| 324 | + int (*deflateInit2_)(z_streamp, int, int, int, int, int, const char *, int) = dlsym(libz, "deflateInit2_"); |
| 325 | + int (*deflate)(z_streamp, int) = dlsym(libz, "deflate"); |
| 326 | + int (*deflateEnd)(z_streamp) = dlsym(libz, "deflateEnd"); |
| 327 | + |
| 328 | + z_stream stream; |
| 329 | + stream.zalloc = Z_NULL; |
| 330 | + stream.zfree = Z_NULL; |
| 331 | + stream.opaque = Z_NULL; |
| 332 | + stream.avail_in = (uint)input.length; |
| 333 | + stream.next_in = (Bytef *)input.bytes; |
| 334 | + stream.total_out = 0; |
| 335 | + stream.avail_out = 0; |
| 336 | + |
| 337 | + static const NSUInteger RCTGZipChunkSize = 16384; |
| 338 | + |
| 339 | + NSMutableData *output = nil; |
| 340 | + int compression = (level < 0.0f)? Z_DEFAULT_COMPRESSION: (int)(roundf(level * 9)); |
| 341 | + if (deflateInit2(&stream, compression, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY) == Z_OK) { |
| 342 | + output = [NSMutableData dataWithLength:RCTGZipChunkSize]; |
| 343 | + while (stream.avail_out == 0) { |
| 344 | + if (stream.total_out >= output.length) { |
| 345 | + output.length += RCTGZipChunkSize; |
| 346 | + } |
| 347 | + stream.next_out = (uint8_t *)output.mutableBytes + stream.total_out; |
| 348 | + stream.avail_out = (uInt)(output.length - stream.total_out); |
| 349 | + deflate(&stream, Z_FINISH); |
| 350 | + } |
| 351 | + deflateEnd(&stream); |
| 352 | + output.length = stream.total_out; |
| 353 | + } |
| 354 | + |
| 355 | + dlclose(libz); |
| 356 | + |
| 357 | + return output; |
| 358 | +} |
0 commit comments