压缩
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
-(NSData *)compressData:(NSData *)uncompressedData
{
if
([uncompressedData length] ==
0
)
return
uncompressedData;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out =
0
;
strm.next_in=(Bytef *)[uncompressedData bytes];
strm.avail_in = (unsigned
int
)[uncompressedData length];
if
(deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (
15
+
16
),
8
, Z_DEFAULT_STRATEGY) != Z_OK)
return
nil;
NSMutableData *compressed = [NSMutableData dataWithLength:
16384
];
// 16K chunks for expansion
do
{
if
(strm.total_out >= [compressed length])
[compressed increaseLengthBy:
16384
];
strm.next_out = [compressed mutableBytes] + strm.total_out;
strm.avail_out = (unsigned
int
)([compressed length] - strm.total_out);
deflate(&strm, Z_FINISH);
}
while
(strm.avail_out ==
0
);
deflateEnd(&strm);
[compressed setLength: strm.total_out];
return
[NSData dataWithData:compressed];
}
|
解压缩
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
-(NSData *)uncompressZippedData:(NSData *)compressedData
{
if
([compressedData length] ==
0
)
return
compressedData;
unsigned full_length = [compressedData length];
unsigned half_length = [compressedData length] /
2
;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int
status;
z_stream strm;
strm.next_in = (Bytef *)[compressedData bytes];
strm.avail_in = [compressedData length];
strm.total_out =
0
;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if
(inflateInit2(&strm, (
15
+
32
)) != Z_OK)
return
nil;
while
(!done) {
// Make sure we have enough room and reset the lengths.
if
(strm.total_out >= [decompressed length]) {
[decompressed increaseLengthBy: half_length];
}
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] - strm.total_out;
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
if
(status == Z_STREAM_END) {
done = YES;
}
else
if
(status != Z_OK) {
break
;
}
}
if
(inflateEnd (&strm) != Z_OK)
return
nil;
// Set real length.
if
(done) {
[decompressed setLength: strm.total_out];
return
[NSData dataWithData: decompressed];
}
else
{
return
nil;
}
}
|