栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

这是gzip inflate方法中的错误吗?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

这是gzip inflate方法中的错误吗?

是的,这是一个错误。

实际上是正确的,如果

inflate()
不返回
Z_STREAM_END
,则说明您还没有完成通货膨胀。
inflateEnd()
返回
Z_OK
实际上并没有多大意义,只是返回了一个有效的状态并能够释放内存。

因此

inflate()
必须最终返回,
Z_STREAM_END
然后才能声明成功。但是,
Z_BUF_ERROR
这不是放弃的理由。在这种情况下,您只需
inflate()
使用更多的输入或更多的输出空间再次调用即可。然后您将得到
Z_STREAM_END

从zlib.h中的文档中:

更新:

由于那里有许多错误代码,下面是实现所需方法的正确代码。该代码处理不完整的gzip流,串联的gzip流和非常大的gzip流。对于非常大的gzip流,当编译为64位可执行文件时,中的

unsigned
长度
z_stream
不够大。
NSUInteger
是64位,而是
unsigned
32位。在这种情况下,您必须循环输入才能将其提供给
inflate()

本示例仅返回

nil
任何错误。
return nil;
如果需要更高级的错误处理,请在每个注释后的注释中注明错误的性质。

- (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;}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/661240.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号