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

你可能感兴趣的:(L006Linux和androidNDK之使用zlib 在解压缩数据)