00001 /****************************************************************************** 00002 * swcomprs.cpp - code for class 'ZipCompress'- a driver class that provides 00003 * compression utilities. - using zlib 00004 */ 00005 00006 #include <string.h> 00007 #include <string> 00008 #include <stdlib.h> 00009 #include <stdio.h> 00010 #include <zipcomprs.h> 00011 #include <zlib.h> 00012 00013 /****************************************************************************** 00014 * ZipCompress Constructor - Initializes data for instance of ZipCompress 00015 * 00016 */ 00017 00018 ZipCompress::ZipCompress() : SWCompress() 00019 { 00020 // fprintf(stderr, "init compress\n"); 00021 } 00022 00023 00024 /****************************************************************************** 00025 * ZipCompress Destructor - Cleans up instance of ZipCompress 00026 */ 00027 00028 ZipCompress::~ZipCompress() { 00029 } 00030 00031 00032 /****************************************************************************** 00033 * ZipCompress::Encode - This function "encodes" the input stream into the 00034 * output stream. 00035 * The GetChars() and SendChars() functions are 00036 * used to separate this method from the actual 00037 * i/o. 00038 * NOTE: must set zlen for parent class to know length of 00039 * compressed buffer. 00040 */ 00041 00042 void ZipCompress::Encode(void) 00043 { 00044 /* 00045 ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, 00046 const Bytef *source, uLong sourceLen)); 00047 Compresses the source buffer into the destination buffer. sourceLen is 00048 the byte length of the source buffer. Upon entry, destLen is the total 00049 size of the destination buffer, which must be at least 0.1% larger than 00050 sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the 00051 compressed buffer. 00052 This function can be used to compress a whole file at once if the 00053 input file is mmap'ed. 00054 compress returns Z_OK if success, Z_MEM_ERROR if there was not 00055 enough memory, Z_BUF_ERROR if there was not enough room in the output 00056 buffer. 00057 */ 00058 direct = 0; // set direction needed by parent [Get|Send]Chars() 00059 00060 // get buffer 00061 char chunk[1024]; 00062 char *buf = (char *)calloc(1, 1024); 00063 char *chunkbuf = buf; 00064 unsigned long chunklen; 00065 unsigned long len = 0; 00066 while((chunklen = GetChars(chunk, 1023))) { 00067 memcpy(chunkbuf, chunk, chunklen); 00068 len += chunklen; 00069 if (chunklen < 1023) 00070 break; 00071 else buf = (char *)realloc(buf, len + 1024); 00072 chunkbuf = buf+len; 00073 } 00074 00075 00076 zlen = (long) (len*1.001)+15; 00077 char *zbuf = new char[zlen+1]; 00078 if (len) 00079 { 00080 //printf("Doing compress\n"); 00081 if (compress((Bytef*)zbuf, &zlen, (const Bytef*)buf, len)!=Z_OK) 00082 { 00083 printf("ERROR in compression\n"); 00084 } 00085 else { 00086 SendChars(zbuf, zlen); 00087 } 00088 } 00089 else 00090 { 00091 fprintf(stderr, "No buffer to compress\n"); 00092 } 00093 delete [] zbuf; 00094 free (buf); 00095 } 00096 00097 00098 /****************************************************************************** 00099 * ZipCompress::Decode - This function "decodes" the input stream into the 00100 * output stream. 00101 * The GetChars() and SendChars() functions are 00102 * used to separate this method from the actual 00103 * i/o. 00104 */ 00105 00106 void ZipCompress::Decode(void) 00107 { 00108 /* 00109 ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, 00110 const Bytef *source, uLong sourceLen)); 00111 Decompresses the source buffer into the destination buffer. sourceLen is 00112 the byte length of the source buffer. Upon entry, destLen is the total 00113 size of the destination buffer, which must be large enough to hold the 00114 entire uncompressed data. (The size of the uncompressed data must have 00115 been saved previously by the compressor and transmitted to the decompressor 00116 by some mechanism outside the scope of this compression library.) 00117 Upon exit, destLen is the actual size of the compressed buffer. 00118 This function can be used to decompress a whole file at once if the 00119 input file is mmap'ed. 00120 00121 uncompress returns Z_OK if success, Z_MEM_ERROR if there was not 00122 enough memory, Z_BUF_ERROR if there was not enough room in the output 00123 buffer, or Z_DATA_ERROR if the input data was corrupted. 00124 */ 00125 00126 // get buffer 00127 char chunk[1024]; 00128 char *zbuf = (char *)calloc(1, 1024); 00129 char *chunkbuf = zbuf; 00130 int chunklen; 00131 unsigned long zlen = 0; 00132 while((chunklen = GetChars(chunk, 1023))) { 00133 memcpy(chunkbuf, chunk, chunklen); 00134 zlen += chunklen; 00135 if (chunklen < 1023) 00136 break; 00137 else zbuf = (char *)realloc(zbuf, zlen + 1024); 00138 chunkbuf = zbuf + zlen; 00139 } 00140 00141 //printf("Decoding complength{%ld} uncomp{%ld}\n", zlen, blen); 00142 if (zlen) { 00143 unsigned long blen = zlen*20; // trust compression is less than 1000% 00144 char *buf = new char[blen]; 00145 //printf("Doing decompress {%s}\n", zbuf); 00146 if (uncompress((Bytef*)buf, &blen, (Bytef*)zbuf, zlen) != Z_OK) { 00147 fprintf(stderr, "no room in outbuffer to during decompression. see zipcomp.cpp\n"); 00148 } 00149 SendChars(buf, blen); 00150 delete [] buf; 00151 slen = blen; 00152 } 00153 else { 00154 fprintf(stderr, "No buffer to decompress!\n"); 00155 } 00156 //printf("Finished decoding\n"); 00157 free (zbuf); 00158 }