00001 /******************************************************************************
00002 * swcomprs.cpp - code for class 'SWCompress'- a driver class that provides
00003 * compression utilities.
00004 */
00005
00006 #include <string.h>
00007 #include <stdlib.h>
00008 #include <swcomprs.h>
00009
00010
00011 /******************************************************************************
00012 * SWCompress Constructor - Initializes data for instance of SWCompress
00013 *
00014 */
00015
00016 SWCompress::SWCompress()
00017 {
00018 buf = zbuf = 0;
00019 Init();
00020 }
00021
00022
00023 /******************************************************************************
00024 * SWCompress Destructor - Cleans up instance of SWCompress
00025 */
00026
00027 SWCompress::~SWCompress()
00028 {
00029 if (zbuf)
00030 free(zbuf);
00031
00032 if (buf)
00033 free(buf);
00034 }
00035
00036
00037 void SWCompress::Init()
00038 {
00039 if (buf)
00040 free(buf);
00041
00042 if (zbuf)
00043 free(zbuf);
00044
00045 buf = 0;
00046 zbuf = 0;
00047 direct = 0;
00048 zlen = 0;
00049 slen = 0;
00050 zpos = 0;
00051 pos = 0;
00052 }
00053
00054
00055 char *SWCompress::Buf(const char *ibuf, unsigned long *len) {
00056 // setting an uncompressed buffer
00057 if (ibuf) {
00058 Init();
00059 slen = (len) ? *len : strlen(ibuf);
00060 buf = (char *) calloc(slen + 1, 1);
00061 memcpy(buf, ibuf, slen);
00062 }
00063
00064 // getting an uncompressed buffer
00065 if (!buf) {
00066 buf = (char *)calloc(1,1); // be sure we at least allocate an empty buf for return;
00067 direct = 1;
00068 Decode();
00069 // slen = strlen(buf);
00070 if (len)
00071 *len = slen;
00072 }
00073 return buf;
00074 }
00075
00076
00077 char *SWCompress::zBuf(unsigned long *len, char *ibuf)
00078 {
00079 // setting a compressed buffer
00080 if (ibuf) {
00081 Init();
00082 zbuf = (char *) malloc(*len);
00083 memcpy(zbuf, ibuf, *len);
00084 zlen = *len;
00085 }
00086
00087 // getting a compressed buffer
00088 if (!zbuf) {
00089 direct = 0;
00090 Encode();
00091 }
00092
00093 *len = zlen;
00094 return zbuf;
00095 }
00096
00097
00098 unsigned long SWCompress::GetChars(char *ibuf, unsigned long len)
00099 {
00100 if (direct) {
00101 len = (((zlen - zpos) > (unsigned)len) ? len : zlen - zpos);
00102 if (len > 0) {
00103 memmove(ibuf, &zbuf[zpos], len);
00104 zpos += len;
00105 }
00106 }
00107 else {
00108 // slen = strlen(buf);
00109 len = (((slen - pos) > (unsigned)len) ? len : slen - pos);
00110 if (len > 0) {
00111 memmove(ibuf, &buf[pos], len);
00112 pos += len;
00113 }
00114 }
00115 return len;
00116 }
00117
00118
00119 unsigned long SWCompress::SendChars(char *ibuf, unsigned long len)
00120 {
00121 if (direct) {
00122 if (buf) {
00123 // slen = strlen(buf);
00124 if ((pos + len) > (unsigned)slen) {
00125 buf = (char *) realloc(buf, pos + len + 1024);
00126 memset(&buf[pos], 0, len + 1024);
00127 }
00128 }
00129 else buf = (char *)calloc(1, len + 1024);
00130 memmove(&buf[pos], ibuf, len);
00131 pos += len;
00132 }
00133 else {
00134 if (zbuf) {
00135 if ((zpos + len) > zlen) {
00136 zbuf = (char *) realloc(zbuf, zpos + len + 1024);
00137 zlen = zpos + len + 1024;
00138 }
00139 }
00140 else {
00141 zbuf = (char *)calloc(1, len + 1024);
00142 zlen = len + 1024;
00143 }
00144 memmove(&zbuf[zpos], ibuf, len);
00145 zpos += len;
00146 }
00147 return len;
00148 }
00149
00150
00151 /******************************************************************************
00152 * SWCompress::Encode - This function "encodes" the input stream into the
00153 * output stream.
00154 * The GetChars() and SendChars() functions are
00155 * used to separate this method from the actual
00156 * i/o.
00157 */
00158
00159 void SWCompress::Encode(void)
00160 {
00161 cycleStream();
00162 }
00163
00164
00165 /******************************************************************************
00166 * SWCompress::Decode - This function "decodes" the input stream into the
00167 * output stream.
00168 * The GetChars() and SendChars() functions are
00169 * used to separate this method from the actual
00170 * i/o.
00171 */
00172
00173 void SWCompress::Decode(void)
00174 {
00175 cycleStream();
00176 }
00177
00178
00179 void SWCompress::cycleStream() {
00180 char buf[1024];
00181 unsigned long len, totlen = 0;
00182
00183 do {
00184 len = GetChars(buf, 1024);
00185 if (len)
00186 totlen += SendChars(buf, len);
00187 } while (len == 1024);
00188
00189 zlen = slen = totlen;
00190 }
1.2.15