概述
关于gzip格式解码
使用zlib库解压GZIP格式数据,相关函数inflateInit2(),inflate(),inflateEnd().
zlib库安装这个比较简单不做过多描述
代码示例
直接加入#include <zlib.h>
static int vidpeek_uncompressGzip(unsigned char* pSrc, unsigned int srcSize,char*pOutDest, unsigned int* pOutBufSize)
{
int ret = OK;
char* pBuf = pSrc+ (srcSize - 1);
unsigned int len =1000000;
int uncompressResult;
z_stream d_stream;
int i = 0;
printf("#############pSrc 0x%x 0x%x 0x%x 0x%x %d", pSrc[0], pSrc[1],*pSrc, *(pSrc+1),srcSize);
if((*pSrc !=0x1f)||(*(pSrc+1) != 0x8b))
{
printf("nuncompressGzip non Gzipn");
return ERR;
}
//初始化解压系统
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)
{
printf("ninflateInit2 error:%dn",uncompressResult);
return uncompressResult;
}
d_stream.next_in=pSrc;
d_stream.avail_in=srcSize;
d_stream.next_out=(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;
}
printf("outlen= %d, total_in= %d, total_out= %d, avail_out= %d@@@@@@@@@@@n",len, d_stream.total_in, d_stream.total_out, d_stream.avail_out);
inflateEnd(&d_stream);
#if 0
for (i = 0; i < 1000000; i++ )
{
printf("%c",*(pOutDest+i));
}
#endif
*pOutBufSize = strlen(pOutDest);
return ret;
}
下面代码是处理gzip分片的数据
static int vidpeek_uncompressGzip(unsigned char* pSrc, unsigned int srcSize,char*pOutDest, unsigned int* pOutBufSize,void **ctx)
{
int ret = OK;
char* pBuf = pSrc+ (srcSize - 1);
unsigned int len =1000000;
int uncompressResult;
z_stream* d_stream=NULL;
int i = 0;
if(!(*ctx))
{
d_stream=(z_stream*)malloc(sizeof(z_stream));
//初始化解压系统
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)
{
printf("ninflateInit2 error:%dn",uncompressResult);
return uncompressResult;
}
*ctx = d_stream;
}
else
{
d_stream = *ctx;
}
d_stream->next_in=pSrc;
d_stream->avail_in=srcSize;
d_stream->next_out=(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;
}
*pOutBufSize = strlen(pOutDest);
return ret;
}
关于br解压缩
https://github.com/google/brotli 上下载,下面有编译方法
使用brotli库解压br,相关函数BrotliDecoderDecompress();(brotli-1.0.9cincludebrotlidecode.h)
如果需要解压所的数据比较完整 直接调用上面函数即可。
但是br数据解压 后面数据的解压依赖前面数据 故将BrotliDecoderDecompress()改造加入到decode.c .h 中 ,重新生成动态库调用即可。
BrotliDecoderResult BrotliDecoderDecompress_new(
size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,
uint8_t* decoded_buffer, void **ctx, size_t* total_out) {
BrotliDecoderState *s;
if(!(*ctx))
{
s = BrotliDecoderCreateInstance(NULL, NULL, NULL);
}
BrotliDecoderResult result;
//size_t total_out = 0;
size_t available_in = encoded_size;
const uint8_t* next_in = encoded_buffer;
//size_t available_out = *decoded_size;
uint8_t* next_out = decoded_buffer;
if(!(*ctx))
{
if (!BrotliDecoderStateInit(s, 0, 0, 0)) {
return BROTLI_DECODER_RESULT_ERROR;
}
*ctx = s;
}
else
{
s = *ctx;
}
result = BrotliDecoderDecompressStream(
s, &available_in, &next_in, decoded_size, &next_out, total_out);
//*decoded_size = total_out;
// 判断是否解完
if(BrotliDecoderIsFinished(s))
{
BrotliDecoderStateCleanup(s);
// 销毁
BrotliDecoderDestroyInstance(s);
*ctx = NULL;
}
if (result != BROTLI_DECODER_RESULT_SUCCESS && result != BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT
) {
result = BROTLI_DECODER_RESULT_ERROR;
BrotliDecoderStateCleanup(s);
// 销毁
BrotliDecoderDestroyInstance(s);
*ctx = NULL;
}
return result;
}
测试结果:
#include <stdio.h>
/* For "exit". */
#include <stdlib.h>
/* For "strerror". */
#include <string.h>
#include <decode.h>
//数据太大 不贴了
static unsigned char in[]={};
static unsigned char in1[]={};
static unsigned char in2[]={};
static unsigned char out[100000]={0};
static unsigned char out1[100000]={0};
static unsigned char out2[100000]={0};
static unsigned char out3[100000]={0};
int main()
{
size_t psize=100000;
size_t total_out = 0;
void *ctx=NULL;
printf("-------len : %dn", sizeof(in));
int ret=BrotliDecoderDecompress_new(500,in,&psize,&out, &ctx,&total_out);
printf("strlen =%d,ret=%d total_out: %dn", psize,ret, total_out);
printf("strlen=%dn",strlen(out));
//printf("strlen=%sn",out);
ret=BrotliDecoderDecompress_new(sizeof(in)-500,in+500,&psize,&out, &ctx,&total_out);
printf("strlen =%d,ret=%d total_out: %dn", psize,ret, total_out);
printf("strlen=%dn",strlen(out));
//printf("strlen=%sn",out);
psize=100000;
int ret1=BrotliDecoderDecompress_new(sizeof(in1),in1,&psize,&out1, &ctx,&total_out);
printf("strlen =%d,ret=%d total_out: %dn",psize,ret, total_out);
printf("strlen=%dn",strlen(out1));
printf("strlen=%sn",out1);
psize=100000;
int ret2=BrotliDecoderDecompress_new(sizeof(in2),in2,&psize,&out2, &ctx,&total_out);
printf("strlen =%d,ret=%d total_out: %dn",psize,ret, total_out);
printf("strlen=%dn",strlen(out2));
printf("strlen=%sn",out2);
psize=100000;
int ret3=BrotliDecoderDecompress_new(sizeof(in3),in3,&psize,&out3, &ctx,&total_out);
printf("strlen =%d,ret=%d total_out: %dn",psize,ret, total_out);
printf("strlen=%dn",strlen(out3));
printf("strlen=%sn",out3);
return 0;
}
gcc unbr.c -I. -L. -lbrotlidec
最后
以上就是虚幻小兔子为你收集整理的关于HTTP2.0 gzip和br解压缩的全部内容,希望文章能够帮你解决关于HTTP2.0 gzip和br解压缩所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复