`
chinamming
  • 浏览: 151353 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

zlib库剖析(4):使用示例example.c

 
阅读更多
下面分析test/example.c,它示范了zlib库的各个函数的使用。

下面代码定义要压缩的字符串、压缩时使用的字典、压缩/解压缩的内存分配策略等。

  1. /*example.c--usageexampleofthezlibcompressionlibrary
  2. *Copyright(C)1995-2006,2011Jean-loupGailly.
  3. *Forconditionsofdistributionanduse,seecopyrightnoticeinzlib.h
  4. */
  5. /*@(#)$Id$*/
  6. #include"zlib.h"
  7. #include<stdio.h>
  8. #ifdefSTDC
  9. #include<string.h>
  10. #include<stdlib.h>
  11. #endif
  12. #ifdefined(VMS)||defined(RISCOS)
  13. #defineTESTFILE"foo-gz"
  14. #else
  15. #defineTESTFILE"foo.gz"
  16. #endif
  17. #defineCHECK_ERR(err,msg){\
  18. if(err!=Z_OK){\
  19. fprintf(stderr,"%serror:%d\n",msg,err);\
  20. exit(1);\
  21. }\
  22. }
  23. constcharhello[]="hello,hello!";/*字符长度为14(末尾还有一个null字符)*/
  24. /*"helloworld"wouldbemorestandard,buttherepeated"hello"
  25. *stressesthecompressioncodebetter,sorry...
  26. */
  27. constchardictionary[]="hello";
  28. uLongdictId;/*字典的Adler32校验值*/
  29. voidtest_deflateOF((Byte*compr,uLongcomprLen));
  30. voidtest_inflateOF((Byte*compr,uLongcomprLen,
  31. Byte*uncompr,uLonguncomprLen));
  32. voidtest_large_deflateOF((Byte*compr,uLongcomprLen,
  33. Byte*uncompr,uLonguncomprLen));
  34. voidtest_large_inflateOF((Byte*compr,uLongcomprLen,
  35. Byte*uncompr,uLonguncomprLen));
  36. voidtest_flushOF((Byte*compr,uLong*comprLen));
  37. voidtest_syncOF((Byte*compr,uLongcomprLen,
  38. Byte*uncompr,uLonguncomprLen));
  39. voidtest_dict_deflateOF((Byte*compr,uLongcomprLen));
  40. voidtest_dict_inflateOF((Byte*compr,uLongcomprLen,
  41. Byte*uncompr,uLonguncomprLen));
  42. intmainOF((intargc,char*argv[]));
  43. /*Z_SOLO表示把zlib库编译成单独的不依赖第三方的库*/
  44. #ifdefZ_SOLO
  45. /*使用自定义的内存分配策略*/
  46. void*myallocOF((void*,unsigned,unsigned));
  47. voidmyfreeOF((void*,void*));
  48. void*myalloc(q,n,m)
  49. void*q;
  50. unsignedn,m;
  51. {
  52. q=Z_NULL;
  53. returncalloc(n,m);
  54. }
  55. voidmyfree(void*q,void*p)
  56. {
  57. q=Z_NULL;
  58. free(p);
  59. }
  60. staticalloc_funczalloc=myalloc;
  61. staticfree_funczfree=myfree;
  62. #else/*!Z_SOLO*/
  63. /*使用zlib默认的内存分配策略*/
  64. staticalloc_funczalloc=(alloc_func)0;
  65. staticfree_funczfree=(free_func)0;
下面测试compress和uncompress的用法:
  1. voidtest_compressOF((Byte*compr,uLongcomprLen,
  2. Byte*uncompr,uLonguncomprLen));
  3. voidtest_gzioOF((constchar*fname,
  4. Byte*uncompr,uLonguncomprLen));
  5. /*===========================================================================
  6. *测试compress()和uncompress()
  7. */
  8. voidtest_compress(compr,comprLen,uncompr,uncomprLen)
  9. Byte*compr,*uncompr;
  10. uLongcomprLen,uncomprLen;
  11. {
  12. interr;
  13. uLonglen=(uLong)strlen(hello)+1;/*获取字符串长度*/
  14. /*压缩字符串*/
  15. err=compress(compr,&comprLen,(constBytef*)hello,len);
  16. CHECK_ERR(err,"compress");
  17. strcpy((char*)uncompr,"garbage");
  18. /*解压字符串*/
  19. err=uncompress(uncompr,&uncomprLen,compr,comprLen);
  20. CHECK_ERR(err,"uncompress");
  21. /*比较解压后的结果*/
  22. if(strcmp((char*)uncompr,hello)){
  23. fprintf(stderr,"baduncompress\n");
  24. exit(1);
  25. }else{
  26. printf("uncompress():%s\n",(char*)uncompr);
  27. }
  28. }
下面测试gzip文件的读写操作:
  1. /*===========================================================================
  2. *测试.gz文件的读写操作
  3. */
  4. voidtest_gzio(fname,uncompr,uncomprLen)
  5. constchar*fname;/*gz文件名*/
  6. Byte*uncompr;
  7. uLonguncomprLen;
  8. {
  9. #ifdefNO_GZCOMPRESS
  10. fprintf(stderr,"NO_GZCOMPRESS--gz*functionscannotcompress\n");
  11. #else
  12. interr;
  13. intlen=(int)strlen(hello)+1;
  14. gzFilefile;
  15. z_off_tpos;
  16. file=gzopen(fname,"wb");/*打开要写入的gz文件*/
  17. if(file==NULL){
  18. fprintf(stderr,"gzopenerror\n");
  19. exit(1);
  20. }
  21. gzputc(file,'h');/*写入一个字符'h'*/
  22. if(gzputs(file,"ello")!=4){/*写入字符串"ello"*/
  23. fprintf(stderr,"gzputserr:%s\n",gzerror(file,&err));
  24. exit(1);
  25. }
  26. if(gzprintf(file,",%s!","hello")!=8){/*按格式写入字符串",hello!"*/
  27. fprintf(stderr,"gzprintferr:%s\n",gzerror(file,&err));
  28. exit(1);
  29. }
  30. gzseek(file,1L,SEEK_CUR);/*读写头向前移动1字节(即添加一个0字节)*/
  31. gzclose(file);/*关闭gz文件*/
  32. file=gzopen(fname,"rb");/*打开要读取的gz文件*/
  33. if(file==NULL){
  34. fprintf(stderr,"gzopenerror\n");
  35. exit(1);
  36. }
  37. strcpy((char*)uncompr,"garbage");
  38. /*从压缩文件中读取给定大小的解压字节数*/
  39. if(gzread(file,uncompr,(unsigned)uncomprLen)!=len){
  40. fprintf(stderr,"gzreaderr:%s\n",gzerror(file,&err));
  41. exit(1);
  42. }
  43. if(strcmp((char*)uncompr,hello)){/*比较解压后的结果*/
  44. fprintf(stderr,"badgzread:%s\n",(char*)uncompr);
  45. exit(1);
  46. }else{
  47. printf("gzread():%s\n",(char*)uncompr);
  48. }
  49. pos=gzseek(file,-8L,SEEK_CUR);/*读写头向后移动8字节,应该停留在第6个字符处*/
  50. if(pos!=6||gztell(file)!=pos){/*判断是否停留在第6个字符处*/
  51. fprintf(stderr,"gzseekerror,pos=%ld,gztell=%ld\n",
  52. (long)pos,(long)gztell(file));
  53. exit(1);
  54. }
  55. if(gzgetc(file)!=''){/*从当前位置读取1个字符,应该为字符''*/
  56. fprintf(stderr,"gzgetcerror\n");
  57. exit(1);
  58. }
  59. if(gzungetc('',file)!=''){/*推回这个字符到流中*/
  60. fprintf(stderr,"gzungetcerror\n");
  61. exit(1);
  62. }
  63. /*从压缩文件当前位置读取指定长度的解压字节数,直到len-1个字符被读取*/
  64. gzgets(file,(char*)uncompr,(int)uncomprLen);
  65. if(strlen((char*)uncompr)!=7){/*"hello!"*/
  66. fprintf(stderr,"gzgetserraftergzseek:%s\n",gzerror(file,&err));
  67. exit(1);
  68. }
  69. if(strcmp((char*)uncompr,hello+6)){
  70. fprintf(stderr,"badgzgetsaftergzseek\n");
  71. exit(1);
  72. }else{
  73. printf("gzgets()aftergzseek:%s\n",(char*)uncompr);
  74. }
  75. gzclose(file);/*关闭gz文件*/
  76. #endif
  77. }
  78. #endif/*Z_SOLO*/
下面用小缓冲区测试压缩、解压操作(deflate/deflate):
  1. /*===========================================================================
  2. *测试deflate():使用小缓冲区
  3. */
  4. voidtest_deflate(compr,comprLen)
  5. Byte*compr;
  6. uLongcomprLen;
  7. {
  8. z_streamc_stream;/*压缩流*/
  9. interr;
  10. uLonglen=(uLong)strlen(hello)+1;
  11. /*这三个字段要在defalteInit之前初始化*/
  12. c_stream.zalloc=zalloc;
  13. c_stream.zfree=zfree;
  14. c_stream.opaque=(voidpf)0;
  15. /*初始化压缩流的状态,使用默认压缩级别*/
  16. err=deflateInit(&c_stream,Z_DEFAULT_COMPRESSION);
  17. CHECK_ERR(err,"deflateInit");
  18. /*设置压缩操作的输入数据和输出缓冲区*/
  19. c_stream.next_in=(Bytef*)hello;/*输入缓冲区指向输入字符串*/
  20. c_stream.next_out=compr;
  21. /*第一个循环:将flush设为Z_NO_FLUSH(表示还有输入数据未读完),将所有输入都读进去并进行压缩
  22. 根据avail_in和avail_out,不停地调用deflate将输入缓冲区的数据压缩
  23. 并写到输出缓冲区,直到输入字符串读完或输出缓冲区用完
  24. */
  25. while(c_stream.total_in!=len&&c_stream.total_out<comprLen){
  26. c_stream.avail_in=c_stream.avail_out=1;/*强制小缓冲区*/
  27. err=deflate(&c_stream,Z_NO_FLUSH);
  28. CHECK_ERR(err,"deflate");
  29. }
  30. /*第二个循环:将flush设置为Z_FINISH,不再输入,让deflate()完成全部的压缩输出
  31. 注意因为deflate压缩时可能是异步的(为了加速压缩,读取一次输入后不一定立刻就会产生压缩输出,
  32. 可能读完K字节后才会产生输出),所以上一个循环可能还没产生全部输出,需要这个循环,让flush保持Z_FINISH
  33. (表示输入数据已读完),多次调用deflate(),直到返回Z_STREAM_END,表示处理完全部输入并产生了全部的压缩输出
  34. */
  35. for(;;){/*完成压缩流的刷新,仍然强制小缓冲区*/
  36. c_stream.avail_out=1;
  37. err=deflate(&c_stream,Z_FINISH);
  38. if(err==Z_STREAM_END)break;
  39. CHECK_ERR(err,"deflate");
  40. }
  41. err=deflateEnd(&c_stream);/*释放压缩流的资源*/
  42. CHECK_ERR(err,"deflateEnd");
  43. }
  44. /*===========================================================================
  45. *测试inflate():使用小缓冲区
  46. */
  47. voidtest_inflate(compr,comprLen,uncompr,uncomprLen)
  48. Byte*compr,*uncompr;
  49. uLongcomprLen,uncomprLen;
  50. {
  51. interr;
  52. z_streamd_stream;/*解压流*/
  53. strcpy((char*)uncompr,"garbage");
  54. /*这些个字段要在infalteInit之前初始化*/
  55. d_stream.zalloc=zalloc;
  56. d_stream.zfree=zfree;
  57. d_stream.opaque=(voidpf)0;
  58. d_stream.next_in=compr;/*设置输入缓冲区*/
  59. d_stream.avail_in=0;
  60. d_stream.next_out=uncompr;/*设置输出缓冲区*/
  61. /*初始化解压流的状态*/
  62. err=inflateInit(&d_stream);
  63. CHECK_ERR(err,"inflateInit");
  64. /*只需一个循环:根据avail_in和avail_out,不停地调用inflate将输入缓冲区的数据
  65. 解压,直到返回Z_STREAM_END,表示处理完全部输入并产生了全部的解压输出
  66. 这里与flush参数是否为Z_FINISH无关
  67. */
  68. while(d_stream.total_out<uncomprLen&&d_stream.total_in<comprLen){
  69. d_stream.avail_in=d_stream.avail_out=1;/*强制小缓冲区*/
  70. err=inflate(&d_stream,Z_NO_FLUSH);
  71. if(err==Z_STREAM_END)break;
  72. CHECK_ERR(err,"inflate");
  73. }
  74. err=inflateEnd(&d_stream);/*释放解压流的资源*/
  75. CHECK_ERR(err,"inflateEnd");
  76. if(strcmp((char*)uncompr,hello)){/*比较解压后的数据*/
  77. fprintf(stderr,"badinflate\n");
  78. exit(1);
  79. }else{
  80. printf("inflate():%s\n",(char*)uncompr);
  81. }
  82. }
下面使用大缓冲区测试压缩、解压操作(deflate/deflate):
  1. /*===========================================================================
  2. *测试deflate():使用大缓冲区和动态改变的压缩级别
  3. */
  4. voidtest_large_deflate(compr,comprLen,uncompr,uncomprLen)
  5. Byte*compr,*uncompr;
  6. uLongcomprLen,uncomprLen;
  7. {
  8. z_streamc_stream;/*压缩流*/
  9. interr;
  10. /*这三个字段要在defalteInit之前初始化*/
  11. c_stream.zalloc=zalloc;
  12. c_stream.zfree=zfree;
  13. c_stream.opaque=(voidpf)0;
  14. /*初始化压缩流的状态,使用最快速度压缩*/
  15. err=deflateInit(&c_stream,Z_BEST_SPEED);
  16. CHECK_ERR(err,"deflateInit");
  17. c_stream.next_out=compr;
  18. c_stream.avail_out=(uInt)comprLen;
  19. /*这里,uncompr几乎都为0,因此可以很好地被压缩*/
  20. c_stream.next_in=uncompr;
  21. c_stream.avail_in=(uInt)uncomprLen;
  22. err=deflate(&c_stream,Z_NO_FLUSH);/*压缩输入数据*/
  23. CHECK_ERR(err,"deflate");
  24. if(c_stream.avail_in!=0){
  25. fprintf(stderr,"deflatenotgreedy\n");
  26. exit(1);
  27. }
  28. /*把已压缩的数据转换成未压缩:*/
  29. /*设置流的压缩级别(为未压缩)和压缩策略*/
  30. deflateParams(&c_stream,Z_NO_COMPRESSION,Z_DEFAULT_STRATEGY);
  31. c_stream.next_in=compr;
  32. c_stream.avail_in=(uInt)comprLen/2;
  33. err=deflate(&c_stream,Z_NO_FLUSH);
  34. CHECK_ERR(err,"deflate");
  35. /*转换回压缩模式(最高压缩率):*/
  36. deflateParams(&c_stream,Z_BEST_COMPRESSION,Z_FILTERED);
  37. c_stream.next_in=uncompr;
  38. c_stream.avail_in=(uInt)uncomprLen;
  39. err=deflate(&c_stream,Z_NO_FLUSH);
  40. CHECK_ERR(err,"deflate");
  41. /*流刷新,产生全部压缩输出*/
  42. err=deflate(&c_stream,Z_FINISH);
  43. if(err!=Z_STREAM_END){
  44. fprintf(stderr,"deflateshouldreportZ_STREAM_END\n");
  45. exit(1);
  46. }
  47. err=deflateEnd(&c_stream);/*释放流的资源*/
  48. CHECK_ERR(err,"deflateEnd");
  49. }
  50. /*===========================================================================
  51. *测试inflate():使用大缓冲区
  52. */
  53. voidtest_large_inflate(compr,comprLen,uncompr,uncomprLen)
  54. Byte*compr,*uncompr;
  55. uLongcomprLen,uncomprLen;
  56. {
  57. interr;
  58. z_streamd_stream;/*解压流*/
  59. strcpy((char*)uncompr,"garbage");
  60. /*这些个字段要在infalteInit之前初始化*/
  61. d_stream.zalloc=zalloc;
  62. d_stream.zfree=zfree;
  63. d_stream.opaque=(voidpf)0;
  64. d_stream.next_in=compr;
  65. d_stream.avail_in=(uInt)comprLen;
  66. /*初始化解压流*/
  67. err=inflateInit(&d_stream);
  68. CHECK_ERR(err,"inflateInit");
  69. /*解压*/
  70. for(;;){
  71. d_stream.next_out=uncompr;/*抛弃输出*/
  72. d_stream.avail_out=(uInt)uncomprLen;
  73. err=inflate(&d_stream,Z_NO_FLUSH);/*解压输入数据*/
  74. if(err==Z_STREAM_END)break;
  75. CHECK_ERR(err,"largeinflate");
  76. }
  77. err=inflateEnd(&d_stream);
  78. CHECK_ERR(err,"inflateEnd");
  79. if(d_stream.total_out!=2*uncomprLen+comprLen/2){
  80. fprintf(stderr,"badlargeinflate:%ld\n",d_stream.total_out);
  81. exit(1);
  82. }else{
  83. printf("large_inflate():OK\n");
  84. }
  85. }
下面使用完全刷新模式测试压缩操作deflate:
  1. /*===========================================================================
  2. *测试deflate():使用完全刷新
  3. */
  4. voidtest_flush(compr,comprLen)
  5. Byte*compr;
  6. uLong*comprLen;
  7. {
  8. z_streamc_stream;/*压缩流*/
  9. interr;
  10. uIntlen=(uInt)strlen(hello)+1;
  11. c_stream.zalloc=zalloc;
  12. c_stream.zfree=zfree;
  13. c_stream.opaque=(voidpf)0;
  14. err=deflateInit(&c_stream,Z_DEFAULT_COMPRESSION);
  15. CHECK_ERR(err,"deflateInit");
  16. c_stream.next_in=(Bytef*)hello;
  17. c_stream.next_out=compr;
  18. c_stream.avail_in=3;
  19. c_stream.avail_out=(uInt)*comprLen;
  20. /*使用完全刷新来压缩字符串*/
  21. err=deflate(&c_stream,Z_FULL_FLUSH);
  22. CHECK_ERR(err,"deflate");
  23. compr[3]++;/*在第一个压缩块中强制产生一个错误*/
  24. c_stream.avail_in=len-3;
  25. err=deflate(&c_stream,Z_FINISH);
  26. if(err!=Z_STREAM_END){
  27. CHECK_ERR(err,"deflate");
  28. }
  29. err=deflateEnd(&c_stream);
  30. CHECK_ERR(err,"deflateEnd");
  31. *comprLen=c_stream.total_out;
  32. }
下面测试同步方式的解压操作inflateSync:
  1. /*===========================================================================
  2. *TestinflateSync()
  3. */
  4. voidtest_sync(compr,comprLen,uncompr,uncomprLen)
  5. Byte*compr,*uncompr;
  6. uLongcomprLen,uncomprLen;
  7. {
  8. interr;
  9. z_streamd_stream;/*解压流*/
  10. strcpy((char*)uncompr,"garbage");
  11. d_stream.zalloc=zalloc;
  12. d_stream.zfree=zfree;
  13. d_stream.opaque=(voidpf)0;
  14. d_stream.next_in=compr;/*设置输入缓冲区*/
  15. d_stream.avail_in=2;/*只读取zlib头部信息*/
  16. err=inflateInit(&d_stream);
  17. CHECK_ERR(err,"inflateInit");
  18. d_stream.next_out=uncompr;/*设置输出缓冲区*/
  19. d_stream.avail_out=(uInt)uncomprLen;
  20. inflate(&d_stream,Z_NO_FLUSH);
  21. CHECK_ERR(err,"inflate");
  22. d_stream.avail_in=(uInt)comprLen-2;/*读取所有压缩数据*/
  23. err=inflateSync(&d_stream);/*但忽略损坏的部分*/
  24. CHECK_ERR(err,"inflateSync");
  25. err=inflate(&d_stream,Z_FINISH);/*完成解压*/
  26. if(err!=Z_DATA_ERROR){
  27. fprintf(stderr,"inflateshouldreportDATA_ERROR\n");
  28. /*因为不正确的adler32*/
  29. exit(1);
  30. }
  31. err=inflateEnd(&d_stream);
  32. CHECK_ERR(err,"inflateEnd");
  33. printf("afterinflateSync():hel%s\n",(char*)uncompr);
  34. }
下面用预设的字典测试压缩、解压操作(deflate/inflate):
  1. /*===========================================================================
  2. *测试:deflate():使用预设的字典
  3. */
  4. voidtest_dict_deflate(compr,comprLen)
  5. Byte*compr;
  6. uLongcomprLen;
  7. {
  8. z_streamc_stream;/*压缩流*/
  9. interr;
  10. c_stream.zalloc=zalloc;
  11. c_stream.zfree=zfree;
  12. c_stream.opaque=(voidpf)0;
  13. err=deflateInit(&c_stream,Z_BEST_COMPRESSION);
  14. CHECK_ERR(err,"deflateInit");
  15. /*设置压缩流要使用的字典*/
  16. err=deflateSetDictionary(&c_stream,
  17. (constBytef*)dictionary,(int)sizeof(dictionary));
  18. CHECK_ERR(err,"deflateSetDictionary");
  19. dictId=c_stream.adler;/*得到字典的Alder32校验值*/
  20. c_stream.next_out=compr;
  21. c_stream.avail_out=(uInt)comprLen;
  22. c_stream.next_in=(Bytef*)hello;/*输入要压缩的字符串*/
  23. c_stream.avail_in=(uInt)strlen(hello)+1;
  24. /*直接进行压缩*/
  25. err=deflate(&c_stream,Z_FINISH);
  26. if(err!=Z_STREAM_END){
  27. fprintf(stderr,"deflateshouldreportZ_STREAM_END\n");
  28. exit(1);
  29. }
  30. err=deflateEnd(&c_stream);
  31. CHECK_ERR(err,"deflateEnd");
  32. }
  33. /*===========================================================================
  34. *测试inflate():使用预设的字典
  35. */
  36. voidtest_dict_inflate(compr,comprLen,uncompr,uncomprLen)
  37. Byte*compr,*uncompr;
  38. uLongcomprLen,uncomprLen;
  39. {
  40. interr;
  41. z_streamd_stream;/*解压流*/
  42. strcpy((char*)uncompr,"garbage");
  43. d_stream.zalloc=zalloc;
  44. d_stream.zfree=zfree;
  45. d_stream.opaque=(voidpf)0;
  46. d_stream.next_in=compr;
  47. d_stream.avail_in=(uInt)comprLen;
  48. err=inflateInit(&d_stream);
  49. CHECK_ERR(err,"inflateInit");
  50. d_stream.next_out=uncompr;
  51. d_stream.avail_out=(uInt)uncomprLen;
  52. for(;;){/*解压*/
  53. err=inflate(&d_stream,Z_NO_FLUSH);
  54. if(err==Z_STREAM_END)break;
  55. if(err==Z_NEED_DICT){/*如果需要字典*/
  56. if(d_stream.adler!=dictId){/*校验是否与压缩时的字典值一致*/
  57. fprintf(stderr,"unexpecteddictionary");
  58. exit(1);
  59. }
  60. /*设置解压需要的字典*/
  61. err=inflateSetDictionary(&d_stream,(constBytef*)dictionary,
  62. (int)sizeof(dictionary));
  63. }
  64. CHECK_ERR(err,"inflatewithdict");
  65. }
  66. err=inflateEnd(&d_stream);
  67. CHECK_ERR(err,"inflateEnd");
  68. if(strcmp((char*)uncompr,hello)){/*比较解压后的字符串*/
  69. fprintf(stderr,"badinflatewithdict\n");
  70. exit(1);
  71. }else{
  72. printf("inflatewithdictionary:%s\n",(char*)uncompr);
  73. }
  74. }
下面是命令行程序:
  1. /*===========================================================================
  2. *Usage:example[output.gz[input.gz]]
  3. */
  4. intmain(argc,argv)
  5. intargc;
  6. char*argv[];
  7. {
  8. Byte*compr,*uncompr;
  9. uLongcomprLen=10000*sizeof(int);/*在MSDOS上不会溢出*/
  10. uLonguncomprLen=comprLen;
  11. staticconstchar*myVersion=ZLIB_VERSION;
  12. /*检查zlib版本是否一致*/
  13. if(zlibVersion()[0]!=myVersion[0]){
  14. fprintf(stderr,"incompatiblezlibversion\n");
  15. exit(1);
  16. }elseif(strcmp(zlibVersion(),ZLIB_VERSION)!=0){
  17. fprintf(stderr,"warning:differentzlibversion\n");
  18. }
  19. /*打印版本和zlib编译信息*/
  20. printf("zlibversion%s=0x%04x,compileflags=0x%lx\n",
  21. ZLIB_VERSION,ZLIB_VERNUM,zlibCompileFlags());
  22. /*分配输入、输出缓冲区的内存*/
  23. compr=(Byte*)calloc((uInt)comprLen,1);
  24. uncompr=(Byte*)calloc((uInt)uncomprLen,1);
  25. /*清空compr和uncompr,以避免读到未初始化的数据,并且确保uncompr能很好
  26. *地被压缩
  27. */
  28. if(compr==Z_NULL||uncompr==Z_NULL){
  29. printf("outofmemory\n");
  30. exit(1);
  31. }
  32. /*下面运行各个测试函数*/
  33. #ifdefZ_SOLO
  34. argc=strlen(argv[0]);
  35. #else
  36. test_compress(compr,comprLen,uncompr,uncomprLen);
  37. test_gzio((argc>1?argv[1]:TESTFILE),
  38. uncompr,uncomprLen);
  39. #endif
  40. test_deflate(compr,comprLen);
  41. test_inflate(compr,comprLen,uncompr,uncomprLen);
  42. test_large_deflate(compr,comprLen,uncompr,uncomprLen);
  43. test_large_inflate(compr,comprLen,uncompr,uncomprLen);
  44. test_flush(compr,&comprLen);
  45. test_sync(compr,comprLen,uncompr,uncomprLen);
  46. comprLen=uncomprLen;
  47. test_dict_deflate(compr,comprLen);
  48. test_dict_inflate(compr,comprLen,uncompr,uncomprLen);
  49. /*释放缓冲区资源*/
  50. free(compr);
  51. free(uncompr);
  52. return0;
  53. }
更多 0
下面分析test/example.c,它示范了zlib库的各个函数的使用。

下面代码定义要压缩的字符串、压缩时使用的字典、压缩/解压缩的内存分配策略等。

  1. /*example.c--usageexampleofthezlibcompressionlibrary
  2. *Copyright(C)1995-2006,2011Jean-loupGailly.
  3. *Forconditionsofdistributionanduse,seecopyrightnoticeinzlib.h
  4. */
  5. /*@(#)$Id$*/
  6. #include"zlib.h"
  7. #include<stdio.h>
  8. #ifdefSTDC
  9. #include<string.h>
  10. #include<stdlib.h>
  11. #endif
  12. #ifdefined(VMS)||defined(RISCOS)
  13. #defineTESTFILE"foo-gz"
  14. #else
  15. #defineTESTFILE"foo.gz"
  16. #endif
  17. #defineCHECK_ERR(err,msg){\
  18. if(err!=Z_OK){\
  19. fprintf(stderr,"%serror:%d\n",msg,err);\
  20. exit(1);\
  21. }\
  22. }
  23. constcharhello[]="hello,hello!";/*字符长度为14(末尾还有一个null字符)*/
  24. /*"helloworld"wouldbemorestandard,buttherepeated"hello"
  25. *stressesthecompressioncodebetter,sorry...
  26. */
  27. constchardictionary[]="hello";
  28. uLongdictId;/*字典的Adler32校验值*/
  29. voidtest_deflateOF((Byte*compr,uLongcomprLen));
  30. voidtest_inflateOF((Byte*compr,uLongcomprLen,
  31. Byte*uncompr,uLonguncomprLen));
  32. voidtest_large_deflateOF((Byte*compr,uLongcomprLen,
  33. Byte*uncompr,uLonguncomprLen));
  34. voidtest_large_inflateOF((Byte*compr,uLongcomprLen,
  35. Byte*uncompr,uLonguncomprLen));
  36. voidtest_flushOF((Byte*compr,uLong*comprLen));
  37. voidtest_syncOF((Byte*compr,uLongcomprLen,
  38. Byte*uncompr,uLonguncomprLen));
  39. voidtest_dict_deflateOF((Byte*compr,uLongcomprLen));
  40. voidtest_dict_inflateOF((Byte*compr,uLongcomprLen,
  41. Byte*uncompr,uLonguncomprLen));
  42. intmainOF((intargc,char*argv[]));
  43. /*Z_SOLO表示把zlib库编译成单独的不依赖第三方的库*/
  44. #ifdefZ_SOLO
  45. /*使用自定义的内存分配策略*/
  46. void*myallocOF((void*,unsigned,unsigned));
  47. voidmyfreeOF((void*,void*));
  48. void*myalloc(q,n,m)
  49. void*q;
  50. unsignedn,m;
  51. {
  52. q=Z_NULL;
  53. returncalloc(n,m);
  54. }
  55. voidmyfree(void*q,void*p)
  56. {
  57. q=Z_NULL;
  58. free(p);
  59. }
  60. staticalloc_funczalloc=myalloc;
  61. staticfree_funczfree=myfree;
  62. #else/*!Z_SOLO*/
  63. /*使用zlib默认的内存分配策略*/
  64. staticalloc_funczalloc=(alloc_func)0;
  65. staticfree_funczfree=(free_func)0;
下面测试compress和uncompress的用法:
  1. voidtest_compressOF((Byte*compr,uLongcomprLen,
  2. Byte*uncompr,uLonguncomprLen));
  3. voidtest_gzioOF((constchar*fname,
  4. Byte*uncompr,uLonguncomprLen));
  5. /*===========================================================================
  6. *测试compress()和uncompress()
  7. */
  8. voidtest_compress(compr,comprLen,uncompr,uncomprLen)
  9. Byte*compr,*uncompr;
  10. uLongcomprLen,uncomprLen;
  11. {
  12. interr;
  13. uLonglen=(uLong)strlen(hello)+1;/*获取字符串长度*/
  14. /*压缩字符串*/
  15. err=compress(compr,&comprLen,(constBytef*)hello,len);
  16. CHECK_ERR(err,"compress");
  17. strcpy((char*)uncompr,"garbage");
  18. /*解压字符串*/
  19. err=uncompress(uncompr,&uncomprLen,compr,comprLen);
  20. CHECK_ERR(err,"uncompress");
  21. /*比较解压后的结果*/
  22. if(strcmp((char*)uncompr,hello)){
  23. fprintf(stderr,"baduncompress\n");
  24. exit(1);
  25. }else{
  26. printf("uncompress():%s\n",(char*)uncompr);
  27. }
  28. }
下面测试gzip文件的读写操作:
  1. /*===========================================================================
  2. *测试.gz文件的读写操作
  3. */
  4. voidtest_gzio(fname,uncompr,uncomprLen)
  5. constchar*fname;/*gz文件名*/
  6. Byte*uncompr;
  7. uLonguncomprLen;
  8. {
  9. #ifdefNO_GZCOMPRESS
  10. fprintf(stderr,"NO_GZCOMPRESS--gz*functionscannotcompress\n");
  11. #else
  12. interr;
  13. intlen=(int)strlen(hello)+1;
  14. gzFilefile;
  15. z_off_tpos;
  16. file=gzopen(fname,"wb");/*打开要写入的gz文件*/
  17. if(file==NULL){
  18. fprintf(stderr,"gzopenerror\n");
  19. exit(1);
  20. }
  21. gzputc(file,'h');/*写入一个字符'h'*/
  22. if(gzputs(file,"ello")!=4){/*写入字符串"ello"*/
  23. fprintf(stderr,"gzputserr:%s\n",gzerror(file,&err));
  24. exit(1);
  25. }
  26. if(gzprintf(file,",%s!","hello")!=8){/*按格式写入字符串",hello!"*/
  27. fprintf(stderr,"gzprintferr:%s\n",gzerror(file,&err));
  28. exit(1);
  29. }
  30. gzseek(file,1L,SEEK_CUR);/*读写头向前移动1字节(即添加一个0字节)*/
  31. gzclose(file);/*关闭gz文件*/
  32. file=gzopen(fname,"rb");/*打开要读取的gz文件*/
  33. if(file==NULL){
  34. fprintf(stderr,"gzopenerror\n");
  35. exit(1);
  36. }
  37. strcpy((char*)uncompr,"garbage");
  38. /*从压缩文件中读取给定大小的解压字节数*/
  39. if(gzread(file,uncompr,(unsigned)uncomprLen)!=len){
  40. fprintf(stderr,"gzreaderr:%s\n",gzerror(file,&err));
  41. exit(1);
  42. }
  43. if(strcmp((char*)uncompr,hello)){/*比较解压后的结果*/
  44. fprintf(stderr,"badgzread:%s\n",(char*)uncompr);
  45. exit(1);
  46. }else{
  47. printf("gzread():%s\n",(char*)uncompr);
  48. }
  49. pos=gzseek(file,-8L,SEEK_CUR);/*读写头向后移动8字节,应该停留在第6个字符处*/
  50. if(pos!=6||gztell(file)!=pos){/*判断是否停留在第6个字符处*/
  51. fprintf(stderr,"gzseekerror,pos=%ld,gztell=%ld\n",
  52. (long)pos,(long)gztell(file));
  53. exit(1);
  54. }
  55. if(gzgetc(file)!=''){/*从当前位置读取1个字符,应该为字符''*/
  56. fprintf(stderr,"gzgetcerror\n");
  57. exit(1);
  58. }
  59. if(gzungetc('',file)!=''){/*推回这个字符到流中*/
  60. fprintf(stderr,"gzungetcerror\n");
  61. exit(1);
  62. }
  63. /*从压缩文件当前位置读取指定长度的解压字节数,直到len-1个字符被读取*/
  64. gzgets(file,(char*)uncompr,(int)uncomprLen);
  65. if(strlen((char*)uncompr)!=7){/*"hello!"*/
  66. fprintf(stderr,"gzgetserraftergzseek:%s\n",gzerror(file,&err));
  67. exit(1);
  68. }
  69. if(strcmp((char*)uncompr,hello+6)){
  70. fprintf(stderr,"badgzgetsaftergzseek\n");
  71. exit(1);
  72. }else{
  73. printf("gzgets()aftergzseek:%s\n",(char*)uncompr);
  74. }
  75. gzclose(file);/*关闭gz文件*/
  76. #endif
  77. }
  78. #endif/*Z_SOLO*/
下面用小缓冲区测试压缩、解压操作(deflate/deflate):
  1. /*===========================================================================
  2. *测试deflate():使用小缓冲区
  3. */
  4. voidtest_deflate(compr,comprLen)
  5. Byte*compr;
  6. uLongcomprLen;
  7. {
  8. z_streamc_stream;/*压缩流*/
  9. interr;
  10. uLonglen=(uLong)strlen(hello)+1;
  11. /*这三个字段要在defalteInit之前初始化*/
  12. c_stream.zalloc=zalloc;
  13. c_stream.zfree=zfree;
  14. c_stream.opaque=(voidpf)0;
  15. /*初始化压缩流的状态,使用默认压缩级别*/
  16. err=deflateInit(&c_stream,Z_DEFAULT_COMPRESSION);
  17. CHECK_ERR(err,"deflateInit");
  18. /*设置压缩操作的输入数据和输出缓冲区*/
  19. c_stream.next_in=(Bytef*)hello;/*输入缓冲区指向输入字符串*/
  20. c_stream.next_out=compr;
  21. /*第一个循环:将flush设为Z_NO_FLUSH(表示还有输入数据未读完),将所有输入都读进去并进行压缩
  22. 根据avail_in和avail_out,不停地调用deflate将输入缓冲区的数据压缩
  23. 并写到输出缓冲区,直到输入字符串读完或输出缓冲区用完
  24. */
  25. while(c_stream.total_in!=len&&c_stream.total_out<comprLen){
  26. c_stream.avail_in=c_stream.avail_out=1;/*强制小缓冲区*/
  27. err=deflate(&c_stream,Z_NO_FLUSH);
  28. CHECK_ERR(err,"deflate");
  29. }
  30. /*第二个循环:将flush设置为Z_FINISH,不再输入,让deflate()完成全部的压缩输出
  31. 注意因为deflate压缩时可能是异步的(为了加速压缩,读取一次输入后不一定立刻就会产生压缩输出,
  32. 可能读完K字节后才会产生输出),所以上一个循环可能还没产生全部输出,需要这个循环,让flush保持Z_FINISH
  33. (表示输入数据已读完),多次调用deflate(),直到返回Z_STREAM_END,表示处理完全部输入并产生了全部的压缩输出
  34. */
  35. for(;;){/*完成压缩流的刷新,仍然强制小缓冲区*/
  36. c_stream.avail_out=1;
  37. err=deflate(&c_stream,Z_FINISH);
  38. if(err==Z_STREAM_END)break;
  39. CHECK_ERR(err,"deflate");
  40. }
  41. err=deflateEnd(&c_stream);/*释放压缩流的资源*/
  42. CHECK_ERR(err,"deflateEnd");
  43. }
  44. /*===========================================================================
  45. *测试inflate():使用小缓冲区
  46. */
  47. voidtest_inflate(compr,comprLen,uncompr,uncomprLen)
  48. Byte*compr,*uncompr;
  49. uLongcomprLen,uncomprLen;
  50. {
  51. interr;
  52. z_streamd_stream;/*解压流*/
  53. strcpy((char*)uncompr,"garbage");
  54. /*这些个字段要在infalteInit之前初始化*/
  55. d_stream.zalloc=zalloc;
  56. d_stream.zfree=zfree;
  57. d_stream.opaque=(voidpf)0;
  58. d_stream.next_in=compr;/*设置输入缓冲区*/
  59. d_stream.avail_in=0;
  60. d_stream.next_out=uncompr;/*设置输出缓冲区*/
  61. /*初始化解压流的状态*/
  62. err=inflateInit(&d_stream);
  63. CHECK_ERR(err,"inflateInit");
  64. /*只需一个循环:根据avail_in和avail_out,不停地调用inflate将输入缓冲区的数据
  65. 解压,直到返回Z_STREAM_END,表示处理完全部输入并产生了全部的解压输出
  66. 这里与flush参数是否为Z_FINISH无关
  67. */
  68. while(d_stream.total_out<uncomprLen&&d_stream.total_in<comprLen){
  69. d_stream.avail_in=d_stream.avail_out=1;/*强制小缓冲区*/
  70. err=inflate(&d_stream,Z_NO_FLUSH);
  71. if(err==Z_STREAM_END)break;
  72. CHECK_ERR(err,"inflate");
  73. }
  74. err=inflateEnd(&d_stream);/*释放解压流的资源*/
  75. CHECK_ERR(err,"inflateEnd");
  76. if(strcmp((char*)uncompr,hello)){/*比较解压后的数据*/
  77. fprintf(stderr,"badinflate\n");
  78. exit(1);
  79. }else{
  80. printf("inflate():%s\n",(char*)uncompr);
  81. }
  82. }
下面使用大缓冲区测试压缩、解压操作(deflate/deflate):
  1. /*===========================================================================
  2. *测试deflate():使用大缓冲区和动态改变的压缩级别
  3. */
  4. voidtest_large_deflate(compr,comprLen,uncompr,uncomprLen)
  5. Byte*compr,*uncompr;
  6. uLongcomprLen,uncomprLen;
  7. {
  8. z_streamc_stream;/*压缩流*/
  9. interr;
  10. /*这三个字段要在defalteInit之前初始化*/
  11. c_stream.zalloc=zalloc;
  12. c_stream.zfree=zfree;
  13. c_stream.opaque=(voidpf)0;
  14. /*初始化压缩流的状态,使用最快速度压缩*/
  15. err=deflateInit(&c_stream,Z_BEST_SPEED);
  16. CHECK_ERR(err,"deflateInit");
  17. c_stream.next_out=compr;
  18. c_stream.avail_out=(uInt)comprLen;
  19. /*这里,uncompr几乎都为0,因此可以很好地被压缩*/
  20. c_stream.next_in=uncompr;
  21. c_stream.avail_in=(uInt)uncomprLen;
  22. err=deflate(&c_stream,Z_NO_FLUSH);/*压缩输入数据*/
  23. CHECK_ERR(err,"deflate");
  24. if(c_stream.avail_in!=0){
  25. fprintf(stderr,"deflatenotgreedy\n");
  26. exit(1);
  27. }
  28. /*把已压缩的数据转换成未压缩:*/
  29. /*设置流的压缩级别(为未压缩)和压缩策略*/
  30. deflateParams(&c_stream,Z_NO_COMPRESSION,Z_DEFAULT_STRATEGY);
  31. c_stream.next_in=compr;
  32. c_stream.avail_in=(uInt)comprLen/2;
  33. err=deflate(&c_stream,Z_NO_FLUSH);
  34. CHECK_ERR(err,"deflate");
  35. /*转换回压缩模式(最高压缩率):*/
  36. deflateParams(&c_stream,Z_BEST_COMPRESSION,Z_FILTERED);
  37. c_stream.next_in=uncompr;
  38. c_stream.avail_in=(uInt)uncomprLen;
  39. err=deflate(&c_stream,Z_NO_FLUSH);
  40. CHECK_ERR(err,"deflate");
  41. /*流刷新,产生全部压缩输出*/
  42. err=deflate(&c_stream,Z_FINISH);
  43. if(err!=Z_STREAM_END){
  44. fprintf(stderr,"deflateshouldreportZ_STREAM_END\n");
  45. exit(1);
  46. }
  47. err=deflateEnd(&c_stream);/*释放流的资源*/
  48. CHECK_ERR(err,"deflateEnd");
  49. }
  50. /*===========================================================================
  51. *测试inflate():使用大缓冲区
  52. */
  53. voidtest_large_inflate(compr,comprLen,uncompr,uncomprLen)
  54. Byte*compr,*uncompr;
  55. uLongcomprLen,uncomprLen;
  56. {
  57. interr;
  58. z_streamd_stream;/*解压流*/
  59. strcpy((char*)uncompr,"garbage");
  60. /*这些个字段要在infalteInit之前初始化*/
  61. d_stream.zalloc=zalloc;
  62. d_stream.zfree=zfree;
  63. d_stream.opaque=(voidpf)0;
  64. d_stream.next_in=compr;
  65. d_stream.avail_in=(uInt)comprLen;
  66. /*初始化解压流*/
  67. err=inflateInit(&d_stream);
  68. CHECK_ERR(err,"inflateInit");
  69. /*解压*/
  70. for(;;){
  71. d_stream.next_out=uncompr;/*抛弃输出*/
  72. d_stream.avail_out=(uInt)uncomprLen;
  73. err=inflate(&d_stream,Z_NO_FLUSH);/*解压输入数据*/
  74. if(err==Z_STREAM_END)break;
  75. CHECK_ERR(err,"largeinflate");
  76. }
  77. err=inflateEnd(&d_stream);
  78. CHECK_ERR(err,"inflateEnd");
  79. if(d_stream.total_out!=2*uncomprLen+comprLen/2){
  80. fprintf(stderr,"badlargeinflate:%ld\n",d_stream.total_out);
  81. exit(1);
  82. }else{
  83. printf("large_inflate():OK\n");
  84. }
  85. }
下面使用完全刷新模式测试压缩操作deflate:
  1. /*===========================================================================
  2. *测试deflate():使用完全刷新
  3. */
  4. voidtest_flush(compr,comprLen)
  5. Byte*compr;
  6. uLong*comprLen;
  7. {
  8. z_streamc_stream;/*压缩流*/
  9. interr;
  10. uIntlen=(uInt)strlen(hello)+1;
  11. c_stream.zalloc=zalloc;
  12. c_stream.zfree=zfree;
  13. c_stream.opaque=(voidpf)0;
  14. err=deflateInit(&c_stream,Z_DEFAULT_COMPRESSION);
  15. CHECK_ERR(err,"deflateInit");
  16. c_stream.next_in=(Bytef*)hello;
  17. c_stream.next_out=compr;
  18. c_stream.avail_in=3;
  19. c_stream.avail_out=(uInt)*comprLen;
  20. /*使用完全刷新来压缩字符串*/
  21. err=deflate(&c_stream,Z_FULL_FLUSH);
  22. CHECK_ERR(err,"deflate");
  23. compr[3]++;/*在第一个压缩块中强制产生一个错误*/
  24. c_stream.avail_in=len-3;
  25. err=deflate(&c_stream,Z_FINISH);
  26. if(err!=Z_STREAM_END){
  27. CHECK_ERR(err,"deflate");
  28. }
  29. err=deflateEnd(&c_stream);
  30. CHECK_ERR(err,"deflateEnd");
  31. *comprLen=c_stream.total_out;
  32. }
下面测试同步方式的解压操作inflateSync:
  1. /*===========================================================================
  2. *TestinflateSync()
  3. */
  4. voidtest_sync(compr,comprLen,uncompr,uncomprLen)
  5. Byte*compr,*uncompr;
  6. uLongcomprLen,uncomprLen;
  7. {
  8. interr;
  9. z_streamd_stream;/*解压流*/
  10. strcpy((char*)uncompr,"garbage");
  11. d_stream.zalloc=zalloc;
  12. d_stream.zfree=zfree;
  13. d_stream.opaque=(voidpf)0;
  14. d_stream.next_in=compr;/*设置输入缓冲区*/
  15. d_stream.avail_in=2;/*只读取zlib头部信息*/
  16. err=inflateInit(&d_stream);
  17. CHECK_ERR(err,"inflateInit");
  18. d_stream.next_out=uncompr;/*设置输出缓冲区*/
  19. d_stream.avail_out=(uInt)uncomprLen;
  20. inflate(&d_stream,Z_NO_FLUSH);
  21. CHECK_ERR(err,"inflate");
  22. d_stream.avail_in=(uInt)comprLen-2;/*读取所有压缩数据*/
  23. err=inflateSync(&d_stream);/*但忽略损坏的部分*/
  24. CHECK_ERR(err,"inflateSync");
  25. err=inflate(&d_stream,Z_FINISH);/*完成解压*/
  26. if(err!=Z_DATA_ERROR){
  27. fprintf(stderr,"inflateshouldreportDATA_ERROR\n");
  28. /*因为不正确的adler32*/
  29. exit(1);
  30. }
  31. err=inflateEnd(&d_stream);
  32. CHECK_ERR(err,"inflateEnd");
  33. printf("afterinflateSync():hel%s\n",(char*)uncompr);
  34. }
下面用预设的字典测试压缩、解压操作(deflate/inflate):
  1. /*===========================================================================
  2. *测试:deflate():使用预设的字典
  3. */
  4. voidtest_dict_deflate(compr,comprLen)
  5. Byte*compr;
  6. uLongcomprLen;
  7. {
  8. z_streamc_stream;/*压缩流*/
  9. interr;
  10. c_stream.zalloc=zalloc;
  11. c_stream.zfree=zfree;
  12. c_stream.opaque=(voidpf)0;
  13. err=deflateInit(&c_stream,Z_BEST_COMPRESSION);
  14. CHECK_ERR(err,"deflateInit");
  15. /*设置压缩流要使用的字典*/
  16. err=deflateSetDictionary(&c_stream,
  17. (constBytef*)dictionary,(int)sizeof(dictionary));
  18. CHECK_ERR(err,"deflateSetDictionary");
  19. dictId=c_stream.adler;/*得到字典的Alder32校验值*/
  20. c_stream.next_out=compr;
  21. c_stream.avail_out=(uInt)comprLen;
  22. c_stream.next_in=(Bytef*)hello;/*输入要压缩的字符串*/
  23. c_stream.avail_in=(uInt)strlen(hello)+1;
  24. /*直接进行压缩*/
  25. err=deflate(&c_stream,Z_FINISH);
  26. if(err!=Z_STREAM_END){
  27. fprintf(stderr,"deflateshouldreportZ_STREAM_END\n");
  28. exit(1);
  29. }
  30. err=deflateEnd(&c_stream);
  31. CHECK_ERR(err,"deflateEnd");
  32. }
  33. /*===========================================================================
  34. *测试inflate():使用预设的字典
  35. */
  36. voidtest_dict_inflate(compr,comprLen,uncompr,uncomprLen)
  37. Byte*compr,*uncompr;
  38. uLongcomprLen,uncomprLen;
  39. {
  40. interr;
  41. z_streamd_stream;/*解压流*/
  42. strcpy((char*)uncompr,"garbage");
  43. d_stream.zalloc=zalloc;
  44. d_stream.zfree=zfree;
  45. d_stream.opaque=(voidpf)0;
  46. d_stream.next_in=compr;
  47. d_stream.avail_in=(uInt)comprLen;
  48. err=inflateInit(&d_stream);
  49. CHECK_ERR(err,"inflateInit");
  50. d_stream.next_out=uncompr;
  51. d_stream.avail_out=(uInt)uncomprLen;
  52. for(;;){/*解压*/
  53. err=inflate(&d_stream,Z_NO_FLUSH);
  54. if(err==Z_STREAM_END)break;
  55. if(err==Z_NEED_DICT){/*如果需要字典*/
  56. if(d_stream.adler!=dictId){/*校验是否与压缩时的字典值一致*/
  57. fprintf(stderr,"unexpecteddictionary");
  58. exit(1);
  59. }
  60. /*设置解压需要的字典*/
  61. err=inflateSetDictionary(&d_stream,(constBytef*)dictionary,
  62. (int)sizeof(dictionary));
  63. }
  64. CHECK_ERR(err,"inflatewithdict");
  65. }
  66. err=inflateEnd(&d_stream);
  67. CHECK_ERR(err,"inflateEnd");
  68. if(strcmp((char*)uncompr,hello)){/*比较解压后的字符串*/
  69. fprintf(stderr,"badinflatewithdict\n");
  70. exit(1);
  71. }else{
  72. printf("inflatewithdictionary:%s\n",(char*)uncompr);
  73. }
  74. }
下面是命令行程序:
  1. /*===========================================================================
  2. *Usage:example[output.gz[input.gz]]
  3. */
  4. intmain(argc,argv)
  5. intargc;
  6. char*argv[];
  7. {
  8. Byte*compr,*uncompr;
  9. uLongcomprLen=10000*sizeof(int);/*在MSDOS上不会溢出*/
  10. uLonguncomprLen=comprLen;
  11. staticconstchar*myVersion=ZLIB_VERSION;
  12. /*检查zlib版本是否一致*/
  13. if(zlibVersion()[0]!=myVersion[0]){
  14. fprintf(stderr,"incompatiblezlibversion\n");
  15. exit(1);
  16. }elseif(strcmp(zlibVersion(),ZLIB_VERSION)!=0){
  17. fprintf(stderr,"warning:differentzlibversion\n");
  18. }
  19. /*打印版本和zlib编译信息*/
  20. printf("zlibversion%s=0x%04x,compileflags=0x%lx\n",
  21. ZLIB_VERSION,ZLIB_VERNUM,zlibCompileFlags());
  22. /*分配输入、输出缓冲区的内存*/
  23. compr=(Byte*)calloc((uInt)comprLen,1);
  24. uncompr=(Byte*)calloc((uInt)uncomprLen,1);
  25. /*清空compr和uncompr,以避免读到未初始化的数据,并且确保uncompr能很好
  26. *地被压缩
  27. */
  28. if(compr==Z_NULL||uncompr==Z_NULL){
  29. printf("outofmemory\n");
  30. exit(1);
  31. }
  32. /*下面运行各个测试函数*/
  33. #ifdefZ_SOLO
  34. argc=strlen(argv[0]);
  35. #else
  36. test_compress(compr,comprLen,uncompr,uncomprLen);
  37. test_gzio((argc>1?argv[1]:TESTFILE),
  38. uncompr,uncomprLen);
  39. #endif
  40. test_deflate(compr,comprLen);
  41. test_inflate(compr,comprLen,uncompr,uncomprLen);
  42. test_large_deflate(compr,comprLen,uncompr,uncomprLen);
  43. test_large_inflate(compr,comprLen,uncompr,uncomprLen);
  44. test_flush(compr,&comprLen);
  45. test_sync(compr,comprLen,uncompr,uncomprLen);
  46. comprLen=uncomprLen;
  47. test_dict_deflate(compr,comprLen);
  48. test_dict_inflate(compr,comprLen,uncompr,uncomprLen);
  49. /*释放缓冲区资源*/
  50. free(compr);
  51. free(uncompr);
  52. return0;
  53. }
分享到:
评论

相关推荐

    zlib1.1.4源码

    7. `example.c`:示例代码,展示了如何在实际项目中使用zlib库。 8. `inftrees.c`:处理解压缩时的树结构操作,与`trees.c`相辅相成。 9. `inffast.c`:快速解压缩实现,通过优化算法来提高解压速度。 10. `crc32.c`...

    zlib压缩算法源代码

    - `example.c`:包含了一些示例代码,展示了如何使用`zlib`库进行压缩和解压缩操作。 - `inftrees.c`:处理`deflate`编码中用到的动态霍夫曼树。 - `crc32.c`:实现了CRC32校验码的计算,用于验证数据的完整性和一致...

    SSH客户端操作Linux

    在你输入“yes”之前呢,最佳的选择或许是联系你的系统管理员来分析为什么会出现主机验证码改变的信息,核对主机验证码是否正确。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 localhost$ ssh -l jsmith remotehost....

    nginx安装包

    1. **日志管理**:配置日志文件位置和级别,便于监控和分析。 2. **安全设置**:启用HTTPS,使用SSL证书加密通信,限制访问权限。 3. **缓存设置**:配置静态文件缓存,提高响应速度。 4. **负载均衡**:通过Nginx的...

    HDF5的C++安装包

    HDF5(Hierarchical Data Format 5)是一种高级数据存储格式,被广泛应用于科学计算、数据分析和工程领域。它提供了高效、灵活和可扩展的方式来组织和管理大量的多维数据。在C++环境中,HDF5库允许开发人员创建、...

    main2_C++_Cool_zip_

    2. 打开 ZIP 文件:使用库提供的函数打开 ZIP 文件,可能需要指定文件路径和操作模式(如只读、读写)。 3. 遍历文件:获取 ZIP 文件中的所有条目(entries),通常是一个包含文件信息的列表。 4. 读取或写入:根据...

    matio:MATLAB MAT文件IO库

    - 写入变量:使用`matioWriteVariable`将C数据类型转换为MATLAB兼容的数据类型,并写入文件。 - 读取变量:使用`matioReadVariable`从文件中读取变量。 - 关闭文件:使用`matioClose`关闭文件。 **6. 示例代码**...

    libuv-cmake-v1.39.0源码和cmake解决方案.zip

    3. **Example项目**:示例代码,展示libuv的使用方法。 四、编译与运行 在E:\Aubo\libuv-v1.39.0.tar目录下,首先使用CMake配置生成.sln文件,然后使用Visual Studio打开.sln,选择适当的配置(如Debug或Release)...

    node-stream-demo:使用节点的演示流服务器

    - `example.js`:可能包含了一些示例代码,展示了如何使用流处理数据。 - `test`目录:可能包含了测试文件,用于验证服务器功能的正确性。 通过分析这些文件,你可以更深入地了解流服务器的实现细节。例如,`server...

    SSHD移植文档_ssh移植_

    4. **构建依赖**:检查源代码中的编译依赖项,如OpenSSL、zlib等,确保目标系统已安装这些库或准备安装它们。有时需要交叉编译这些库以适应目标环境。 5. **编译选项**:配置编译选项以适应目标系统。使用 `./...

    nodejs-stream-example:有关NodeJS流如何工作的示例项目

    - 使用Transform流,比如zlib模块的Gzip或Gunzip,对数据进行压缩或解压缩。 - 处理HTTP请求和响应时,利用内置的http模块,可以看到流的用法。 - 可能还有自定义的双工流,用于自定义的数据处理和传输逻辑。 五、...

    cpp (1)_win32API_zip_

    描述中的"win 32 touch example"可能是指一个使用Win32 API来处理触摸输入功能的示例,这在现代的Windows操作系统中,尤其是支持触摸屏设备的系统中是常见的需求。这里的“touch”可能意味着示例代码会展示如何在Win...

    Pillow-2.3.2.tar.gz

    《Pillow库详解及其在Python中的应用》 Pillow,作为一个Python图像处理库,是 PIL(Python Imaging Library)的一个分支,旨在提供更加友好且易于安装的接口,支持Python 3.x版本。在“Pillow-2.3.2.tar.gz”这个...

    quazip:一个用于Gilles Vollant的ZIPUNZIP C包(minizip)的QtC ++包装器。 使用QIODevice API提供对来自Qt程序的ZIP存档的访问

    Minizip库是对Zlib库的扩展,Zlib是一个广泛使用的数据压缩库。 2. **QtC++接口的引入** Quazip将minizip的功能包装成C++类,使其更符合Qt的编程模式。这意味着开发者可以使用Qt的I/O设备接口,如QFile或...

    lab_05_zip_Asm_

    - 使用汇编语言调用高级语言的库:可能需要使用系统调用或DLL导入来利用已经存在的ZIP处理库,如zlib,因为直接在Asm中实现完整的压缩和解压缩功能可能非常复杂。 总之,“lab_05_zip_Asm_”的学习涵盖了汇编语言...

Global site tag (gtag.js) - Google Analytics