L006Linux和androidNDK之使用zlib 在解压缩数据

L006Linux和androidNDK之使用zlib 在解压缩数据

看一个一个http头

GET /fly-fish/p/4932314.html HTTP/1.1
Host: 42.121.252.58
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: text/plain, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive

这个头,是浏览器发给服务器,告诉web服务器我这儿支持gzip deflate,你如果支持gzip deflate 可发gzip deflate 压缩格式的数据过来,省传输时间,省带宽。

还是用代码说话吧:

//在内存中压缩数据,解压缩数据。
int gZipcompress( char *src, int srcLen,char *denst, int *denstLen) 
{
    int ret, flush;
    unsigned have;
    z_stream strm;
    unsigned char out[CHUNK];

    /* allocate deflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
    
    if (ret != Z_OK)
        return ret;

    /* compress until end of file */
    int times=0;
    int pos=0;
    do {
        strm.avail_in = ((times+1)*CHUNK>srcLen)?(srcLen%CHUNK):CHUNK;
        
        
        flush = ((times+1)*CHUNK>=srcLen) ? Z_FINISH : Z_NO_FLUSH;

        T("%2d,%4d,%4d\n",times,strm.avail_in,flush);
        strm.next_in = src+times*CHUNK;

        /* run deflate() on input until output buffer not full, finish
           compression if all of source has been read in */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = deflate(&strm, flush);    /* no bad return value */
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
            have = CHUNK - strm.avail_out;
            memcpy(denst+pos,out,have);
            pos += have;
            
        } while (strm.avail_out == 0);
        assert(strm.avail_in == 0);     /* all input will be used */

        times++;
        /* done when last data in file processed */
    } while (flush != Z_FINISH);
    assert(ret == Z_STREAM_END);        /* stream will be complete */

    /* clean up and return */
    (void)deflateEnd(&strm);

    *denstLen = pos;
    return Z_OK;
}


int gZipuncompress( char *src, int srcLen,char *denst, int *denstLen) 
{
    int ret;
    unsigned have;
    z_stream strm;
    //unsigned char in[CHUNK];
    unsigned char out[CHUNK];

    /* allocate inflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = 0;
    strm.next_in = Z_NULL;
    ret = inflateInit(&strm);
    
    if (ret != Z_OK)
        return ret;

    int times=0;
    int pos=0;

    /* decompress until deflate stream ends or end of file */
    do {
        strm.avail_in = ((times+1)*CHUNK>srcLen)?(srcLen%CHUNK):CHUNK;
        
        T("%2d,%4d\n",times,strm.avail_in);
        if (strm.avail_in == 0)
            break;
        strm.next_in = src+times*CHUNK;;

        /* run inflate() on input until output buffer not full */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = inflate(&strm, Z_NO_FLUSH);
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
            switch (ret) {
            case Z_NEED_DICT:
                ret = Z_DATA_ERROR;     /* and fall through */
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:
                (void)inflateEnd(&strm);
                return ret;
            }
            have = CHUNK - strm.avail_out;
            memcpy(denst+pos,out,have);
            pos += have;
            
        } while (strm.avail_out == 0);
        times++;

        /* done when inflate() says it's done */
    } while (ret != Z_STREAM_END);

    /* clean up and return */
    (void)inflateEnd(&strm);
    *denstLen = pos;
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}

参考链接

  1. gzip原理与实现
  2. gzip头部格式
  3. GZIP数据格式
  4. Basic Functions

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

通过shell定制dbms_advisor.quick_tune(r4笔记第15天)

在平时的调优工作中,在11g中的新特性sql monitor可以极大的简化性能监控的工作,对于执行时间超过5秒的sql语句都会记入v$sql_monitor中...

33340
来自专栏杨建荣的学习笔记

海量数据迁移之外部表并行抽取(99天)

在10g开始的新特性中,外部表是一个不容忽视的好工具。对于大型项目中海量数据使用sqlloader是一种全新的方式,不过很明显,sqlloader的可扩展性更强...

38350
来自专栏乐沙弥的世界

又一例SPFILE设置错误导致数据库无法启动

--========================================

9030
来自专栏数据和云

诊断案例:从实例挂起到归档失败和内存管理的蝴蝶效应

杨廷琨(yangtingkun) 云和恩墨 CTO 高级咨询顾问,Oracle ACE 总监,ITPUB Oracle 数据库管理版版主 编辑手记:在很多数据...

33390
来自专栏乐沙弥的世界

Oracle 控制文件(CONTROLFILE)

为二进制文件,初始化大小由CREATE DATABASE指定,可以使用RMAN备份

12920
来自专栏杨建荣的学习笔记

关于exp/imp的总结学习(r4笔记第26天)

关于exp/imp,是很常用的数据导出导入工具,在10g开始推出的数据泵datapump相当于是exp/imp的补充和升级版本。在后续章节再做一个总结。 exp...

31570
来自专栏乐沙弥的世界

Heap size 80869K exceeds notification threshold (51200K)

      前阵子的alert日志获得了所需堆尺寸的大小超出指定阙值的提示,即Heap size 80869K exceeds notification thr...

10830
来自专栏乐沙弥的世界

数据导入时遭遇 ORA-01187 ORA-01110

最近的数据导入(IMP)时碰到了ORA-01187 ORA-01110 错误,由于这个数据库是使用热备恢复过来的,且恢复也是成功的,因为数据库能够成功open,...

9630
来自专栏张善友的专栏

非域环境下使用证书设置数据库镜像

数据库镜像是将数据库事务处理从一个SQL Server数据库移动到不同SQL Server环境中的另一个SQL Server数据库中。镜像不能直接访问;它只用在...

21950
来自专栏杨建荣的学习笔记

通过shell脚本快速定位active session问题(r4笔记第65天)

如果你得到反馈,数据库突然间性能下降了好多,希望你能够尽快的定位出问题来,有一些思路和方法可以参考。分别从数据库层面,系统层面来定位,但是个人感觉而言还是不够快...

36050

扫码关注云+社区

领取腾讯云代金券