summaryrefslogtreecommitdiff
path: root/boost/iostreams/filter/gzip.hpp
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
commit1a78a62555be32868418fe52f8e330c9d0f95d5a (patch)
treed3765a80e7d3b9640ec2e930743630cd6b9fce2b /boost/iostreams/filter/gzip.hpp
downloadboost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'boost/iostreams/filter/gzip.hpp')
-rw-r--r--boost/iostreams/filter/gzip.hpp757
1 files changed, 757 insertions, 0 deletions
diff --git a/boost/iostreams/filter/gzip.hpp b/boost/iostreams/filter/gzip.hpp
new file mode 100644
index 0000000000..0f483b4463
--- /dev/null
+++ b/boost/iostreams/filter/gzip.hpp
@@ -0,0 +1,757 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains the definitions of the class templates gzip_compressor and
+// gzip_decompressor for reading and writing files in the gzip file format
+// (RFC 1952). Based in part on work of Jonathan de Halleux; see [...]
+
+#ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED
+#define BOOST_IOSTREAMS_GZIP_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/config.hpp> // STATIC_CONSTANT, STDC_NAMESPACE,
+ // DINKUMWARE_STDLIB, __STL_CONFIG_H.
+#include <algorithm> // min.
+#include <boost/assert.hpp>
+#include <cstdio> // EOF.
+#include <cstddef> // size_t.
+#include <ctime> // std::time_t.
+#include <memory> // allocator.
+#include <boost/config.hpp> // Put size_t in std.
+#include <boost/detail/workaround.hpp>
+#include <boost/cstdint.hpp> // uint8_t, uint32_t.
+#include <boost/iostreams/constants.hpp> // buffer size.
+#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
+#include <boost/iostreams/detail/adapter/range_adapter.hpp>
+#include <boost/iostreams/detail/char_traits.hpp>
+#include <boost/iostreams/detail/ios.hpp> // failure.
+#include <boost/iostreams/detail/error.hpp>
+#include <boost/iostreams/operations.hpp>
+#include <boost/iostreams/device/back_inserter.hpp>
+#include <boost/iostreams/filter/zlib.hpp>
+#include <boost/iostreams/pipeline.hpp>
+#include <boost/iostreams/putback.hpp>
+#include <boost/throw_exception.hpp>
+
+// Must come last.
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4309) // Truncation of constant value.
+#endif
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std { using ::time_t; }
+#endif
+
+namespace boost { namespace iostreams {
+
+//------------------Definitions of constants----------------------------------//
+
+namespace gzip {
+
+using namespace boost::iostreams::zlib;
+
+ // Error codes used by gzip_error.
+
+const int zlib_error = 1;
+const int bad_crc = 2; // Recorded crc doesn't match data.
+const int bad_length = 3; // Recorded length doesn't match data.
+const int bad_header = 4; // Malformed header.
+const int bad_footer = 5; // Malformed footer.
+const int bad_method = 6; // Unsupported compression method.
+
+namespace magic {
+
+ // Magic numbers used by gzip header.
+
+const int id1 = 0x1f;
+const int id2 = 0x8b;
+
+} // End namespace magic.
+
+namespace method {
+
+ // Codes used for the 'CM' byte of the gzip header.
+
+const int deflate = 8;
+
+} // End namespace method.
+
+namespace flags {
+
+ // Codes used for the 'FLG' byte of the gzip header.
+
+const int text = 1;
+const int header_crc = 2;
+const int extra = 4;
+const int name = 8;
+const int comment = 16;
+
+} // End namespace flags.
+
+namespace extra_flags {
+
+ // Codes used for the 'XFL' byte of the gzip header.
+
+const int best_compression = 2;
+const int best_speed = 4;
+
+} // End namespace extra_flags.
+
+ // Codes used for the 'OS' byte of the gzip header.
+
+const int os_fat = 0;
+const int os_amiga = 1;
+const int os_vms = 2;
+const int os_unix = 3;
+const int os_vm_cms = 4;
+const int os_atari = 5;
+const int os_hpfs = 6;
+const int os_macintosh = 7;
+const int os_z_system = 8;
+const int os_cp_m = 9;
+const int os_tops_20 = 10;
+const int os_ntfs = 11;
+const int os_qdos = 12;
+const int os_acorn = 13;
+const int os_unknown = 255;
+
+} // End namespace gzip.
+
+//------------------Definition of gzip_params---------------------------------//
+
+//
+// Class name: gzip_params.
+// Description: Subclass of zlib_params with an additional field
+// representing a file name.
+//
+struct gzip_params : zlib_params {
+
+ // Non-explicit constructor.
+ gzip_params( int level = gzip::default_compression,
+ int method = gzip::deflated,
+ int window_bits = gzip::default_window_bits,
+ int mem_level = gzip::default_mem_level,
+ int strategy = gzip::default_strategy,
+ std::string file_name = "",
+ std::string comment = "",
+ std::time_t mtime = 0 )
+ : zlib_params(level, method, window_bits, mem_level, strategy),
+ file_name(file_name), comment(comment), mtime(mtime)
+ { }
+ std::string file_name;
+ std::string comment;
+ std::time_t mtime;
+};
+
+//------------------Definition of gzip_error----------------------------------//
+
+//
+// Class name: gzip_error.
+// Description: Subclass of std::ios_base::failure thrown to indicate
+// zlib errors other than out-of-memory conditions.
+//
+class gzip_error : public BOOST_IOSTREAMS_FAILURE {
+public:
+ explicit gzip_error(int error)
+ : BOOST_IOSTREAMS_FAILURE("gzip error"),
+ error_(error), zlib_error_code_(zlib::okay) { }
+ explicit gzip_error(const zlib_error& e)
+ : BOOST_IOSTREAMS_FAILURE("gzip error"),
+ error_(gzip::zlib_error), zlib_error_code_(e.error())
+ { }
+ int error() const { return error_; }
+ int zlib_error_code() const { return zlib_error_code_; }
+private:
+ int error_;
+ int zlib_error_code_;
+};
+
+//------------------Definition of gzip_compressor-----------------------------//
+
+//
+// Template name: gzip_compressor
+// Description: Model of OutputFilter implementing compression in the
+// gzip format.
+//
+template<typename Alloc = std::allocator<char> >
+class basic_gzip_compressor : basic_zlib_compressor<Alloc> {
+private:
+ typedef basic_zlib_compressor<Alloc> base_type;
+public:
+ typedef char char_type;
+ struct category
+ : dual_use,
+ filter_tag,
+ multichar_tag,
+ closable_tag
+ { };
+ basic_gzip_compressor( const gzip_params& = gzip::default_compression,
+ int buffer_size = default_device_buffer_size );
+
+ template<typename Source>
+ std::streamsize read(Source& src, char_type* s, std::streamsize n)
+ {
+ std::streamsize result = 0;
+
+ // Read header.
+ if (!(flags_ & f_header_done))
+ result += read_string(s, n, header_);
+
+ // Read body.
+ if (!(flags_ & f_body_done)) {
+
+ // Read from basic_zlib_filter.
+ std::streamsize amt = base_type::read(src, s + result, n - result);
+ if (amt != -1) {
+ result += amt;
+ if (amt < n - result) { // Double-check for EOF.
+ amt = base_type::read(src, s + result, n - result);
+ if (amt != -1)
+ result += amt;
+ }
+ }
+ if (amt == -1)
+ prepare_footer();
+ }
+
+ // Read footer.
+ if ((flags_ & f_body_done) != 0 && result < n)
+ result += read_string(s + result, n - result, footer_);
+
+ return result != 0 ? result : -1;
+ }
+
+ template<typename Sink>
+ std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+ {
+ if (!(flags_ & f_header_done)) {
+ std::streamsize amt =
+ static_cast<std::streamsize>(header_.size() - offset_);
+ offset_ += boost::iostreams::write(snk, header_.data() + offset_, amt);
+ if (offset_ == header_.size())
+ flags_ |= f_header_done;
+ else
+ return 0;
+ }
+ return base_type::write(snk, s, n);
+ }
+
+ template<typename Sink>
+ void close(Sink& snk, BOOST_IOS::openmode m)
+ {
+ try {
+ // Close zlib compressor.
+ base_type::close(snk, m);
+
+ if (m == BOOST_IOS::out) {
+ if (flags_ & f_header_done) {
+
+ // Write final fields of gzip file format.
+ write_long(this->crc(), snk);
+ write_long(this->total_in(), snk);
+ }
+ }
+ } catch(...) {
+ close_impl();
+ throw;
+ }
+ close_impl();
+ }
+private:
+ static gzip_params normalize_params(gzip_params p);
+ void prepare_footer();
+ std::streamsize read_string(char* s, std::streamsize n, std::string& str);
+
+ template<typename Sink>
+ static void write_long(long n, Sink& next, boost::mpl::true_)
+ {
+ boost::iostreams::put(next, static_cast<char>(0xFF & n));
+ boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 8)));
+ boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 16)));
+ boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 24)));
+ }
+ template<typename Sink>
+ static void write_long(long n, Sink& next, boost::mpl::false_)
+ {
+ }
+ template<typename Sink>
+ static void write_long(long n, Sink& next)
+ {
+ typedef typename category_of<Sink>::type category;
+ typedef is_convertible<category, output> can_write;
+ write_long(n, next, can_write());
+ }
+
+ void close_impl()
+ {
+ #if BOOST_WORKAROUND(__GNUC__, == 2) && defined(__STL_CONFIG_H) || \
+ BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) \
+ /**/
+ footer_.erase(0, std::string::npos);
+ #else
+ footer_.clear();
+ #endif
+ offset_ = 0;
+ flags_ = 0;
+ }
+
+ enum state_type {
+ f_header_done = 1,
+ f_body_done = f_header_done << 1,
+ f_footer_done = f_body_done << 1
+ };
+ std::string header_;
+ std::string footer_;
+ std::size_t offset_;
+ int flags_;
+};
+BOOST_IOSTREAMS_PIPABLE(basic_gzip_compressor, 1)
+
+typedef basic_gzip_compressor<> gzip_compressor;
+
+//------------------Definition of helper templates for decompression----------//
+
+namespace detail {
+
+// Processes gzip headers
+class BOOST_IOSTREAMS_DECL gzip_header {
+public:
+ gzip_header() { reset(); }
+
+ // Members for processing header data
+ void process(char c);
+ bool done() const { return state_ == s_done; }
+ void reset();
+
+ // Members for accessing header data
+ std::string file_name() const { return file_name_; }
+ std::string comment() const { return comment_; }
+ bool text() const { return (flags_ & gzip::flags::text) != 0; }
+ int os() const { return os_; }
+ std::time_t mtime() const { return mtime_; }
+private:
+ enum state_type {
+ s_id1 = 1,
+ s_id2 = s_id1 + 1,
+ s_cm = s_id2 + 1,
+ s_flg = s_cm + 1,
+ s_mtime = s_flg + 1,
+ s_xfl = s_mtime + 1,
+ s_os = s_xfl + 1,
+ s_xlen = s_os + 1,
+ s_extra = s_xlen + 1,
+ s_name = s_extra + 1,
+ s_comment = s_name + 1,
+ s_hcrc = s_comment + 1,
+ s_done = s_hcrc + 1
+ };
+ std::string file_name_;
+ std::string comment_;
+ int os_;
+ std::time_t mtime_;
+ int flags_;
+ int state_;
+ int offset_; // Offset within fixed-length region.
+ int xlen_; // Bytes remaining in extra field.
+};
+
+// Processes gzip footers
+class BOOST_IOSTREAMS_DECL gzip_footer {
+public:
+ gzip_footer() { reset(); }
+
+ // Members for processing footer data
+ void process(char c);
+ bool done() const { return state_ == s_done; }
+ void reset();
+
+ // Members for accessing footer data
+ zlib::ulong crc() const { return crc_; }
+ zlib::ulong uncompressed_size() const { return isize_; }
+private:
+ enum state_type {
+ s_crc = 1,
+ s_isize = s_crc + 1,
+ s_done = s_isize + 1
+ };
+ zlib::ulong crc_;
+ zlib::ulong isize_;
+ int state_;
+ int offset_;
+};
+
+} // End namespace boost::iostreams::detail.
+
+//------------------Definition of basic_gzip_decompressor---------------------//
+
+//
+// Template name: basic_gzip_decompressor
+// Description: Model of InputFilter implementing compression in the
+// gzip format.
+//
+template<typename Alloc = std::allocator<char> >
+class basic_gzip_decompressor : basic_zlib_decompressor<Alloc> {
+private:
+ typedef basic_zlib_decompressor<Alloc> base_type;
+ typedef typename base_type::string_type string_type;
+public:
+ typedef char char_type;
+ struct category
+ : dual_use,
+ filter_tag,
+ multichar_tag,
+ closable_tag
+ { };
+ basic_gzip_decompressor( int window_bits = gzip::default_window_bits,
+ int buffer_size = default_device_buffer_size );
+
+ template<typename Sink>
+ std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+ {
+ std::streamsize result = 0;
+ while(result < n) {
+ if(state_ == s_start) {
+ state_ = s_header;
+ header_.reset();
+ footer_.reset();
+ }
+ if (state_ == s_header) {
+ int c = s[result++];
+ header_.process(c);
+ if (header_.done())
+ state_ = s_body;
+ } else if (state_ == s_body) {
+ try {
+ std::streamsize amt =
+ base_type::write(snk, s + result, n - result);
+ result += amt;
+ if (!this->eof()) {
+ break;
+ } else {
+ state_ = s_footer;
+ }
+ } catch (const zlib_error& e) {
+ boost::throw_exception(gzip_error(e));
+ }
+ } else { // state_ == s_footer
+ if (footer_.done()) {
+ if (footer_.crc() != this->crc())
+ boost::throw_exception(gzip_error(gzip::bad_crc));
+
+ base_type::close(snk, BOOST_IOS::out);
+ state_ = s_start;
+ } else {
+ int c = s[result++];
+ footer_.process(c);
+ }
+ }
+ }
+ return result;
+ }
+
+ template<typename Source>
+ std::streamsize read(Source& src, char_type* s, std::streamsize n)
+ {
+ typedef char_traits<char> traits_type;
+ std::streamsize result = 0;
+ peekable_source<Source> peek(src, putback_);
+ while (result < n && state_ != s_done) {
+ if (state_ == s_start) {
+ state_ = s_header;
+ header_.reset();
+ footer_.reset();
+ }
+ if (state_ == s_header) {
+ int c = boost::iostreams::get(peek);
+ if (traits_type::is_eof(c)) {
+ boost::throw_exception(gzip_error(gzip::bad_header));
+ } else if (traits_type::would_block(c)) {
+ break;
+ }
+ header_.process(c);
+ if (header_.done())
+ state_ = s_body;
+ } else if (state_ == s_body) {
+ try {
+ std::streamsize amt =
+ base_type::read(peek, s + result, n - result);
+ if (amt != -1) {
+ result += amt;
+ if (amt < n - result)
+ break;
+ } else {
+ peek.putback(this->unconsumed_input());
+ state_ = s_footer;
+ }
+ } catch (const zlib_error& e) {
+ boost::throw_exception(gzip_error(e));
+ }
+ } else { // state_ == s_footer
+ int c = boost::iostreams::get(peek);
+ if (traits_type::is_eof(c)) {
+ boost::throw_exception(gzip_error(gzip::bad_footer));
+ } else if (traits_type::would_block(c)) {
+ break;
+ }
+ footer_.process(c);
+ if (footer_.done()) {
+ if (footer_.crc() != this->crc())
+ boost::throw_exception(gzip_error(gzip::bad_crc));
+ int c = boost::iostreams::get(peek);
+ if (traits_type::is_eof(c)) {
+ state_ = s_done;
+ } else {
+ peek.putback(c);
+ base_type::close(peek, BOOST_IOS::in);
+ state_ = s_start;
+ header_.reset();
+ footer_.reset();
+ }
+ }
+ }
+ }
+ if (peek.has_unconsumed_input()) {
+ putback_ = peek.unconsumed_input();
+ } else {
+ putback_.clear();
+ }
+ return result != 0 || state_ != s_done ?
+ result :
+ -1;
+ }
+
+ template<typename Source>
+ void close(Source& src, BOOST_IOS::openmode m)
+ {
+ try {
+ base_type::close(src, m);
+ } catch (const zlib_error& e) {
+ state_ = s_start;
+ boost::throw_exception(gzip_error(e));
+ }
+ if (m == BOOST_IOS::out) {
+ if (state_ == s_start || state_ == s_header)
+ boost::throw_exception(gzip_error(gzip::bad_header));
+ else if (state_ == s_body)
+ boost::throw_exception(gzip_error(gzip::bad_footer));
+ else if (state_ == s_footer) {
+ if (!footer_.done())
+ boost::throw_exception(gzip_error(gzip::bad_footer));
+ else if(footer_.crc() != this->crc())
+ boost::throw_exception(gzip_error(gzip::bad_crc));
+ } else {
+ BOOST_ASSERT(!"Bad state");
+ }
+ }
+ state_ = s_start;
+ }
+
+ std::string file_name() const { return header_.file_name(); }
+ std::string comment() const { return header_.comment(); }
+ bool text() const { return header_.text(); }
+ int os() const { return header_.os(); }
+ std::time_t mtime() const { return header_.mtime(); }
+private:
+ static gzip_params make_params(int window_bits);
+
+ // Source adapter allowing an arbitrary character sequence to be put back.
+ template<typename Source>
+ struct peekable_source {
+ typedef char char_type;
+ struct category : source_tag, peekable_tag { };
+ explicit peekable_source(Source& src, const string_type& putback = "")
+ : src_(src), putback_(putback), offset_(0)
+ { }
+ std::streamsize read(char* s, std::streamsize n)
+ {
+ std::streamsize result = 0;
+
+ // Copy characters from putback buffer
+ std::streamsize pbsize =
+ static_cast<std::streamsize>(putback_.size());
+ if (offset_ < pbsize) {
+ result = (std::min)(n, pbsize - offset_);
+ BOOST_IOSTREAMS_CHAR_TRAITS(char)::copy(
+ s, putback_.data() + offset_, result);
+ offset_ += result;
+ if (result == n)
+ return result;
+ }
+
+ // Read characters from src_
+ std::streamsize amt =
+ boost::iostreams::read(src_, s + result, n - result);
+ return amt != -1 ?
+ result + amt :
+ result ? result : -1;
+ }
+ bool putback(char c)
+ {
+ if (offset_) {
+ putback_[--offset_] = c;
+ } else {
+ boost::throw_exception(
+ boost::iostreams::detail::bad_putback());
+ }
+ return true;
+ }
+ void putback(const string_type& s)
+ {
+ putback_.replace(0, offset_, s);
+ offset_ = 0;
+ }
+
+ // Returns true if some characters have been putback but not re-read.
+ bool has_unconsumed_input() const
+ {
+ return offset_ < static_cast<std::streamsize>(putback_.size());
+ }
+
+ // Returns the sequence of characters that have been put back but not re-read.
+ string_type unconsumed_input() const
+ {
+ return string_type(putback_, offset_, putback_.size() - offset_);
+ }
+ Source& src_;
+ string_type putback_;
+ std::streamsize offset_;
+ };
+
+ enum state_type {
+ s_start = 1,
+ s_header = s_start + 1,
+ s_body = s_header + 1,
+ s_footer = s_body + 1,
+ s_done = s_footer + 1
+ };
+ detail::gzip_header header_;
+ detail::gzip_footer footer_;
+ string_type putback_;
+ int state_;
+};
+BOOST_IOSTREAMS_PIPABLE(basic_gzip_decompressor, 1)
+
+typedef basic_gzip_decompressor<> gzip_decompressor;
+
+//------------------Implementation of gzip_compressor-------------------------//
+
+template<typename Alloc>
+basic_gzip_compressor<Alloc>::basic_gzip_compressor
+ (const gzip_params& p, int buffer_size)
+ : base_type(normalize_params(p), buffer_size),
+ offset_(0), flags_(0)
+{
+ // Calculate gzip header.
+ bool has_name = !p.file_name.empty();
+ bool has_comment = !p.comment.empty();
+
+ std::string::size_type length =
+ 10 +
+ (has_name ? p.file_name.size() + 1 : 0) +
+ (has_comment ? p.comment.size() + 1 : 0);
+ // + 2; // Header crc confuses gunzip.
+ int flags =
+ //gzip::flags::header_crc +
+ (has_name ? gzip::flags::name : 0) +
+ (has_comment ? gzip::flags::comment : 0);
+ int extra_flags =
+ ( p.level == zlib::best_compression ?
+ gzip::extra_flags::best_compression :
+ 0 ) +
+ ( p.level == zlib::best_speed ?
+ gzip::extra_flags::best_speed :
+ 0 );
+ header_.reserve(length);
+ header_ += gzip::magic::id1; // ID1.
+ header_ += gzip::magic::id2; // ID2.
+ header_ += gzip::method::deflate; // CM.
+ header_ += static_cast<char>(flags); // FLG.
+ header_ += static_cast<char>(0xFF & p.mtime); // MTIME.
+ header_ += static_cast<char>(0xFF & (p.mtime >> 8));
+ header_ += static_cast<char>(0xFF & (p.mtime >> 16));
+ header_ += static_cast<char>(0xFF & (p.mtime >> 24));
+ header_ += static_cast<char>(extra_flags); // XFL.
+ header_ += static_cast<char>(gzip::os_unknown); // OS.
+ if (has_name) {
+ header_ += p.file_name;
+ header_ += '\0';
+ }
+ if (has_comment) {
+ header_ += p.comment;
+ header_ += '\0';
+ }
+}
+
+template<typename Alloc>
+gzip_params basic_gzip_compressor<Alloc>::normalize_params(gzip_params p)
+{
+ p.noheader = true;
+ p.calculate_crc = true;
+ return p;
+}
+
+template<typename Alloc>
+void basic_gzip_compressor<Alloc>::prepare_footer()
+{
+ boost::iostreams::back_insert_device<std::string> out(footer_);
+ write_long(this->crc(), out);
+ write_long(this->total_in(), out);
+ flags_ |= f_body_done;
+ offset_ = 0;
+}
+
+template<typename Alloc>
+std::streamsize basic_gzip_compressor<Alloc>::read_string
+ (char* s, std::streamsize n, std::string& str)
+{
+ std::streamsize avail =
+ static_cast<std::streamsize>(str.size() - offset_);
+ std::streamsize amt = (std::min)(avail, n);
+ std::copy( str.data() + offset_,
+ str.data() + offset_ + amt,
+ s );
+ offset_ += amt;
+ if ( !(flags_ & f_header_done) &&
+ offset_ == static_cast<std::size_t>(str.size()) )
+ {
+ flags_ |= f_header_done;
+ }
+ return amt;
+}
+
+//------------------Implementation of gzip_decompressor-----------------------//
+
+template<typename Alloc>
+basic_gzip_decompressor<Alloc>::basic_gzip_decompressor
+ (int window_bits, int buffer_size)
+ : base_type(make_params(window_bits), buffer_size),
+ state_(s_start)
+ { }
+
+template<typename Alloc>
+gzip_params basic_gzip_decompressor<Alloc>::make_params(int window_bits)
+{
+ gzip_params p;
+ p.window_bits = window_bits;
+ p.noheader = true;
+ p.calculate_crc = true;
+ return p;
+}
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif // #ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED