1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2 // (C) Copyright 2003-2007 Jonathan Turkanis
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
5
6 // See http://www.boost.org/libs/iostreams for documentation.
7
8 // To configure Boost to work with zlib, see the
9 // installation instructions here:
10 // http://boost.org/libs/iostreams/doc/index.html?path=7
11
12 // Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp>
13 // knows that we are building the library (possibly exporting code), rather
14 // than using it (possibly importing code).
15 #define BOOST_IOSTREAMS_SOURCE
16
17 #include <boost/throw_exception.hpp>
18 #include <boost/iostreams/detail/config/dyn_link.hpp>
19 #include <boost/iostreams/filter/zlib.hpp>
20 #include "zlib.h" // Jean-loup Gailly's and Mark Adler's "zlib.h" header.
21 // To configure Boost to work with zlib, see the
22 // installation instructions here:
23 // http://boost.org/libs/iostreams/doc/index.html?path=7
24
25 namespace boost { namespace iostreams {
26
27 namespace zlib {
28
29 // Compression levels
30
31 const int no_compression = Z_NO_COMPRESSION;
32 const int best_speed = Z_BEST_SPEED;
33 const int best_compression = Z_BEST_COMPRESSION;
34 const int default_compression = Z_DEFAULT_COMPRESSION;
35
36 // Compression methods
37
38 const int deflated = Z_DEFLATED;
39
40 // Compression strategies
41
42 const int default_strategy = Z_DEFAULT_STRATEGY;
43 const int filtered = Z_FILTERED;
44 const int huffman_only = Z_HUFFMAN_ONLY;
45
46 // Status codes
47
48 const int okay = Z_OK;
49 const int stream_end = Z_STREAM_END;
50 const int stream_error = Z_STREAM_ERROR;
51 const int version_error = Z_VERSION_ERROR;
52 const int data_error = Z_DATA_ERROR;
53 const int mem_error = Z_MEM_ERROR;
54 const int buf_error = Z_BUF_ERROR;
55
56 // Flush codes
57
58 const int finish = Z_FINISH;
59 const int no_flush = Z_NO_FLUSH;
60 const int sync_flush = Z_SYNC_FLUSH;
61
62 // Code for current OS
63
64 //const int os_code = OS_CODE;
65
66 } // End namespace zlib.
67
68 //------------------Implementation of zlib_error------------------------------//
69
zlib_error(int error)70 zlib_error::zlib_error(int error)
71 : BOOST_IOSTREAMS_FAILURE("zlib error"), error_(error)
72 { }
73
BOOST_PREVENT_MACRO_SUBSTITUTION(int error)74 void zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(int error)
75 {
76 switch (error) {
77 case Z_OK:
78 case Z_STREAM_END:
79 //case Z_BUF_ERROR:
80 return;
81 case Z_MEM_ERROR:
82 boost::throw_exception(std::bad_alloc());
83 default:
84 boost::throw_exception(zlib_error(error));
85 ;
86 }
87 }
88
89 //------------------Implementation of zlib_base-------------------------------//
90
91 namespace detail {
92
zlib_base()93 zlib_base::zlib_base()
94 : stream_(new z_stream), calculate_crc_(false), crc_(0), crc_imp_(0),
95 total_in_(0), total_out_(0)
96 { }
97
~zlib_base()98 zlib_base::~zlib_base() { delete static_cast<z_stream*>(stream_); }
99
before(const char * & src_begin,const char * src_end,char * & dest_begin,char * dest_end)100 void zlib_base::before( const char*& src_begin, const char* src_end,
101 char*& dest_begin, char* dest_end )
102 {
103 z_stream* s = static_cast<z_stream*>(stream_);
104 s->next_in = reinterpret_cast<zlib::byte*>(const_cast<char*>(src_begin));
105 s->avail_in = static_cast<zlib::uint>(src_end - src_begin);
106 s->next_out = reinterpret_cast<zlib::byte*>(dest_begin);
107 s->avail_out= static_cast<zlib::uint>(dest_end - dest_begin);
108 }
109
after(const char * & src_begin,char * & dest_begin,bool compress)110 void zlib_base::after(const char*& src_begin, char*& dest_begin, bool compress)
111 {
112 z_stream* s = static_cast<z_stream*>(stream_);
113 const char* next_in = reinterpret_cast<const char*>(s->next_in);
114 char* next_out = reinterpret_cast<char*>(s->next_out);
115 if (calculate_crc_) {
116 const zlib::byte* buf = compress ?
117 reinterpret_cast<const zlib::byte*>(src_begin) :
118 reinterpret_cast<const zlib::byte*>(
119 const_cast<const char*>(dest_begin)
120 );
121 zlib::uint length = compress ?
122 static_cast<zlib::uint>(next_in - src_begin) :
123 static_cast<zlib::uint>(next_out - dest_begin);
124 crc_ = crc_imp_ = crc32(crc_imp_, buf, length);
125 }
126 total_in_ = s->total_in;
127 total_out_ = s->total_out;
128 src_begin = next_in;
129 dest_begin = next_out;
130 }
131
xdeflate(int flush)132 int zlib_base::xdeflate(int flush)
133 {
134 return ::deflate(static_cast<z_stream*>(stream_), flush);
135 }
136
xinflate(int flush)137 int zlib_base::xinflate(int flush)
138 {
139 return ::inflate(static_cast<z_stream*>(stream_), flush);
140 }
141
reset(bool compress,bool realloc)142 void zlib_base::reset(bool compress, bool realloc)
143 {
144 z_stream* s = static_cast<z_stream*>(stream_);
145 // Undiagnosed bug:
146 // deflateReset(), etc., return Z_DATA_ERROR
147 //zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(
148 realloc ?
149 (compress ? deflateReset(s) : inflateReset(s)) :
150 (compress ? deflateEnd(s) : inflateEnd(s))
151 ;
152 //);
153 crc_imp_ = 0;
154 }
155
do_init(const zlib_params & p,bool compress,zlib::xalloc_func,zlib::xfree_func,void * derived)156 void zlib_base::do_init
157 ( const zlib_params& p, bool compress,
158 zlib::xalloc_func /* alloc */, zlib::xfree_func /* free*/,
159 void* derived )
160 {
161 calculate_crc_ = p.calculate_crc;
162 z_stream* s = static_cast<z_stream*>(stream_);
163
164 // Current interface for customizing memory management
165 // is non-conforming and has been disabled:
166 // s->zalloc = alloc;
167 // s->zfree = free;
168 s->zalloc = 0;
169 s->zfree = 0;
170 s->opaque = derived;
171 int window_bits = p.noheader? -p.window_bits : p.window_bits;
172 zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(
173 compress ?
174 deflateInit2( s,
175 p.level,
176 p.method,
177 window_bits,
178 p.mem_level,
179 p.strategy ) :
180 inflateInit2(s, window_bits)
181 );
182 }
183
184 } // End namespace detail.
185
186 //----------------------------------------------------------------------------//
187
188 } } // End namespaces iostreams, boost.
189