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