请帮我弄清楚解压缩从Nitty 4.0服务器收到的数据的方法。 由于服务器端的deflate功能使用JDK1.7 gzip,包括Huffman算法和LZ77。
所以当服务器第一次发送压缩的数据时,我使用Gzip库:
- (NSData *) gzipInflate
{ z_stream strm;
// Initialize input
strm.next_in = (Bytef *)[self bytes];
NSUInteger left = [self length]; // input left to decompress
if (left == 0)
return nil; // incomplete gzip stream
// Create starting space for output (guess double the input size, will grow
// if needed -- in an extreme case, could end up needing more than 1000
// times the input size)
NSUInteger space = left << 1;
if (space < left)
space = NSUIntegerMax;
NSMutableData *decompressed = [NSMutableData dataWithLength: space];
space = [decompressed length];
// Initialize output
strm.next_out = (Bytef *)[decompressed mutableBytes];
NSUInteger have = 0; // output generated so far
// Set up for gzip decoding
strm.avail_in = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int status = inflateInit2(&strm, (15+16));
if (status != Z_OK)
return nil; // out of memory
// Decompress all of self
do {
// Allow for concatenated gzip streams (per RFC 1952)
if (status == Z_STREAM_END)
(void)inflateReset(&strm);
// Provide input for inflate
if (strm.avail_in == 0) {
strm.avail_in = left > UINT_MAX ? UINT_MAX : (unsigned)left;
left -= strm.avail_in;
}
// Decompress the available input
do {
// Allocate more output space if none left
if (space == have) {
// Double space, handle overflow
space <<= 1;
if (space < have) {
space = NSUIntegerMax;
if (space == have) {
// space was already maxed out!
(void)inflateEnd(&strm);
return nil; // output exceeds integer size
}
}
// Increase space
[decompressed setLength: space];
space = [decompressed length];
// Update output pointer (might have moved)
strm.next_out = (Bytef *)[decompressed mutableBytes] + have;
}
// Provide output space for inflate
strm.avail_out = space - have > UINT_MAX ? UINT_MAX :
(unsigned)(space - have);
have += strm.avail_out;
// Inflate and update the decompressed size
status = inflate (&strm, Z_SYNC_FLUSH);
have -= strm.avail_out;
// Bail out if any errors
if (status != Z_OK && status != Z_BUF_ERROR &&
status != Z_STREAM_END) {
(void)inflateEnd(&strm);
return nil; // invalid gzip stream
}
// Repeat until all output is generated from provided input (note
// that even if strm.avail_in is zero, there may still be pending
// output -- we're not done until the output buffer isn't filled)
} while (strm.avail_out == 0);
// Continue until all input consumed
} while (left || strm.avail_in);
// Free the memory allocated by inflateInit2()
(void)inflateEnd(&strm);
// Verify that the input is a valid gzip stream
// if (status != Z_STREAM_END)
// return nil; // incomplete gzip stream
// Set the actual length and return the decompressed data
[decompressed setLength: have];
return decompressed;
}
因此,如果您熟悉DEFLATE的霍夫曼算法(我希望) 下一次nitty放气相同的字符串发送它我收到它但比第一次短,我不能给它充气,
有没有办法将inflate应用为Huffman Tree算法,将LZ77应用为Java Nitty Server?
答案 0 :(得分:0)
现在您已在下面的评论中提供了数据,很明显发生了什么。第二个字符串是第一个字符串的延续。您只需将后续数据保存到同一个膨胀实例中即可。
第一个字符串启动gzip流并以空块结束,但不终止该流。第二个字符串继续使用更多的膨胀块,这些块指的是第一个字符串。
第二个字符串也不是结尾。之后应该有更多,因为它也不会终止gzip流。最终你应该得到一个完成gzip流的数据包,在这种情况下inflate()
将返回Z_STREAM_END
。