00001
00002
00003 #include "cheprep/DeflateOutputStreamBuffer.h"
00004
00009 namespace cheprep {
00010
00011 using namespace std;
00012
00013 unsigned long DeflateOutputStreamBuffer::crctable[] = {
00014 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
00015 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
00016 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
00017 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
00018 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
00019 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
00020 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
00021 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
00022 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
00023 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
00024 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
00025 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
00026 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
00027 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
00028 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
00029 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
00030 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
00031 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
00032 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
00033 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
00034 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
00035 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
00036 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
00037 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
00038 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
00039 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
00040 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
00041 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
00042 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
00043 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
00044 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
00045 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
00046 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
00047 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
00048 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
00049 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
00050 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
00051 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
00052 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
00053 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
00054 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
00055 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
00056 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
00057 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
00058 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
00059 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
00060 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
00061 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
00062 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
00063 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
00064 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
00065 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
00066 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
00067 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
00068 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
00069 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
00070 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
00071 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
00072 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
00073 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
00074 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
00075 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
00076 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
00077 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
00078 };
00079
00080 DeflateOutputStreamBuffer::DeflateOutputStreamBuffer(streambuf *aBuffer)
00081 : buffer(aBuffer)
00082 , crc(0)
00083 , size(0)
00084 #ifndef CHEPREP_NO_ZLIB
00085 , zStreamOpen(false)
00086 , in(inSize)
00087 , out(outSize)
00088 #endif
00089 {
00090
00091 #ifndef CHEPREP_NO_ZLIB
00092 zStream.zalloc = Z_NULL;
00093 zStream.zfree = Z_NULL;
00094 zStream.opaque = Z_NULL;
00095 #endif // CHEPREP_NO_ZLIB
00096 }
00097
00098 #ifndef CHEPREP_NO_ZLIB
00099 void DeflateOutputStreamBuffer::init(bool compress) {
00100
00101 if (compress) {
00102 if (zStreamOpen) return;
00103
00104 zStream.next_in = reinterpret_cast<unsigned char *>(&(in[0]));
00105 zStream.avail_in = 0 ;
00106
00107 zStream.next_out = reinterpret_cast<unsigned char *>(&(out[0]));
00108 zStream.avail_out = out.size();
00109
00110 if (deflateInit2(&zStream, 6, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY ) != Z_OK) {
00111 cerr << "ERROR: deflateInit2 failed" << endl;
00112 } else {
00113 zStreamOpen = true;
00114 setp(&(in[0]), &(in[0])+inSize);
00115 }
00116 }
00117 #else
00118 void DeflateOutputStreamBuffer::init(bool ) {
00119 #endif // CHEPREP_NO_ZLIB
00120
00121 crc = 0;
00122 size = 0;
00123 }
00124
00125 void DeflateOutputStreamBuffer::finish() {
00126
00127 #ifndef CHEPREP_NO_ZLIB
00128 if (zStreamOpen) {
00129
00130 overflow() ;
00131
00132 zStream.next_out = reinterpret_cast<unsigned char *>(&(out[0]));
00133 zStream.avail_out = outSize;
00134
00135 int err = Z_OK ;
00136 while ( err == Z_OK ) {
00137 if (zStream.avail_out == 0) {
00138 flushOut();
00139 }
00140 err = deflate(&zStream, Z_FINISH);
00141 }
00142
00143 flushOut() ;
00144
00145 if (err != Z_STREAM_END) {
00146 cerr << "ERROR: deflation failed" << endl;
00147 }
00148
00149 if (deflateEnd(&zStream) != Z_OK) {
00150 cerr << "ERROR: deflateEnd failed" << endl;
00151 }
00152
00153 zStreamOpen = false ;
00154 }
00155 #endif // CHEPREP_NO_ZLIB
00156 }
00157
00158 DeflateOutputStreamBuffer::~DeflateOutputStreamBuffer() {
00159 }
00160
00161
00162 #ifndef CHEPREP_NO_ZLIB
00163 #define DO1 crc = crctable[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
00164 #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
00165 #endif // CHEPREP_NO_ZLIB
00166
00167
00168 int DeflateOutputStreamBuffer::overflow(int c) {
00169
00170 #ifndef CHEPREP_NO_ZLIB
00171 if (zStreamOpen) {
00172 zStream.avail_in = pptr() - pbase() ;
00173 zStream.next_in = reinterpret_cast<unsigned char *>(&(in[0]));
00174
00175 int len = zStream.avail_in;
00176 unsigned char* buf = zStream.next_in;
00177
00178 crc = crc ^ 0xffffffffUL;
00179 while (len >= 8) {
00180 DO8;
00181 len -= 8;
00182 }
00183 if (len) do {
00184 DO1;
00185 } while (--len);
00186 crc = crc ^ 0xffffffffUL;
00187
00188 size += zStream.avail_in;
00189
00190 zStream.next_out = reinterpret_cast<unsigned char *>(&(out[0]));
00191 zStream.avail_out = outSize ;
00192
00193 int err = Z_OK ;
00194 while ((zStream.avail_in > 0 || zStream.avail_out == 0) && err == Z_OK) {
00195 if (zStream.avail_out == 0 ) {
00196 flushOut();
00197 }
00198 err = deflate(&zStream, Z_NO_FLUSH);
00199 }
00200
00201 flushOut();
00202
00203 setp(&(in[0]), &(in[0]) + inSize);
00204
00205 if ((err != Z_OK) && (err != Z_STREAM_END)) {
00206 cerr << "ERROR: deflation failed" << endl;
00207 return EOF ;
00208 }
00209
00210 if ( c != EOF ) {
00211 *pptr() = c ;
00212 pbump(1);
00213 }
00214
00215 return 0 ;
00216 } else {
00217 #endif // CHEPREP_NO_ZLIB
00218 crc = crc ^ 0xffffffffUL;
00219 crc = crctable[(crc ^ c) & 0xff] ^ (crc >> 8);
00220 crc = crc ^ 0xffffffffUL;
00221 size++;
00222 return buffer->sputc((char)c);
00223 #ifndef CHEPREP_NO_ZLIB
00224 }
00225 #endif // CHEPREP_NO_ZLIB
00226 }
00227
00228
00229 #ifndef CHEPREP_NO_ZLIB
00230 bool DeflateOutputStreamBuffer::flushOut() {
00231 int deflatedCount = outSize - zStream.avail_out;
00232 int byteCount = buffer->sputn(&(out[0]), deflatedCount);
00233
00234 zStream.next_out = reinterpret_cast<unsigned char *>(&(out[0]));
00235 zStream.avail_out = outSize ;
00236
00237 return deflatedCount == byteCount ;
00238 }
00239 #endif // CHEPREP_NO_ZLIB
00240
00241 }