00001
00002
00003
00004
00005
00006
00007
00008
00009 static const char rcsid[] __attribute__((used)) = "$Id: Compress.cpp 1230 2014-11-16 02:32:01Z sella $";
00010
00011 #include "Compress.h"
00012 #include "CommonMacro.h"
00013
00014 #include <zlib.h>
00015 #include <stdio.h>
00016 #include <string.h>
00017 #include <signal.h>
00018 #include <stdlib.h>
00019 #include <unistd.h>
00020 #include <pthread.h>
00021 #include <sys/stat.h>
00022 #include <sys/types.h>
00023 #include <assert.h>
00024
00025 #define SET_BINARY_MODE(file)
00026
00027 #define CHUNK 16384
00028
00029
00030 using namespace sella::util;
00031
00032 Compress::Compress(int level) : c(NULL), un(NULL), clen(0), unlen(0) {
00033 setLevel(level);
00034 }
00035
00036 Compress::Compress(const Compress &other) :
00037 level(other.level),
00038 c(malloc(other.clen)),
00039 un(malloc(other.unlen)),
00040
00041 clen(other.clen),
00042 unlen(other.unlen)
00043 {
00044 memcpy(this->c, other.c, this->clen);
00045 memcpy(this->un, other.un, this->unlen);
00046 }
00047
00048 Compress::~Compress() {
00049 clear();
00050 }
00051
00052 Compress& Compress::operator=(const Compress &other) throw () {
00053 if (this != &other) {
00054 this->level = other.level;
00055 this->clen = other.clen;
00056 this->unlen = other.unlen;
00057 }
00058
00059 c = malloc(this->clen);
00060 memcpy(this->c, other.c, this->clen);
00061
00062 un = malloc(this->unlen);
00063 memcpy(this->un, other.un, this->unlen);
00064
00065 return *this;
00066 }
00067
00068 void Compress::clear(void) {
00069 SAFE_FREE(c);
00070 SAFE_FREE(un);
00071
00072 clen = 0;
00073 unlen = 0;
00074 }
00075
00076 void Compress::setLevel(int level) {
00077 this->level = level;
00078 }
00079
00080 int Compress::getLevel(void) const {
00081 return level;
00082 }
00083
00084 bool Compress::deflate(const void *uncompressed, size_t len) {
00085 bool retval = true;
00086 int ret;
00087 unsigned int avail_out;
00088 z_stream strm;
00089
00090 SAFE_FREE(c);
00091 clen = 0;
00092
00093 #ifdef DUMP
00094 printf("deflate: uncompressed(%d): 0x", len);
00095 for (int i = 0; i < len; i++) {
00096 printf("%.2x", ((unsigned char*) uncompressed)[i]);
00097 }
00098 printf("\n");
00099 #endif
00100
00101 if (uncompressed == NULL || len < 1) {
00102 return false;
00103 }
00104
00105
00106 strm.zalloc = Z_NULL;
00107 strm.zfree = Z_NULL;
00108 strm.opaque = Z_NULL;
00109
00110 if ((ret = deflateInit(&strm, level)) != Z_OK) {
00111 return false;
00112 }
00113
00114 avail_out = deflateBound(&strm, len);
00115
00116 if ((c = malloc(avail_out)) == NULL) {
00117 retval = false;
00118
00119 goto cleanup;
00120 }
00121
00122 strm.next_in = (Bytef*) uncompressed;
00123 strm.avail_in = len;
00124 strm.next_out = (Bytef*) c;
00125 strm.avail_out = avail_out;
00126
00127 if ((ret = ::deflate(&strm, Z_FINISH)) == Z_STREAM_ERROR) {
00128 retval = false;
00129
00130 goto cleanup;
00131 }
00132
00133 if (strm.avail_out == 0) {
00134 retval = false;
00135
00136 goto cleanup;
00137 }
00138
00139 clen = strm.total_out;
00140
00141 #ifdef DUMP
00142 printf("deflate: compressed(%d): 0x", clen);
00143 for (int i = 0; i < clen; i++) {
00144 printf("%.2x", ((unsigned char*) c)[i]);
00145 }
00146 printf("\n");
00147 #endif
00148
00149 cleanup:
00150 (void) deflateEnd(&strm);
00151
00152 if (!retval) {
00153 SAFE_FREE(c);
00154 clen = 0;
00155 }
00156
00157 return retval;
00158 }
00159
00160 bool Compress::inflate(const void *compressed, size_t len) {
00161 bool retval = true;
00162 int ret;
00163 unsigned int delta;
00164 z_stream strm;
00165 unsigned char buf[CHUNK];
00166 void *ptr;
00167
00168 SAFE_FREE(un);
00169 unlen = 0;
00170
00171 #ifdef DUMP
00172 printf("inflate: compressed(%d): 0x", len);
00173 for (int i = 0; i < len; i++) {
00174 printf("%.2x", ((unsigned char*) compressed)[i]);
00175 }
00176 printf("\n");
00177 #endif
00178
00179 if (compressed == NULL || len < 1) {
00180 return false;
00181 }
00182
00183
00184 strm.zalloc = Z_NULL;
00185 strm.zfree = Z_NULL;
00186 strm.opaque = Z_NULL;
00187 strm.avail_in = 0;
00188 strm.next_in = Z_NULL;
00189
00190 if ((ret = inflateInit(&strm)) != Z_OK) {
00191 return false;
00192 }
00193
00194 strm.avail_in = len;
00195 strm.next_in = (Bytef*) compressed;
00196
00197 do {
00198 strm.avail_out = CHUNK;
00199 strm.next_out = buf;
00200
00201 ret = ::inflate(&strm, Z_NO_FLUSH);
00202 if (ret != Z_OK && ret != Z_STREAM_END) {
00203 retval = false;
00204
00205 goto error;
00206 }
00207
00208
00209 un = realloc(un, strm.total_out);
00210 delta = CHUNK - strm.avail_out;
00211 ptr = (Bytef*) un + (strm.total_out - delta);
00212 memcpy(ptr, buf, delta);
00213 } while (strm.avail_out == 0);
00214
00215 error:
00216 (void) inflateEnd(&strm);
00217
00218 if (!retval) {
00219 SAFE_FREE(un);
00220 unlen = 0;
00221 }
00222
00223 return retval;
00224 }
00225
00226 const void* Compress::getCompressed(void) const {
00227 return c;
00228 }
00229
00230 const void* Compress::getUncompressed(void) const {
00231 return un;
00232 }
00233
00234 size_t Compress::getCompressedLen(void) const {
00235 return clen;
00236 }
00237
00238 size_t Compress::getUncompressedLen(void) const {
00239 return unlen;
00240 }
00241
00242
00243
00244