Botan
1.11.15
|
00001 /* 00002 * Zlib Compressor 00003 * (C) 2001 Peter J Jones 00004 * 2001-2007,2014 Jack Lloyd 00005 * 2006 Matt Johnston 00006 * 00007 * Botan is released under the Simplified BSD License (see license.txt) 00008 */ 00009 00010 #include <botan/zlib.h> 00011 #include <botan/internal/compress_utils.h> 00012 #include <ctime> 00013 #include <zlib.h> 00014 00015 namespace Botan { 00016 00017 BOTAN_REGISTER_COMPRESSION(Zlib_Compression, Zlib_Decompression); 00018 BOTAN_REGISTER_COMPRESSION(Gzip_Compression, Gzip_Decompression); 00019 BOTAN_REGISTER_COMPRESSION(Deflate_Compression, Deflate_Decompression); 00020 00021 namespace { 00022 00023 class Zlib_Stream : public Zlib_Style_Stream<z_stream, Bytef> 00024 { 00025 public: 00026 Zlib_Stream() 00027 { 00028 streamp()->opaque = alloc(); 00029 streamp()->zalloc = Compression_Alloc_Info::malloc<unsigned int>; 00030 streamp()->zfree = Compression_Alloc_Info::free; 00031 } 00032 00033 u32bit run_flag() const override { return Z_NO_FLUSH; } 00034 u32bit flush_flag() const override { return Z_FULL_FLUSH; } 00035 u32bit finish_flag() const override { return Z_FINISH; } 00036 00037 int compute_window_bits(int wbits, int wbits_offset) const 00038 { 00039 if(wbits_offset == -1) 00040 return -wbits; 00041 else 00042 return wbits + wbits_offset; 00043 } 00044 }; 00045 00046 class Zlib_Compression_Stream : public Zlib_Stream 00047 { 00048 public: 00049 Zlib_Compression_Stream(size_t level, int wbits, int wbits_offset = 0) 00050 { 00051 wbits = compute_window_bits(wbits, wbits_offset); 00052 00053 int rc = deflateInit2(streamp(), level, Z_DEFLATED, wbits, 00054 8, Z_DEFAULT_STRATEGY); 00055 if(rc != Z_OK) 00056 throw std::runtime_error("zlib deflate initialization failed"); 00057 } 00058 00059 ~Zlib_Compression_Stream() 00060 { 00061 deflateEnd(streamp()); 00062 } 00063 00064 bool run(u32bit flags) override 00065 { 00066 int rc = deflate(streamp(), flags); 00067 00068 if(rc == Z_MEM_ERROR) 00069 throw std::bad_alloc(); 00070 else if(rc != Z_OK && rc != Z_STREAM_END) 00071 throw std::runtime_error("zlib deflate error"); 00072 00073 return (rc == Z_STREAM_END); 00074 } 00075 }; 00076 00077 class Zlib_Decompression_Stream : public Zlib_Stream 00078 { 00079 public: 00080 Zlib_Decompression_Stream(int wbits, int wbits_offset = 0) 00081 { 00082 int rc = inflateInit2(streamp(), compute_window_bits(wbits, wbits_offset)); 00083 00084 if(rc == Z_MEM_ERROR) 00085 throw std::bad_alloc(); 00086 else if(rc != Z_OK) 00087 throw std::runtime_error("zlib inflate initialization failed"); 00088 } 00089 00090 ~Zlib_Decompression_Stream() 00091 { 00092 inflateEnd(streamp()); 00093 } 00094 00095 bool run(u32bit flags) override 00096 { 00097 int rc = inflate(streamp(), flags); 00098 00099 if(rc == Z_MEM_ERROR) 00100 throw std::bad_alloc(); 00101 else if(rc != Z_OK && rc != Z_STREAM_END) 00102 throw std::runtime_error("zlib deflate error"); 00103 00104 return (rc == Z_STREAM_END); 00105 } 00106 }; 00107 00108 class Deflate_Compression_Stream : public Zlib_Compression_Stream 00109 { 00110 public: 00111 Deflate_Compression_Stream(size_t level, int wbits) : 00112 Zlib_Compression_Stream(level, wbits, -1) {} 00113 }; 00114 00115 class Deflate_Decompression_Stream : public Zlib_Decompression_Stream 00116 { 00117 public: 00118 Deflate_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, -1) {} 00119 }; 00120 00121 class Gzip_Compression_Stream : public Zlib_Compression_Stream 00122 { 00123 public: 00124 Gzip_Compression_Stream(size_t level, int wbits, byte os_code) : 00125 Zlib_Compression_Stream(level, wbits, 16) 00126 { 00127 clear_mem(&m_header, 1); 00128 m_header.os = os_code; 00129 m_header.time = std::time(nullptr); 00130 00131 int rc = deflateSetHeader(streamp(), &m_header); 00132 if(rc != Z_OK) 00133 throw std::runtime_error("setting gzip header failed"); 00134 } 00135 00136 private: 00137 ::gz_header m_header; 00138 }; 00139 00140 class Gzip_Decompression_Stream : public Zlib_Decompression_Stream 00141 { 00142 public: 00143 Gzip_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, 16) {} 00144 }; 00145 00146 } 00147 00148 Compression_Stream* Zlib_Compression::make_stream() const 00149 { 00150 return new Zlib_Compression_Stream(m_level, 15); 00151 } 00152 00153 Compression_Stream* Zlib_Decompression::make_stream() const 00154 { 00155 return new Zlib_Decompression_Stream(15); 00156 } 00157 00158 Compression_Stream* Deflate_Compression::make_stream() const 00159 { 00160 return new Deflate_Compression_Stream(m_level, 15); 00161 } 00162 00163 Compression_Stream* Deflate_Decompression::make_stream() const 00164 { 00165 return new Deflate_Decompression_Stream(15); 00166 } 00167 00168 Compression_Stream* Gzip_Compression::make_stream() const 00169 { 00170 return new Gzip_Compression_Stream(m_level, 15, m_os_code); 00171 } 00172 00173 Compression_Stream* Gzip_Decompression::make_stream() const 00174 { 00175 return new Gzip_Decompression_Stream(15); 00176 } 00177 00178 }