使用zlib库
下载zlib源码,https://github.com/madler/zlib
espidf工程components文件夹下新建zlib文件夹,解压上面下载的源码到zlib文件夹,新建CMakeList.txt文件。
完成后目录如下图:
编辑CMakeList.txt文件如下:
idf_component_register(SRCS "zlib/adler32.c" "zlib/crc32.c" "zlib/infback.c" "zlib/inffast.c" "zlib/inflate.c" "zlib/inftrees.c" "zlib/zutil.c" INCLUDE_DIRS zlib )从http响应中获取gzip数据长度,http响应如下图
可以通过headers中的键以及'\r\n'等标志截取来获取content-length数据长度,具体代码就不贴了。
然后获取gzip数据长度后,就可以使用下面的解压缩函数来解压数据流。
gzip解压缩函数如下:
/** * pSrc: http返回的gzip数据 * srcSize: http返回gzip数据长度 * pOutDest: 解压后数据缓存区地址,malloc申请内存空间 * pOutBufSize: 缓存区大小 */ int vidpeek_uncompressGzip(unsigned char *pSrc, unsigned int srcSize, char **pOutDest, unsigned int *pOutBufSize) { #define OK 0 #define ERR -1 int ret = OK; char *pBuf = (char *)pSrc + (srcSize - 1); unsigned int len = *pBuf; int uncompressResult; z_stream d_stream; int i = 0; // check gz file,rfc1952 P6 if ((*pSrc != 0x1f) || (*(pSrc + 1) != 0x8b)) { return ERR; } for (i = 0; i < 3; i++) { pBuf--; len <<= 8; len += *pBuf; } // fortest if ((len == 0) || (len > 1000000)) { return ERR; } // gzipdecompression start!!! d_stream.zalloc = Z_NULL; d_stream.zfree = Z_NULL; d_stream.opaque = Z_NULL; d_stream.next_in = Z_NULL; d_stream.avail_in = 0; uncompressResult = inflateInit2(&d_stream, 47); if (uncompressResult != Z_OK) { return uncompressResult; } d_stream.next_in = pSrc; d_stream.avail_in = srcSize; d_stream.next_out = (unsigned char *)*pOutDest; d_stream.avail_out = len; uncompressResult = inflate(&d_stream, Z_NO_FLUSH); switch (uncompressResult) { case Z_NEED_DICT: uncompressResult = Z_DATA_ERROR; case Z_DATA_ERROR: case Z_MEM_ERROR: (void)inflateEnd(&d_stream); return uncompressResult; } inflateEnd(&d_stream); *pOutBufSize = len - 2; return ret; }
函数调用如下:
size_t out_len = 0; char *gzip_out_buff = (char *)malloc(MAX_HTTP_OUTPUT_BUFFER * sizeof(char)); memset(gzip_out_buff, 0x0, MAX_HTTP_OUTPUT_BUFFER); //in_buff即为上面根据http响应获取到的gzip数据流 //len为根据content-length获取的gzip数据长度 vidpeek_uncompressGzip(in_buff, len, &gzip_out_buff, &out_len);
解压缩后就可以使用cJson来解析了。
注:其实get请求时可以使用&gzip=n来避免返回gzip数据,不过次数多了好像就不管用了
参考文章:
https://yuanze.wang/posts/esp32-unzip-gzip-http-response/
https://blog.csdn.net/weixin_28607671/article/details/116988589
---
转载请注明本文标题和链接:《和风天气接口返回的gzip格式数据解析--esp32--espidf》
发表评论