PIVToken/NSData_Zip.m
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Implements ZIP functionality for PIV standard |
*/ |
#import <Foundation/Foundation.h> |
#import <zlib.h> |
#import <zconf.h> |
#import "Token.h" |
NS_ASSUME_NONNULL_BEGIN |
@implementation NSData(Zip) |
- (int)getWindowSize { |
int windowSize = MAX_WBITS; |
uint8_t *bytes = (uint8_t *)self.bytes; |
if (self.length > 2 && bytes[0] == 0x1F && bytes[1] == 0x8B) //gzip |
windowSize += 0x10; |
else |
windowSize += 0x20; |
return windowSize; |
} |
- (nullable NSData *)inflate { |
z_stream dstream; |
int windowSize = [self getWindowSize]; |
dstream.zalloc = (alloc_func)0; |
dstream.zfree = (free_func)0; |
dstream.opaque = (voidpf)0; |
/* Input not altered , so de-const-casting ok*/ |
dstream.next_in = (Bytef*)self.bytes; |
dstream.avail_in = (uInt)self.length; |
int err = inflateInit2(&dstream, windowSize); |
if (err != Z_OK) |
return nil; |
NSUInteger offset = 0; |
NSMutableData *data = [NSMutableData dataWithLength:1024]; |
for (;;) { |
dstream.next_out = [data mutableBytes] + offset; |
dstream.avail_out = (uInt)(data.length - offset); |
err = inflate(&dstream, Z_NO_FLUSH); |
if (err == Z_OK) { |
offset = data.length; |
[data setLength:data.length + data.length / 2]; |
} |
else if (err == Z_STREAM_END) { |
break; |
} |
else { |
inflateEnd(&dstream); |
return nil; |
} |
} |
[data setLength:dstream.total_out]; |
inflateEnd(&dstream); |
return data; |
} |
@end |
NS_ASSUME_NONNULL_END |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-09-22