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 }
1.2.15