Warning, /include/Geant4/toolx/zlib is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef toolx_zlib
0005 #define toolx_zlib
0006
0007 // what is needed for root file compression with zlib.
0008
0009 //NOTE : zlib contains deflate/inflate and also the gz functions to write/read a .gz file.
0010 // The gz functions use also deflate/inflate.
0011
0012 #include <zlib.h>
0013
0014 #include <ostream>
0015
0016 namespace toolx {
0017
0018 inline bool compress_buffer(std::ostream& a_out,
0019 unsigned int a_level,
0020 unsigned int a_srcsize,const char* a_src,
0021 unsigned int a_tgtsize,char* a_tgt,
0022 unsigned int& a_irep) {
0023
0024 z_stream stream; // decompression stream
0025
0026 stream.next_in = (Bytef*)(a_src);
0027 stream.avail_in = (uInt)(a_srcsize);
0028 stream.next_out = (Bytef*)a_tgt;
0029 stream.avail_out = (uInt)(a_tgtsize);
0030 stream.zalloc = (alloc_func)0;
0031 stream.zfree = (free_func)0;
0032 stream.opaque = (voidpf)0;
0033 stream.total_in = 0; /*to quiet Coverity.*/
0034 stream.total_out = 0; /*to quiet Coverity.*/
0035
0036 int err = deflateInit(&stream,a_level);
0037 if(err!=Z_OK) {
0038 a_out << "toolx::compress_buffer :"
0039 << " error in zlib/deflateInit." << std::endl;
0040 a_irep = 0;
0041 return false;
0042 }
0043
0044 err = deflate(&stream, Z_FINISH);
0045 if(err!=Z_STREAM_END) {
0046 deflateEnd(&stream);
0047 a_out << "toolx::compress_buffer :"
0048 << " error in zlib/deflate." << std::endl;
0049 a_irep = 0;
0050 return false;
0051 }
0052
0053 deflateEnd(&stream);
0054
0055 //a_out << "toolx::compress_buffer : ok "
0056 // << stream.total_out << std::endl;
0057
0058 a_irep = (unsigned)stream.total_out;
0059
0060 return true;
0061 }
0062
0063 inline bool decompress_buffer(std::ostream& a_out,
0064 unsigned int a_srcsize,const char* a_src,
0065 unsigned int a_tgtsize,char* a_tgt,
0066 unsigned int& a_irep) {
0067
0068 z_stream stream; // decompression stream
0069
0070 stream.next_in = (Bytef*)(a_src);
0071 stream.avail_in = (uInt)(a_srcsize);
0072 stream.next_out = (Bytef*)a_tgt;
0073 stream.avail_out = (uInt)(a_tgtsize);
0074 stream.zalloc = (alloc_func)0;
0075 stream.zfree = (free_func)0;
0076 stream.opaque = (voidpf)0;
0077 stream.total_in = 0; /*to quiet Coverity.*/
0078 stream.total_out = 0; /*to quiet Coverity.*/
0079
0080 int err = inflateInit(&stream);
0081 if (err != Z_OK) {
0082 a_out << "toolx::decompress_buffer :"
0083 << " error " << err << " in zlib/inflateInit." << std::endl;
0084 return false;
0085 }
0086
0087 err = inflate(&stream, Z_FINISH);
0088 if (err != Z_STREAM_END) {
0089 inflateEnd(&stream);
0090 a_out << "toolx::decompress_buffer :"
0091 << " error " << err << " in zlib/inflate." << std::endl;
0092 return false;
0093 }
0094
0095 inflateEnd(&stream);
0096
0097 //a_out << "toolx::decompress_buffer : zlib : ok "
0098 // << stream.total_out << std::endl;
0099
0100 a_irep = (unsigned)stream.total_out;
0101
0102 return true;
0103 }
0104
0105 }
0106
0107 #if ZLIB_VERNUM <= 0x1140
0108 #include <cstdio>
0109 #endif
0110
0111 namespace toolx {
0112
0113 #if ZLIB_VERNUM <= 0x1140
0114 inline int gunzip_get_byte(char*& a_buffer) {
0115 int c = *a_buffer;a_buffer++;
0116 return c;
0117 }
0118
0119 inline int gunzip_check_header(char*& a_buffer) {
0120 #define TOOLX_ZLIB_HEAD_CRC 0x02 /* bit 1 set: header CRC present */
0121 #define TOOLX_ZLIB_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
0122 #define TOOLX_ZLIB_ORIG_NAME 0x08 /* bit 3 set: original file name present */
0123 #define TOOLX_ZLIB_COMMENT 0x10 /* bit 4 set: file comment present */
0124 #define TOOLX_ZLIB_RESERVED 0xE0 /* bits 5..7: reserved */
0125
0126 uInt len;
0127 int c;
0128
0129 /* Check the gzip magic header */
0130 for (len = 0; len < 2; len++) {
0131 c = gunzip_get_byte(a_buffer);
0132 /*
0133 if (c != gz_magic[len]) {
0134 if (len != 0) s->stream.avail_in++, s->stream.next_in--;
0135 if (c != EOF) {
0136 s->stream.avail_in++, s->stream.next_in--;
0137 s->transparent = 1;
0138 }
0139 s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
0140 return;
0141 }
0142 */
0143 }
0144 int method = gunzip_get_byte(a_buffer);
0145 int flags = gunzip_get_byte(a_buffer);
0146 if (method != Z_DEFLATED || (flags & TOOLX_ZLIB_RESERVED) != 0) {
0147 return Z_DATA_ERROR;
0148 }
0149
0150 /* Discard time, xflags and OS code: */
0151 for (len = 0; len < 6; len++) (void)gunzip_get_byte(a_buffer);
0152
0153 if ((flags & TOOLX_ZLIB_EXTRA_FIELD) != 0) { /* skip the extra field */
0154 len = (uInt)gunzip_get_byte(a_buffer);
0155 len += ((uInt)gunzip_get_byte(a_buffer))<<8;
0156 /* len is garbage if EOF but the loop below will quit anyway */
0157 while (len-- != 0 && gunzip_get_byte(a_buffer) != EOF) ;
0158 }
0159 if ((flags & TOOLX_ZLIB_ORIG_NAME) != 0) { /* skip the original file name */
0160 while ((c = gunzip_get_byte(a_buffer)) != 0 && c != EOF) ;
0161 }
0162 if ((flags & TOOLX_ZLIB_COMMENT) != 0) { /* skip the .gz file comment */
0163 while ((c = gunzip_get_byte(a_buffer)) != 0 && c != EOF) ;
0164 }
0165 if ((flags & TOOLX_ZLIB_HEAD_CRC) != 0) { /* skip the header crc */
0166 for (len = 0; len < 2; len++) (void)gunzip_get_byte(a_buffer);
0167 }
0168 //s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
0169 return Z_OK;
0170
0171 #undef TOOLX_ZLIB_HEAD_CRC
0172 #undef TOOLX_ZLIB_EXTRA_FIELD
0173 #undef TOOLX_ZLIB_ORIG_NAME
0174 #undef TOOLX_ZLIB_COMMENT
0175 #undef TOOLX_ZLIB_RESERVED
0176 }
0177 #endif //ZLIB_VERNUM <= 0x1140
0178
0179 inline bool gunzip_buffer(std::ostream& a_out,
0180 unsigned int a_srcsize,const char* a_src,
0181 unsigned int a_tgtsize,char* a_tgt,
0182 unsigned int& a_irep) {
0183
0184 z_stream stream; // decompression stream
0185
0186 #if ZLIB_VERNUM <= 0x1140
0187 char* pos = (char*)a_src;
0188 if(gunzip_check_header(pos)!=Z_OK) return false;
0189 stream.next_in = (Bytef*)pos;
0190 stream.avail_in = (uInt)(a_srcsize-(pos-a_src));
0191 #else
0192 stream.next_in = (Bytef*)a_src;
0193 stream.avail_in = (uInt)a_srcsize;
0194 #endif //ZLIB_VERNUM
0195
0196 stream.next_out = (Bytef*)a_tgt;
0197 stream.avail_out = (uInt)a_tgtsize;
0198 stream.zalloc = (alloc_func)0;
0199 stream.zfree = (free_func)0;
0200 stream.opaque = (voidpf)0;
0201
0202 #if ZLIB_VERNUM <= 0x1140
0203 int err = inflateInit2(&stream,-MAX_WBITS);
0204 #else
0205 int err = inflateInit2(&stream,MAX_WBITS+16);
0206 #endif
0207 if (err != Z_OK) {
0208 a_out << "toolx::gunzip_buffer :"
0209 << " error " << err << " in zlib/inflateInit2." << std::endl;
0210 return false;
0211 }
0212
0213 err = inflate(&stream, Z_FINISH);
0214 if (err != Z_STREAM_END) {
0215 inflateEnd(&stream);
0216 a_out << "toolx::gunzip_buffer :"
0217 << " error " << err << " in zlib/inflate." << std::endl;
0218 return false;
0219 }
0220
0221 inflateEnd(&stream);
0222
0223 a_irep = (unsigned)stream.total_out;
0224
0225 return true;
0226 }
0227
0228 }
0229
0230 #endif