Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:44:31

0001 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
0002 // (C) Copyright 2003-2007 Jonathan Turkanis
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
0005 
0006 // See http://www.boost.org/libs/iostreams for documentation.
0007 
0008 // Contains the definitions of the class templates gzip_compressor and
0009 // gzip_decompressor for reading and writing files in the gzip file format
0010 // (RFC 1952). Based in part on work of Jonathan de Halleux; see [...]
0011 
0012 #ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED
0013 #define BOOST_IOSTREAMS_GZIP_HPP_INCLUDED
0014 
0015 #if defined(_MSC_VER)
0016 # pragma once
0017 #endif
0018 
0019 #include <boost/config.hpp> // STATIC_CONSTANT, STDC_NAMESPACE, 
0020                             // DINKUMWARE_STDLIB, __STL_CONFIG_H.
0021 #include <algorithm>                      // min.
0022 #include <boost/assert.hpp>
0023 #include <cstdio>                         // EOF.
0024 #include <cstddef>                        // size_t.
0025 #include <ctime>                          // std::time_t.
0026 #include <memory>                         // allocator.
0027 #include <boost/config.hpp>               // Put size_t in std.
0028 #include <boost/detail/workaround.hpp>
0029 #include <boost/cstdint.hpp>              // uint8_t, uint32_t.
0030 #include <boost/iostreams/checked_operations.hpp>
0031 #include <boost/iostreams/constants.hpp>  // buffer size.
0032 #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
0033 #include <boost/iostreams/detail/adapter/range_adapter.hpp>
0034 #include <boost/iostreams/detail/char_traits.hpp>
0035 #include <boost/iostreams/detail/ios.hpp> // failure, streamsize.
0036 #include <boost/iostreams/detail/error.hpp>
0037 #include <boost/iostreams/operations.hpp>
0038 #include <boost/iostreams/device/back_inserter.hpp>
0039 #include <boost/iostreams/filter/zlib.hpp>
0040 #include <boost/iostreams/pipeline.hpp>     
0041 #include <boost/iostreams/putback.hpp>
0042 #include <boost/throw_exception.hpp>
0043 
0044 // Must come last.
0045 #if defined(BOOST_MSVC)
0046 # pragma warning(push)
0047 # pragma warning(disable:4244)    // Possible truncation
0048 # pragma warning(disable:4251)    // Missing DLL interface for std::string
0049 # pragma warning(disable:4309)    // Truncation of constant value.
0050 #endif
0051 
0052 #ifdef BOOST_NO_STDC_NAMESPACE
0053 namespace std { using ::time_t; }
0054 #endif
0055 
0056 namespace boost { namespace iostreams {
0057                     
0058 //------------------Definitions of constants----------------------------------//
0059 
0060 namespace gzip {
0061 
0062 using namespace boost::iostreams::zlib;
0063 
0064     // Error codes used by gzip_error.
0065 
0066 const int zlib_error        = 1;
0067 const int bad_crc           = 2; // Recorded crc doesn't match data.
0068 const int bad_length        = 3; // Recorded length doesn't match data.
0069 const int bad_header        = 4; // Malformed header.
0070 const int bad_footer        = 5; // Malformed footer.
0071 const int bad_method        = 6; // Unsupported compression method.
0072 
0073 namespace magic {
0074 
0075     // Magic numbers used by gzip header.
0076 
0077 const int id1               = 0x1f;
0078 const int id2               = 0x8b;
0079 
0080 } // End namespace magic.
0081 
0082 namespace method {
0083 
0084     // Codes used for the 'CM' byte of the gzip header.
0085 
0086 const int deflate           = 8;
0087 
0088 } // End namespace method.
0089 
0090 namespace flags {
0091 
0092     // Codes used for the 'FLG' byte of the gzip header.
0093 
0094 const int text              = 1;
0095 const int header_crc        = 2;
0096 const int extra             = 4;
0097 const int name              = 8;
0098 const int comment           = 16;
0099 
0100 } // End namespace flags.
0101 
0102 namespace extra_flags {
0103 
0104     // Codes used for the 'XFL' byte of the gzip header.
0105 
0106 const int best_compression  = 2;
0107 const int best_speed        = 4;
0108 
0109 } // End namespace extra_flags.
0110 
0111     // Codes used for the 'OS' byte of the gzip header.
0112 
0113 const int os_fat            = 0;
0114 const int os_amiga          = 1;
0115 const int os_vms            = 2;
0116 const int os_unix           = 3;
0117 const int os_vm_cms         = 4;
0118 const int os_atari          = 5;
0119 const int os_hpfs           = 6;
0120 const int os_macintosh      = 7;
0121 const int os_z_system       = 8;
0122 const int os_cp_m           = 9;
0123 const int os_tops_20        = 10;
0124 const int os_ntfs           = 11;
0125 const int os_qdos           = 12;
0126 const int os_acorn          = 13;
0127 const int os_unknown        = 255;
0128 
0129 } // End namespace gzip.
0130 
0131 //------------------Definition of gzip_params---------------------------------//
0132 
0133 //
0134 // Class name: gzip_params.
0135 // Description: Subclass of zlib_params with an additional field
0136 //      representing a file name.
0137 //
0138 struct gzip_params : zlib_params {
0139 
0140     // Non-explicit constructor.
0141     gzip_params( int level_              = gzip::default_compression,
0142                  int method_             = gzip::deflated,
0143                  int window_bits_        = gzip::default_window_bits,
0144                  int mem_level_          = gzip::default_mem_level,
0145                  int strategy_           = gzip::default_strategy,
0146                  std::string file_name_  = "",
0147                  std::string comment_    = "",
0148                  std::time_t mtime_      = 0 )
0149         : zlib_params(level_, method_, window_bits_, mem_level_, strategy_),
0150           file_name(file_name_), comment(comment_), mtime(mtime_)
0151         { }
0152     std::string  file_name;
0153     std::string  comment;
0154     std::time_t  mtime;
0155 };
0156 
0157 //------------------Definition of gzip_error----------------------------------//
0158 
0159 //
0160 // Class name: gzip_error.
0161 // Description: Subclass of std::ios_base::failure thrown to indicate
0162 //     zlib errors other than out-of-memory conditions.
0163 //
0164 class gzip_error : public BOOST_IOSTREAMS_FAILURE {
0165 public:
0166     explicit gzip_error(int error)
0167         : BOOST_IOSTREAMS_FAILURE("gzip error"),
0168           error_(error), zlib_error_code_(zlib::okay) { }
0169     explicit gzip_error(const zlib_error& e)
0170         : BOOST_IOSTREAMS_FAILURE("gzip error"),
0171           error_(gzip::zlib_error), zlib_error_code_(e.error())
0172         { }
0173     int error() const { return error_; }
0174     int zlib_error_code() const { return zlib_error_code_; }
0175 private:
0176     int error_;
0177     int zlib_error_code_;
0178 };
0179 
0180 //------------------Definition of gzip_compressor-----------------------------//
0181 
0182 //
0183 // Template name: gzip_compressor
0184 // Description: Model of OutputFilter implementing compression in the
0185 //      gzip format.
0186 //
0187 template<typename Alloc = std::allocator<char> >
0188 class basic_gzip_compressor : basic_zlib_compressor<Alloc> {
0189 private:
0190     typedef basic_zlib_compressor<Alloc>  base_type;
0191 public:
0192     typedef char char_type;
0193     struct category
0194         : dual_use,
0195           filter_tag,
0196           multichar_tag,
0197           closable_tag
0198         { };
0199     basic_gzip_compressor( const gzip_params& = gzip::default_compression,
0200                            std::streamsize buffer_size = default_device_buffer_size );
0201 
0202     template<typename Source>
0203     std::streamsize read(Source& src, char_type* s, std::streamsize n)
0204     {
0205         std::streamsize result = 0;
0206 
0207         // Read header.
0208         if (!(flags_ & f_header_done))
0209             result += read_string(s, n, header_);
0210 
0211         // Read body.
0212         if (!(flags_ & f_body_done)) {
0213 
0214             // Read from basic_zlib_filter.
0215             std::streamsize amt = base_type::read(src, s + result, n - result);
0216             if (amt != -1) {
0217                 result += amt;
0218                 if (amt < n - result) { // Double-check for EOF.
0219                     amt = base_type::read(src, s + result, n - result);
0220                     if (amt != -1)
0221                         result += amt;
0222                 }
0223             }
0224             if (amt == -1)
0225                 prepare_footer();
0226         }
0227 
0228         // Read footer.
0229         if ((flags_ & f_body_done) != 0 && result < n)
0230             result += read_string(s + result, n - result, footer_);
0231 
0232         return result != 0 ? result : -1;
0233     }
0234 
0235     template<typename Sink>
0236     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
0237     {
0238         if (!(flags_ & f_header_done)) {
0239             std::streamsize amt = 
0240                 static_cast<std::streamsize>(header_.size() - offset_);
0241             offset_ += boost::iostreams::write_if(snk, header_.data() + offset_, amt);
0242             if (offset_ == header_.size())
0243                 flags_ |= f_header_done;
0244             else
0245                 return 0;
0246         }
0247         return base_type::write(snk, s, n);
0248     }
0249 
0250     template<typename Sink>
0251     void close(Sink& snk, BOOST_IOS::openmode m)
0252     {
0253         try {
0254             if (m == BOOST_IOS::out && !(flags_ & f_header_done))
0255                 this->write(snk, 0, 0);
0256 
0257             // Close zlib compressor.
0258             base_type::close(snk, m);
0259 
0260             if (m == BOOST_IOS::out) {
0261                 if (flags_ & f_header_done) {
0262 
0263                     // Write final fields of gzip file format.
0264                     write_long(this->crc(), snk);
0265                     write_long(this->total_in(), snk);
0266                 }
0267             }
0268         } catch(...) {
0269             close_impl();
0270             throw;
0271         }
0272         close_impl();
0273     }
0274 private:
0275     static gzip_params normalize_params(gzip_params p);
0276     void prepare_footer();
0277     std::streamsize read_string(char* s, std::streamsize n, std::string& str);
0278 
0279     template<typename Sink>
0280     static void write_long(long n, Sink& next, boost::mpl::true_)
0281     {
0282         boost::iostreams::put(next, static_cast<char>(0xFF & n));
0283         boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 8)));
0284         boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 16)));
0285         boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 24)));
0286     }
0287     template<typename Sink>
0288     static void write_long(long, Sink&, boost::mpl::false_)
0289     {
0290     }
0291     template<typename Sink>
0292     static void write_long(long n, Sink& next)
0293     {
0294         typedef typename category_of<Sink>::type category;
0295         typedef is_convertible<category, output> can_write;
0296         write_long(n, next, can_write());
0297     }
0298 
0299     void close_impl()
0300     {
0301         footer_.clear();
0302         offset_ = 0;
0303         flags_ = 0;
0304     }
0305 
0306     enum state_type {
0307         f_header_done = 1,
0308         f_body_done = f_header_done << 1,
0309         f_footer_done = f_body_done << 1
0310     };
0311     std::string  header_;
0312     std::string  footer_;
0313     std::size_t  offset_;
0314     int          flags_;
0315 };
0316 BOOST_IOSTREAMS_PIPABLE(basic_gzip_compressor, 1)
0317 
0318 typedef basic_gzip_compressor<> gzip_compressor;
0319 
0320 //------------------Definition of helper templates for decompression----------//
0321 
0322 namespace detail {
0323 
0324 // Processes gzip headers
0325 class BOOST_IOSTREAMS_DECL gzip_header {
0326 public:
0327     gzip_header() { reset(); }
0328 
0329     // Members for processing header data
0330     void process(char c);
0331     bool done() const { return state_ == s_done; }
0332     void reset();
0333 
0334     // Members for accessing header data
0335     std::string file_name() const { return file_name_; }
0336     std::string comment() const { return comment_; }
0337     bool text() const { return (flags_ & gzip::flags::text) != 0; }
0338     int os() const { return os_; }
0339     std::time_t mtime() const { return mtime_; }
0340 private:
0341     enum state_type {
0342         s_id1       = 1,
0343         s_id2       = s_id1 + 1,
0344         s_cm        = s_id2 + 1,
0345         s_flg       = s_cm + 1,
0346         s_mtime     = s_flg + 1,
0347         s_xfl       = s_mtime + 1,
0348         s_os        = s_xfl + 1,
0349         s_xlen      = s_os + 1,
0350         s_extra     = s_xlen + 1,
0351         s_name      = s_extra + 1,
0352         s_comment   = s_name + 1,
0353         s_hcrc      = s_comment + 1,
0354         s_done      = s_hcrc + 1
0355     };
0356     std::string  file_name_;
0357     std::string  comment_;
0358     int          os_;
0359     std::time_t  mtime_;
0360     int          flags_;
0361     int          state_;
0362     int          offset_;  // Offset within fixed-length region.
0363     int          xlen_;    // Bytes remaining in extra field.
0364 };
0365 
0366 // Processes gzip footers
0367 class BOOST_IOSTREAMS_DECL gzip_footer {
0368 public:
0369     gzip_footer() { reset(); }
0370     
0371     // Members for processing footer data
0372     void process(char c);
0373     bool done() const { return state_ == s_done; }
0374     void reset();
0375     
0376     // Members for accessing footer data
0377     zlib::ulong crc() const { return crc_; }
0378     zlib::ulong uncompressed_size() const { return isize_; }
0379 private:
0380     enum state_type {
0381         s_crc     = 1,
0382         s_isize   = s_crc + 1,
0383         s_done    = s_isize + 1
0384     };
0385     zlib::ulong  crc_;
0386     zlib::ulong  isize_;
0387     int          state_;
0388     int          offset_; 
0389 };
0390 
0391 } // End namespace boost::iostreams::detail.
0392 
0393 //------------------Definition of basic_gzip_decompressor---------------------//
0394 
0395 //
0396 // Template name: basic_gzip_decompressor
0397 // Description: Model of InputFilter implementing compression in the
0398 //      gzip format.
0399 //
0400 template<typename Alloc = std::allocator<char> >
0401 class basic_gzip_decompressor : basic_zlib_decompressor<Alloc> {
0402 private:
0403     typedef basic_zlib_decompressor<Alloc>   base_type;
0404     typedef typename base_type::string_type  string_type;
0405 public:
0406     typedef char char_type;
0407     struct category
0408         : dual_use,
0409           filter_tag,
0410           multichar_tag,
0411           closable_tag
0412         { };
0413     basic_gzip_decompressor( int window_bits = gzip::default_window_bits,
0414                              std::streamsize buffer_size = default_device_buffer_size );
0415 
0416     template<typename Sink>
0417     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
0418     {
0419         std::streamsize result = 0;
0420         while(result < n) {
0421             if(state_ == s_start) {
0422                 state_ = s_header;
0423                 header_.reset();
0424                 footer_.reset();
0425             }
0426             if (state_ == s_header) {
0427                 int c = s[result++];
0428                 header_.process(c);
0429                 if (header_.done())
0430                     state_ = s_body;
0431             } else if (state_ == s_body) {
0432                 try {
0433                     std::streamsize amt = 
0434                         base_type::write(snk, s + result, n - result);
0435                     result += amt;
0436                     if (!this->eof()) {
0437                         break;
0438                     } else {
0439                         state_ = s_footer;
0440                     }
0441                 } catch (const zlib_error& e) {
0442                     boost::throw_exception(gzip_error(e));
0443                 }
0444             } else { // state_ == s_footer
0445                 if (footer_.done()) {
0446                     if (footer_.crc() != this->crc())
0447                         boost::throw_exception(gzip_error(gzip::bad_crc));
0448 
0449                     base_type::close(snk, BOOST_IOS::out);
0450                     state_ = s_start;
0451                 } else {
0452                     int c = s[result++];
0453                     footer_.process(c);
0454                 }
0455             }
0456         }
0457         return result;
0458     }
0459 
0460     template<typename Source>
0461     std::streamsize read(Source& src, char_type* s, std::streamsize n)
0462     {
0463         typedef char_traits<char>  traits_type;
0464         std::streamsize            result = 0;
0465         peekable_source<Source>    peek(src, putback_);
0466         while (result < n && state_ != s_done) {
0467             if (state_ == s_start) {
0468                 state_ = s_header;
0469                 header_.reset();
0470                 footer_.reset();
0471             }
0472             if (state_ == s_header) {
0473                 int c = boost::iostreams::get(peek);
0474                 if (traits_type::is_eof(c)) {
0475                     boost::throw_exception(gzip_error(gzip::bad_header));
0476                 } else if (traits_type::would_block(c)) {
0477                     break;
0478                 }
0479                 header_.process(c);
0480                 if (header_.done())
0481                     state_ = s_body;
0482             } else if (state_ == s_body) {
0483                 try {
0484                     std::streamsize amt = 
0485                         base_type::read(peek, s + result, n - result);
0486                     if (amt != -1) {
0487                         result += amt;
0488                         if (amt < n - result)
0489                             break;
0490                     } else {
0491                         peek.putback(this->unconsumed_input());
0492                         state_ = s_footer;
0493                     }
0494                 } catch (const zlib_error& e) {
0495                     boost::throw_exception(gzip_error(e));
0496                 }
0497             } else { // state_ == s_footer
0498                 int c = boost::iostreams::get(peek);
0499                 if (traits_type::is_eof(c)) {
0500                     boost::throw_exception(gzip_error(gzip::bad_footer));
0501                 } else if (traits_type::would_block(c)) {
0502                     break;
0503                 }
0504                 footer_.process(c);
0505                 if (footer_.done()) {
0506                     if (footer_.crc() != this->crc())
0507                         boost::throw_exception(gzip_error(gzip::bad_crc));
0508                     c = boost::iostreams::get(peek);
0509                     if (traits_type::is_eof(c)) {
0510                         state_ = s_done;
0511                     } else {
0512                         peek.putback(c);
0513                         base_type::close(peek, BOOST_IOS::in);
0514                         state_ = s_start;
0515                         header_.reset();
0516                         footer_.reset();
0517                     }
0518                 }
0519             }
0520         }
0521         if (peek.has_unconsumed_input()) {
0522             putback_ = peek.unconsumed_input();
0523         } else {
0524             putback_.clear();
0525         }
0526         return result != 0 || state_ != s_done ?
0527             result :
0528             -1;
0529     }
0530 
0531     template<typename Source>
0532     void close(Source& src, BOOST_IOS::openmode m)
0533     {
0534         try {
0535             base_type::close(src, m);
0536         } catch (const zlib_error& e) {
0537             state_ = s_start;
0538             boost::throw_exception(gzip_error(e));
0539         }
0540         if (m == BOOST_IOS::out) {
0541             if (state_ == s_start || state_ == s_header)
0542                 boost::throw_exception(gzip_error(gzip::bad_header));
0543             else if (state_ == s_body)
0544                 boost::throw_exception(gzip_error(gzip::bad_footer));
0545             else if (state_ == s_footer) {
0546                 if (!footer_.done())
0547                     boost::throw_exception(gzip_error(gzip::bad_footer));
0548                 else if(footer_.crc() != this->crc())
0549                     boost::throw_exception(gzip_error(gzip::bad_crc));
0550             } else {
0551                 BOOST_ASSERT(!"Bad state");
0552             }
0553         }
0554         state_ = s_start;
0555     }
0556 
0557     std::string file_name() const { return header_.file_name(); }
0558     std::string comment() const { return header_.comment(); }
0559     bool text() const { return header_.text(); }
0560     int os() const { return header_.os(); }
0561     std::time_t mtime() const { return header_.mtime(); }
0562 private:
0563     static gzip_params make_params(int window_bits);
0564 
0565     // Source adapter allowing an arbitrary character sequence to be put back.
0566     template<typename Source>
0567     struct peekable_source {
0568         typedef char char_type;
0569         struct category : source_tag, peekable_tag { };
0570         explicit peekable_source(Source& src, const string_type& putback = "") 
0571             : src_(src), putback_(putback), offset_(0)
0572             { }
0573         std::streamsize read(char* s, std::streamsize n)
0574         {
0575             std::streamsize result = 0;
0576 
0577             // Copy characters from putback buffer
0578             std::streamsize pbsize = 
0579                 static_cast<std::streamsize>(putback_.size());
0580             if (offset_ < pbsize) {
0581                 result = (std::min)(n, pbsize - offset_);
0582                 BOOST_IOSTREAMS_CHAR_TRAITS(char)::copy(
0583                     s, putback_.data() + offset_, result);
0584                 offset_ += result;
0585                 if (result == n)
0586                     return result;
0587             }
0588 
0589             // Read characters from src_
0590             std::streamsize amt = 
0591                 boost::iostreams::read(src_, s + result, n - result);
0592             return amt != -1 ? 
0593                 result + amt : 
0594                 result ? result : -1;
0595         }
0596         bool putback(char c)
0597         {
0598             if (offset_) {
0599                 putback_[--offset_] = c;
0600             } else {
0601                 boost::throw_exception(
0602                     boost::iostreams::detail::bad_putback());
0603             }
0604             return true;
0605         }
0606         void putback(const string_type& s)
0607         {
0608             putback_.replace(0, offset_, s);
0609             offset_ = 0;
0610         }
0611 
0612         // Returns true if some characters have been putback but not re-read.
0613         bool has_unconsumed_input() const 
0614         {
0615             return offset_ < static_cast<std::streamsize>(putback_.size());
0616         }
0617 
0618         // Returns the sequence of characters that have been put back but not re-read.
0619         string_type unconsumed_input() const
0620         {
0621             return string_type(putback_, offset_, putback_.size() - offset_);
0622         }
0623         Source&          src_;
0624         string_type      putback_;
0625         std::streamsize  offset_;
0626     };
0627 
0628     enum state_type {
0629         s_start   = 1,
0630         s_header  = s_start + 1,
0631         s_body    = s_header + 1,
0632         s_footer  = s_body + 1,
0633         s_done    = s_footer + 1
0634     };
0635     detail::gzip_header  header_;
0636     detail::gzip_footer  footer_;
0637     string_type          putback_;
0638     int                  state_;
0639 };
0640 BOOST_IOSTREAMS_PIPABLE(basic_gzip_decompressor, 1)
0641 
0642 typedef basic_gzip_decompressor<> gzip_decompressor;
0643 
0644 //------------------Implementation of gzip_compressor-------------------------//
0645 
0646 template<typename Alloc>
0647 basic_gzip_compressor<Alloc>::basic_gzip_compressor
0648     (const gzip_params& p, std::streamsize buffer_size)
0649     : base_type(normalize_params(p), buffer_size),
0650       offset_(0), flags_(0)
0651 {
0652     // Calculate gzip header.
0653     bool has_name = !p.file_name.empty();
0654     bool has_comment = !p.comment.empty();
0655 
0656     std::string::size_type length =
0657         10 +
0658         (has_name ? p.file_name.size() + 1 : 0) +
0659         (has_comment ? p.comment.size() + 1 : 0);
0660         // + 2; // Header crc confuses gunzip.
0661     int flags =
0662         //gzip::flags::header_crc +
0663         (has_name ? gzip::flags::name : 0) +
0664         (has_comment ? gzip::flags::comment : 0);
0665     int extra_flags =
0666         ( p.level == zlib::best_compression ?
0667               gzip::extra_flags::best_compression :
0668               0 ) +
0669         ( p.level == zlib::best_speed ?
0670               gzip::extra_flags::best_speed :
0671               0 );
0672     header_.reserve(length);
0673     header_ += gzip::magic::id1;                         // ID1.
0674     header_ += static_cast<char>(gzip::magic::id2);      // ID2.
0675     header_ += gzip::method::deflate;                    // CM.
0676     header_ += static_cast<char>(flags);                 // FLG.
0677     header_ += static_cast<char>(0xFF & p.mtime);        // MTIME.
0678     header_ += static_cast<char>(0xFF & (p.mtime >> 8));
0679     header_ += static_cast<char>(0xFF & (p.mtime >> 16));
0680     header_ += static_cast<char>(0xFF & (p.mtime >> 24));
0681     header_ += static_cast<char>(extra_flags);           // XFL.
0682     header_ += static_cast<char>(gzip::os_unknown);      // OS.
0683     if (has_name) {
0684         header_ += p.file_name;
0685         header_ += '\0';
0686     }
0687     if (has_comment) {
0688         header_ += p.comment;
0689         header_ += '\0';
0690     }
0691 }
0692 
0693 template<typename Alloc>
0694 gzip_params basic_gzip_compressor<Alloc>::normalize_params(gzip_params p)
0695 {
0696     p.noheader = true;
0697     p.calculate_crc = true;
0698     return p;
0699 }
0700 
0701 template<typename Alloc>
0702 void basic_gzip_compressor<Alloc>::prepare_footer()
0703 {
0704     boost::iostreams::back_insert_device<std::string> out(footer_);
0705     write_long(this->crc(), out);
0706     write_long(this->total_in(), out);
0707     flags_ |= f_body_done;
0708     offset_ = 0;
0709 }
0710 
0711 template<typename Alloc>
0712 std::streamsize basic_gzip_compressor<Alloc>::read_string
0713     (char* s, std::streamsize n, std::string& str)
0714 {
0715     std::streamsize avail =
0716         static_cast<std::streamsize>(str.size() - offset_);
0717     std::streamsize amt = (std::min)(avail, n);
0718     std::copy( str.data() + offset_,
0719                str.data() + offset_ + amt,
0720                s );
0721     offset_ += amt;
0722     if ( !(flags_ & f_header_done) &&
0723          offset_ == static_cast<std::size_t>(str.size()) )
0724     {
0725         flags_ |= f_header_done;
0726     }
0727     return amt;
0728 }
0729 
0730 //------------------Implementation of gzip_decompressor-----------------------//
0731 
0732 template<typename Alloc>
0733 basic_gzip_decompressor<Alloc>::basic_gzip_decompressor
0734     (int window_bits, std::streamsize buffer_size)
0735     : base_type(make_params(window_bits), buffer_size),
0736       state_(s_start)
0737     { }
0738 
0739 template<typename Alloc>
0740 gzip_params basic_gzip_decompressor<Alloc>::make_params(int window_bits)
0741 {
0742     gzip_params p;
0743     p.window_bits = window_bits;
0744     p.noheader = true;
0745     p.calculate_crc = true;
0746     return p;
0747 }
0748 
0749 //----------------------------------------------------------------------------//
0750 
0751 } } // End namespaces iostreams, boost.
0752 
0753 #if defined(BOOST_MSVC)
0754 # pragma warning(pop)
0755 #endif
0756 
0757 #endif // #ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED