接口开发#2:使用zlib库对HTTP Gzip数据进行解压

三、使用zlib库对收到数据进行解压

使用zlib库:http://www.zlib.net/
此软件编译使用的是zlib 1.2.11版本,步骤如下:
1.源码解压后打开VS的命令行,在命令行中执行源码根目录下的\contrib\masmx86\bld_ml32.bat,x64的在\contrib\masmx64\bld_ml64.bat,执行后会在bat文件所在目录下生成两个obj文件和两个lst文件;

Developer Command Prompt for VS2015.png

接口开发#2:使用zlib库对HTTP Gzip数据进行解压_第1张图片
\contrib\masmx86.png

2.将生成的obj文件拷到\contrib\vstudio下对应VS版本目录中,VS2015内部版本号是14,拷到\contrib\vstudio\v14即可然后打开sln解决方案文件按需求编译即可,不同项目的不同编译版本在\contrib\vstudio\v14\x86或\contrib\vstudio\v14\x64下可以看到,我这里只用到了zlib静态连接库的Release版本zlibstat.lib;
接口开发#2:使用zlib库对HTTP Gzip数据进行解压_第2张图片
\contrib\vstudio\v14\x86.png

3.在项目中导入库文件,包含源码根目录下的zlib.h和zconf.h两个头文件:

#include "zlib-1.2.11\zlib.h"
#include "zlib-1.2.11\zconf.h"

切记在项目->属性->配置属性->C/C++->预处理器->预处理器定义中添加ZLIB_WINAPI,否则会编译失败,如果提示模块对于SAFESEH映像是不安全的,在项目->属性->配置属性->链接器->命令行->其它选项中添加/SAFESEH:NO即可。

解压函数:[ref]

// zlib解压Gzip
int httpgzdecompress(Byte *zdata, uLong nzdata,
    Byte *data, uLong *ndata)
{
    int err = 0;
    z_stream d_stream = { 0 }; /* decompression stream */
    static char dummy_head[2] =
    {
        0x8 + 0x7 * 0x10,
        (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
    };
    d_stream.zalloc = (alloc_func)0;
    d_stream.zfree = (free_func)0;
    d_stream.opaque = (voidpf)0;
    d_stream.next_in = zdata;
    d_stream.avail_in = 0;
    d_stream.next_out = data;
    //if (inflateInit2(&d_stream, -MAX_WBITS) != Z_OK) return -1;  
    if (inflateInit2(&d_stream, 47) != Z_OK) return -1;
    while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
        if ((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
        if (err != Z_OK)
        {
            if (err == Z_DATA_ERROR)
            {
                d_stream.next_in = (Bytef*)dummy_head;
                d_stream.avail_in = sizeof(dummy_head);
                if ((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK)
                {
                    return -1;
                }
            }
            else return -1;
        }
    }
    if (inflateEnd(&d_stream) != Z_OK) return -1;
    *ndata = d_stream.total_out;

    return 0;
}

解压结果明显是经过Base64编码过的,虽然不清楚Zlib自己有没有解码的实现,但是也懒得找了(其实是中文资料少英文不想找),反正Base64的解码也很简单。


需要提高的地方:
第三方库的编译使用的一些注意事项得总结一下,开发的过程中时常要用到别人的轮子,规避掉容易犯的粗心错误省心省力又可以提高效率。

你可能感兴趣的:(接口开发#2:使用zlib库对HTTP Gzip数据进行解压)