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_irep = (unsigned)stream.total_out;
0056
0057 return true;
0058 }
0059
0060 inline bool decompress_buffer(std::ostream& a_out,
0061 unsigned int a_srcsize,const char* a_src,
0062 unsigned int a_tgtsize,char* a_tgt,
0063 unsigned int& a_irep) {
0064
0065 z_stream stream; // decompression stream
0066
0067 stream.next_in = (Bytef*)(a_src);
0068 stream.avail_in = (uInt)(a_srcsize);
0069 stream.next_out = (Bytef*)a_tgt;
0070 stream.avail_out = (uInt)(a_tgtsize);
0071 stream.zalloc = (alloc_func)0;
0072 stream.zfree = (free_func)0;
0073 stream.opaque = (voidpf)0;
0074 stream.total_in = 0; /*to quiet Coverity.*/
0075 stream.total_out = 0; /*to quiet Coverity.*/
0076
0077 int err = inflateInit(&stream);
0078 if (err != Z_OK) {
0079 a_out << "toolx::decompress_buffer :"
0080 << " error " << err << " in zlib/inflateInit." << std::endl;
0081 return false;
0082 }
0083
0084 err = inflate(&stream, Z_FINISH);
0085 if (err != Z_STREAM_END) {
0086 inflateEnd(&stream);
0087 a_out << "toolx::decompress_buffer :"
0088 << " error " << err << " in zlib/inflate." << std::endl;
0089 return false;
0090 }
0091
0092 inflateEnd(&stream);
0093
0094 a_irep = (unsigned)stream.total_out;
0095
0096 return true;
0097 }
0098
0099 }
0100
0101 #if ZLIB_VERNUM <= 0x1140
0102 #include <cstdio>
0103 #endif
0104
0105 namespace toolx {
0106
0107 #if ZLIB_VERNUM <= 0x1140
0108 inline int gunzip_get_byte(char*& a_buffer) {
0109 int c = *a_buffer;a_buffer++;
0110 return c;
0111 }
0112
0113 inline int gunzip_check_header(char*& a_buffer) {
0114 #define TOOLX_ZLIB_HEAD_CRC 0x02 /* bit 1 set: header CRC present */
0115 #define TOOLX_ZLIB_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
0116 #define TOOLX_ZLIB_ORIG_NAME 0x08 /* bit 3 set: original file name present */
0117 #define TOOLX_ZLIB_COMMENT 0x10 /* bit 4 set: file comment present */
0118 #define TOOLX_ZLIB_RESERVED 0xE0 /* bits 5..7: reserved */
0119
0120 uInt len;
0121 int c;
0122
0123 /* Check the gzip magic header */
0124 for (len = 0; len < 2; len++) {
0125 c = gunzip_get_byte(a_buffer);
0126 }
0127 int method = gunzip_get_byte(a_buffer);
0128 int flags = gunzip_get_byte(a_buffer);
0129 if (method != Z_DEFLATED || (flags & TOOLX_ZLIB_RESERVED) != 0) {
0130 return Z_DATA_ERROR;
0131 }
0132
0133 /* Discard time, xflags and OS code: */
0134 for (len = 0; len < 6; len++) (void)gunzip_get_byte(a_buffer);
0135
0136 if ((flags & TOOLX_ZLIB_EXTRA_FIELD) != 0) { /* skip the extra field */
0137 len = (uInt)gunzip_get_byte(a_buffer);
0138 len += ((uInt)gunzip_get_byte(a_buffer))<<8;
0139 /* len is garbage if EOF but the loop below will quit anyway */
0140 while (len-- != 0 && gunzip_get_byte(a_buffer) != EOF) ;
0141 }
0142 if ((flags & TOOLX_ZLIB_ORIG_NAME) != 0) { /* skip the original file name */
0143 while ((c = gunzip_get_byte(a_buffer)) != 0 && c != EOF) ;
0144 }
0145 if ((flags & TOOLX_ZLIB_COMMENT) != 0) { /* skip the .gz file comment */
0146 while ((c = gunzip_get_byte(a_buffer)) != 0 && c != EOF) ;
0147 }
0148 if ((flags & TOOLX_ZLIB_HEAD_CRC) != 0) { /* skip the header crc */
0149 for (len = 0; len < 2; len++) (void)gunzip_get_byte(a_buffer);
0150 }
0151 //s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
0152 return Z_OK;
0153
0154 #undef TOOLX_ZLIB_HEAD_CRC
0155 #undef TOOLX_ZLIB_EXTRA_FIELD
0156 #undef TOOLX_ZLIB_ORIG_NAME
0157 #undef TOOLX_ZLIB_COMMENT
0158 #undef TOOLX_ZLIB_RESERVED
0159 }
0160 #endif //ZLIB_VERNUM <= 0x1140
0161
0162 inline bool gunzip_buffer(std::ostream& a_out,
0163 unsigned int a_srcsize,const char* a_src,
0164 unsigned int a_tgtsize,char* a_tgt,
0165 unsigned int& a_irep) {
0166
0167 z_stream stream; // decompression stream
0168
0169 #if ZLIB_VERNUM <= 0x1140
0170 char* pos = (char*)a_src;
0171 if(gunzip_check_header(pos)!=Z_OK) return false;
0172 stream.next_in = (Bytef*)pos;
0173 stream.avail_in = (uInt)(a_srcsize-(pos-a_src));
0174 #else
0175 stream.next_in = (Bytef*)a_src;
0176 stream.avail_in = (uInt)a_srcsize;
0177 #endif //ZLIB_VERNUM
0178
0179 stream.next_out = (Bytef*)a_tgt;
0180 stream.avail_out = (uInt)a_tgtsize;
0181 stream.zalloc = (alloc_func)0;
0182 stream.zfree = (free_func)0;
0183 stream.opaque = (voidpf)0;
0184
0185 #if ZLIB_VERNUM <= 0x1140
0186 int err = inflateInit2(&stream,-MAX_WBITS);
0187 #else
0188 int err = inflateInit2(&stream,MAX_WBITS+16);
0189 #endif
0190 if (err != Z_OK) {
0191 a_out << "toolx::gunzip_buffer :"
0192 << " error " << err << " in zlib/inflateInit2." << std::endl;
0193 return false;
0194 }
0195
0196 err = inflate(&stream, Z_FINISH);
0197 if (err != Z_STREAM_END) {
0198 inflateEnd(&stream);
0199 a_out << "toolx::gunzip_buffer :"
0200 << " error " << err << " in zlib/inflate." << std::endl;
0201 return false;
0202 }
0203
0204 inflateEnd(&stream);
0205
0206 a_irep = (unsigned)stream.total_out;
0207
0208 return true;
0209 }
0210
0211 }
0212
0213 #endif