BVB Source Codes

mars Show gzip.hpp Source code

Return Download mars: download gzip.hpp Source code - Download mars Source code - Type:.hpp
  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. // Contains the definitions of the class templates gzip_compressor and
  9. // gzip_decompressor for reading and writing files in the gzip file format
  10. // (RFC 1952). Based in part on work of Jonathan de Halleux; see [...]
  11.  
  12. #ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED
  13. #define BOOST_IOSTREAMS_GZIP_HPP_INCLUDED
  14.  
  15. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  16. # pragma once
  17. #endif
  18.  
  19. #include <boost/config.hpp> // STATIC_CONSTANT, STDC_NAMESPACE,
  20.                             // DINKUMWARE_STDLIB, __STL_CONFIG_H.
  21. #include <algorithm>                      // min.
  22. #include <boost/assert.hpp>
  23. #include <cstdio>                         // EOF.
  24. #include <cstddef>                        // size_t.
  25. #include <ctime>                          // std::time_t.
  26. #include <memory>                         // allocator.
  27. #include <boost/config.hpp>               // Put size_t in std.
  28. #include <boost/detail/workaround.hpp>
  29. #include <boost/cstdint.hpp>              // uint8_t, uint32_t.
  30. #include <boost/iostreams/constants.hpp>  // buffer size.
  31. #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
  32. #include <boost/iostreams/detail/adapter/range_adapter.hpp>
  33. #include <boost/iostreams/detail/char_traits.hpp>
  34. #include <boost/iostreams/detail/ios.hpp> // failure.
  35. #include <boost/iostreams/detail/error.hpp>
  36. #include <boost/iostreams/operations.hpp>
  37. #include <boost/iostreams/device/back_inserter.hpp>
  38. #include <boost/iostreams/filter/zlib.hpp>
  39. #include <boost/iostreams/pipeline.hpp>    
  40. #include <boost/iostreams/putback.hpp>
  41. #include <boost/throw_exception.hpp>
  42. #include <boost/detail/no_exceptions_support.hpp>
  43.  
  44. // Must come last.
  45. #if defined(BOOST_MSVC)
  46. # pragma warning(push)
  47. # pragma warning(disable: 4309)    // Truncation of constant value.
  48. #endif
  49.  
  50. #ifdef BOOST_NO_STDC_NAMESPACE
  51. namespace std { using ::time_t; }
  52. #endif
  53.  
  54. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost { namespace iostreams {
  55.                    
  56. //------------------Definitions of constants----------------------------------//
  57.  
  58. namespace gzip {
  59.  
  60. using namespace mars_boost::iostreams::zlib;
  61.  
  62.     // Error codes used by gzip_error.
  63.  
  64. const int zlib_error        = 1;
  65. const int bad_crc           = 2; // Recorded crc doesn't match data.
  66. const int bad_length        = 3; // Recorded length doesn't match data.
  67. const int bad_header        = 4; // Malformed header.
  68. const int bad_footer        = 5; // Malformed footer.
  69. const int bad_method        = 6; // Unsupported compression method.
  70.  
  71. namespace magic {
  72.  
  73.     // Magic numbers used by gzip header.
  74.  
  75. const int id1               = 0x1f;
  76. const int id2               = 0x8b;
  77.  
  78. } // End namespace magic.
  79.  
  80. namespace method {
  81.  
  82.     // Codes used for the 'CM' byte of the gzip header.
  83.  
  84. const int deflate           = 8;
  85.  
  86. } // End namespace method.
  87.  
  88. namespace flags {
  89.  
  90.     // Codes used for the 'FLG' byte of the gzip header.
  91.  
  92. const int text              = 1;
  93. const int header_crc        = 2;
  94. const int extra             = 4;
  95. const int name              = 8;
  96. const int comment           = 16;
  97.  
  98. } // End namespace flags.
  99.  
  100. namespace extra_flags {
  101.  
  102.     // Codes used for the 'XFL' byte of the gzip header.
  103.  
  104. const int best_compression  = 2;
  105. const int best_speed        = 4;
  106.  
  107. } // End namespace extra_flags.
  108.  
  109.     // Codes used for the 'OS' byte of the gzip header.
  110.  
  111. const int os_fat            = 0;
  112. const int os_amiga          = 1;
  113. const int os_vms            = 2;
  114. const int os_unix           = 3;
  115. const int os_vm_cms         = 4;
  116. const int os_atari          = 5;
  117. const int os_hpfs           = 6;
  118. const int os_macintosh      = 7;
  119. const int os_z_system       = 8;
  120. const int os_cp_m           = 9;
  121. const int os_tops_20        = 10;
  122. const int os_ntfs           = 11;
  123. const int os_qdos           = 12;
  124. const int os_acorn          = 13;
  125. const int os_unknown        = 255;
  126.  
  127. } // End namespace gzip.
  128.  
  129. //------------------Definition of gzip_params---------------------------------//
  130.  
  131. //
  132. // Class name: gzip_params.
  133. // Description: Subclass of zlib_params with an additional field
  134. //      representing a file name.
  135. //
  136. struct gzip_params : zlib_params {
  137.  
  138.     // Non-explicit constructor.
  139.     gzip_params( int level              = gzip::default_compression,
  140.                  int method             = gzip::deflated,
  141.                  int window_bits        = gzip::default_window_bits,
  142.                  int mem_level          = gzip::default_mem_level,
  143.                  int strategy           = gzip::default_strategy,
  144.                  std::string file_name  = "",
  145.                  std::string comment    = "",
  146.                  std::time_t mtime      = 0 )
  147.         : zlib_params(level, method, window_bits, mem_level, strategy),
  148.           file_name(file_name), comment(comment), mtime(mtime)
  149.         { }
  150.     std::string  file_name;
  151.     std::string  comment;
  152.     std::time_t  mtime;
  153. };
  154.  
  155. //------------------Definition of gzip_error----------------------------------//
  156.  
  157. //
  158. // Class name: gzip_error.
  159. // Description: Subclass of std::ios_base::failure thrown to indicate
  160. //     zlib errors other than out-of-memory conditions.
  161. //
  162. class gzip_error : public BOOST_IOSTREAMS_FAILURE {
  163. public:
  164.     explicit gzip_error(int error)
  165.         : BOOST_IOSTREAMS_FAILURE("gzip error"),
  166.           error_(error), zlib_error_code_(zlib::okay) { }
  167.     explicit gzip_error(const zlib_error& e)
  168.         : BOOST_IOSTREAMS_FAILURE("gzip error"),
  169.           error_(gzip::zlib_error), zlib_error_code_(e.error())
  170.         { }
  171.     int error() const { return error_; }
  172.     int zlib_error_code() const { return zlib_error_code_; }
  173. private:
  174.     int error_;
  175.     int zlib_error_code_;
  176. };
  177.  
  178. //------------------Definition of gzip_compressor-----------------------------//
  179.  
  180. //
  181. // Template name: gzip_compressor
  182. // Description: Model of OutputFilter implementing compression in the
  183. //      gzip format.
  184. //
  185. template<typename Alloc = std::allocator<char> >
  186. class basic_gzip_compressor : basic_zlib_compressor<Alloc> {
  187. private:
  188.     typedef basic_zlib_compressor<Alloc>  base_type;
  189. public:
  190.     typedef char char_type;
  191.     struct category
  192.         : dual_use,
  193.           filter_tag,
  194.           multichar_tag,
  195.           closable_tag
  196.         { };
  197.     basic_gzip_compressor( const gzip_params& = gzip::default_compression,
  198.                            int buffer_size = default_device_buffer_size );
  199.  
  200.     template<typename Source>
  201.     std::streamsize read(Source& src, char_type* s, std::streamsize n)
  202.     {
  203.         std::streamsize result = 0;
  204.  
  205.         // Read header.
  206.         if (!(flags_ & f_header_done))
  207.             result += read_string(s, n, header_);
  208.  
  209.         // Read body.
  210.         if (!(flags_ & f_body_done)) {
  211.  
  212.             // Read from basic_zlib_filter.
  213.             std::streamsize amt = base_type::read(src, s + result, n - result);
  214.             if (amt != -1) {
  215.                 result += amt;
  216.                 if (amt < n - result) { // Double-check for EOF.
  217.                     amt = base_type::read(src, s + result, n - result);
  218.                     if (amt != -1)
  219.                         result += amt;
  220.                 }
  221.             }
  222.             if (amt == -1)
  223.                 prepare_footer();
  224.         }
  225.  
  226.         // Read footer.
  227.         if ((flags_ & f_body_done) != 0 && result < n)
  228.             result += read_string(s + result, n - result, footer_);
  229.  
  230.         return result != 0 ? result : -1;
  231.     }
  232.  
  233.     template<typename Sink>
  234.     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
  235.     {
  236.         if (!(flags_ & f_header_done)) {
  237.             std::streamsize amt =
  238.                 static_cast<std::streamsize>(header_.size() - offset_);
  239.             offset_ += mars_boost::iostreams::write(snk, header_.data() + offset_, amt);
  240.             if (offset_ == header_.size())
  241.                 flags_ |= f_header_done;
  242.             else
  243.                 return 0;
  244.         }
  245.         return base_type::write(snk, s, n);
  246.     }
  247.  
  248.     template<typename Sink>
  249.     void close(Sink& snk, BOOST_IOS::openmode m)
  250.     {
  251.         BOOST_TRY {
  252.             // Close zlib compressor.
  253.             base_type::close(snk, m);
  254.  
  255.             if (m == BOOST_IOS::out) {
  256.                 if (flags_ & f_header_done) {
  257.  
  258.                     // Write final fields of gzip file format.
  259.                     write_long(this->crc(), snk);
  260.                     write_long(this->total_in(), snk);
  261.                 }
  262.             }
  263.         } BOOST_CATCH(...) {
  264.             close_impl();
  265.             throw;
  266.         } BOOST_CATCH_END
  267.         close_impl();
  268.     }
  269. private:
  270.     static gzip_params normalize_params(gzip_params p);
  271.     void prepare_footer();
  272.     std::streamsize read_string(char* s, std::streamsize n, std::string& str);
  273.  
  274.     template<typename Sink>
  275.     static void write_long(long n, Sink& next, mars_boost::mpl::true_)
  276.     {
  277.         mars_boost::iostreams::put(next, static_cast<char>(0xFF & n));
  278.         mars_boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 8)));
  279.         mars_boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 16)));
  280.         mars_boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 24)));
  281.     }
  282.     template<typename Sink>
  283.     static void write_long(long n, Sink& next, mars_boost::mpl::false_)
  284.     {
  285.     }
  286.     template<typename Sink>
  287.     static void write_long(long n, Sink& next)
  288.     {
  289.         typedef typename category_of<Sink>::type category;
  290.         typedef is_convertible<category, output> can_write;
  291.         write_long(n, next, can_write());
  292.     }
  293.  
  294.     void close_impl()
  295.     {
  296.         #if BOOST_WORKAROUND(__GNUC__, == 2) && defined(__STL_CONFIG_H) || \
  297.             BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) \
  298.             /**/
  299.             footer_.erase(0, std::string::npos);
  300.         #else
  301.             footer_.clear();
  302.         #endif
  303.         offset_ = 0;
  304.         flags_ = 0;
  305.     }
  306.  
  307.     enum state_type {
  308.         f_header_done = 1,
  309.         f_body_done = f_header_done << 1,
  310.         f_footer_done = f_body_done << 1
  311.     };
  312.     std::string  header_;
  313.     std::string  footer_;
  314.     std::size_t  offset_;
  315.     int          flags_;
  316. };
  317. BOOST_IOSTREAMS_PIPABLE(basic_gzip_compressor, 1)
  318.  
  319. typedef basic_gzip_compressor<> gzip_compressor;
  320.  
  321. //------------------Definition of helper templates for decompression----------//
  322.  
  323. namespace detail {
  324.  
  325. // Processes gzip headers
  326. class BOOST_IOSTREAMS_DECL gzip_header {
  327. public:
  328.     gzip_header() { reset(); }
  329.  
  330.     // Members for processing header data
  331.     void process(char c);
  332.     bool done() const { return state_ == s_done; }
  333.     void reset();
  334.  
  335.     // Members for accessing header data
  336.     std::string file_name() const { return file_name_; }
  337.     std::string comment() const { return comment_; }
  338.     bool text() const { return (flags_ & gzip::flags::text) != 0; }
  339.     int os() const { return os_; }
  340.     std::time_t mtime() const { return mtime_; }
  341. private:
  342.     enum state_type {
  343.         s_id1       = 1,
  344.         s_id2       = s_id1 + 1,
  345.         s_cm        = s_id2 + 1,
  346.         s_flg       = s_cm + 1,
  347.         s_mtime     = s_flg + 1,
  348.         s_xfl       = s_mtime + 1,
  349.         s_os        = s_xfl + 1,
  350.         s_xlen      = s_os + 1,
  351.         s_extra     = s_xlen + 1,
  352.         s_name      = s_extra + 1,
  353.         s_comment   = s_name + 1,
  354.         s_hcrc      = s_comment + 1,
  355.         s_done      = s_hcrc + 1
  356.     };
  357.     std::string  file_name_;
  358.     std::string  comment_;
  359.     int          os_;
  360.     std::time_t  mtime_;
  361.     int          flags_;
  362.     int          state_;
  363.     int          offset_;  // Offset within fixed-length region.
  364.     int          xlen_;    // Bytes remaining in extra field.
  365. };
  366.  
  367. // Processes gzip footers
  368. class BOOST_IOSTREAMS_DECL gzip_footer {
  369. public:
  370.     gzip_footer() { reset(); }
  371.    
  372.     // Members for processing footer data
  373.     void process(char c);
  374.     bool done() const { return state_ == s_done; }
  375.     void reset();
  376.    
  377.     // Members for accessing footer data
  378.     zlib::ulong crc() const { return crc_; }
  379.     zlib::ulong uncompressed_size() const { return isize_; }
  380. private:
  381.     enum state_type {
  382.         s_crc     = 1,
  383.         s_isize   = s_crc + 1,
  384.         s_done    = s_isize + 1
  385.     };
  386.     zlib::ulong  crc_;
  387.     zlib::ulong  isize_;
  388.     int          state_;
  389.     int          offset_;
  390. };
  391.  
  392. } // End namespace mars_boost::iostreams::detail.
  393.  
  394. //------------------Definition of basic_gzip_decompressor---------------------//
  395.  
  396. //
  397. // Template name: basic_gzip_decompressor
  398. // Description: Model of InputFilter implementing compression in the
  399. //      gzip format.
  400. //
  401. template<typename Alloc = std::allocator<char> >
  402. class basic_gzip_decompressor : basic_zlib_decompressor<Alloc> {
  403. private:
  404.     typedef basic_zlib_decompressor<Alloc>   base_type;
  405.     typedef typename base_type::string_type  string_type;
  406. public:
  407.     typedef char char_type;
  408.     struct category
  409.         : dual_use,
  410.           filter_tag,
  411.           multichar_tag,
  412.           closable_tag
  413.         { };
  414.     basic_gzip_decompressor( int window_bits = gzip::default_window_bits,
  415.                              int buffer_size = default_device_buffer_size );
  416.  
  417.     template<typename Sink>
  418.     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
  419.     {
  420.         std::streamsize result = 0;
  421.         while(result < n) {
  422.             if(state_ == s_start) {
  423.                 state_ = s_header;
  424.                 header_.reset();
  425.                 footer_.reset();
  426.             }
  427.             if (state_ == s_header) {
  428.                 int c = s[result++];
  429.                 header_.process(c);
  430.                 if (header_.done())
  431.                     state_ = s_body;
  432.             } else if (state_ == s_body) {
  433.                 BOOST_TRY {
  434.                     std::streamsize amt =
  435.                         base_type::write(snk, s + result, n - result);
  436.                     result += amt;
  437.                     if (!this->eof()) {
  438.                         break;
  439.                     } else {
  440.                         state_ = s_footer;
  441.                     }
  442.                 } BOOST_CATCH (const zlib_error& e) {
  443.                     mars_boost::throw_exception(gzip_error(e));
  444.                 }
  445.             } else { // state_ == s_footer
  446.                 if (footer_.done()) {
  447.                     if (footer_.crc() != this->crc())
  448.                         mars_boost::throw_exception(gzip_error(gzip::bad_crc));
  449.  
  450.                     base_type::close(snk, BOOST_IOS::out);
  451.                     state_ = s_start;
  452.                 } else {
  453.                     int c = s[result++];
  454.                     footer_.process(c);
  455.                 }
  456.             }
  457.         }
  458.         return result;
  459.     }
  460.  
  461.     template<typename Source>
  462.     std::streamsize read(Source& src, char_type* s, std::streamsize n)
  463.     {
  464.         typedef char_traits<char>  traits_type;
  465.         std::streamsize            result = 0;
  466.         peekable_source<Source>    peek(src, putback_);
  467.         while (result < n && state_ != s_done) {
  468.             if (state_ == s_start) {
  469.                 state_ = s_header;
  470.                 header_.reset();
  471.                 footer_.reset();
  472.             }
  473.             if (state_ == s_header) {
  474.                 int c = mars_boost::iostreams::get(peek);
  475.                 if (traits_type::is_eof(c)) {
  476.                     mars_boost::throw_exception(gzip_error(gzip::bad_header));
  477.                 } else if (traits_type::would_block(c)) {
  478.                     break;
  479.                 }
  480.                 header_.process(c);
  481.                 if (header_.done())
  482.                     state_ = s_body;
  483.             } else if (state_ == s_body) {
  484.                 BOOST_TRY {
  485.                     std::streamsize amt =
  486.                         base_type::read(peek, s + result, n - result);
  487.                     if (amt != -1) {
  488.                         result += amt;
  489.                         if (amt < n - result)
  490.                             break;
  491.                     } else {
  492.                         peek.putback(this->unconsumed_input());
  493.                         state_ = s_footer;
  494.                     }
  495.                 } BOOST_CATCH (const zlib_error& e) {
  496.                     mars_boost::throw_exception(gzip_error(e));
  497.                 } BOOST_CATCH_END
  498.             } else { // state_ == s_footer
  499.                 int c = mars_boost::iostreams::get(peek);
  500.                 if (traits_type::is_eof(c)) {
  501.                     mars_boost::throw_exception(gzip_error(gzip::bad_footer));
  502.                 } else if (traits_type::would_block(c)) {
  503.                     break;
  504.                 }
  505.                 footer_.process(c);
  506.                 if (footer_.done()) {
  507.                     if (footer_.crc() != this->crc())
  508.                         mars_boost::throw_exception(gzip_error(gzip::bad_crc));
  509.                     int c = mars_boost::iostreams::get(peek);
  510.                     if (traits_type::is_eof(c)) {
  511.                         state_ = s_done;
  512.                     } else {
  513.                         peek.putback(c);
  514.                         base_type::close(peek, BOOST_IOS::in);
  515.                         state_ = s_start;
  516.                         header_.reset();
  517.                         footer_.reset();
  518.                     }
  519.                 }
  520.             }
  521.         }
  522.         if (peek.has_unconsumed_input()) {
  523.             putback_ = peek.unconsumed_input();
  524.         } else {
  525.             putback_.clear();
  526.         }
  527.         return result != 0 || state_ != s_done ?
  528.             result :
  529.             -1;
  530.     }
  531.  
  532.     template<typename Source>
  533.     void close(Source& src, BOOST_IOS::openmode m)
  534.     {
  535.         BOOST_TRY {
  536.             base_type::close(src, m);
  537.         } BOOST_CATCH (const zlib_error& e) {
  538.             state_ = s_start;
  539.             mars_boost::throw_exception(gzip_error(e));
  540.         } BOOST_CATCH_END
  541.         if (m == BOOST_IOS::out) {
  542.             if (state_ == s_start || state_ == s_header)
  543.                 mars_boost::throw_exception(gzip_error(gzip::bad_header));
  544.             else if (state_ == s_body)
  545.                 mars_boost::throw_exception(gzip_error(gzip::bad_footer));
  546.             else if (state_ == s_footer) {
  547.                 if (!footer_.done())
  548.                     mars_boost::throw_exception(gzip_error(gzip::bad_footer));
  549.                 else if(footer_.crc() != this->crc())
  550.                     mars_boost::throw_exception(gzip_error(gzip::bad_crc));
  551.             } else {
  552.                 BOOST_ASSERT(!"Bad state");
  553.             }
  554.         }
  555.         state_ = s_start;
  556.     }
  557.  
  558.     std::string file_name() const { return header_.file_name(); }
  559.     std::string comment() const { return header_.comment(); }
  560.     bool text() const { return header_.text(); }
  561.     int os() const { return header_.os(); }
  562.     std::time_t mtime() const { return header_.mtime(); }
  563. private:
  564.     static gzip_params make_params(int window_bits);
  565.  
  566.     // Source adapter allowing an arbitrary character sequence to be put back.
  567.     template<typename Source>
  568.     struct peekable_source {
  569.         typedef char char_type;
  570.         struct category : source_tag, peekable_tag { };
  571.         explicit peekable_source(Source& src, const string_type& putback = "")
  572.             : src_(src), putback_(putback), offset_(0)
  573.             { }
  574.         std::streamsize read(char* s, std::streamsize n)
  575.         {
  576.             std::streamsize result = 0;
  577.  
  578.             // Copy characters from putback buffer
  579.             std::streamsize pbsize =
  580.                 static_cast<std::streamsize>(putback_.size());
  581.             if (offset_ < pbsize) {
  582.                 result = (std::min)(n, pbsize - offset_);
  583.                 BOOST_IOSTREAMS_CHAR_TRAITS(char)::copy(
  584.                     s, putback_.data() + offset_, result);
  585.                 offset_ += result;
  586.                 if (result == n)
  587.                     return result;
  588.             }
  589.  
  590.             // Read characters from src_
  591.             std::streamsize amt =
  592.                 mars_boost::iostreams::read(src_, s + result, n - result);
  593.             return amt != -1 ?
  594.                 result + amt :
  595.                 result ? result : -1;
  596.         }
  597.         bool putback(char c)
  598.         {
  599.             if (offset_) {
  600.                 putback_[--offset_] = c;
  601.             } else {
  602.                 mars_boost::throw_exception(
  603.                     mars_boost::iostreams::detail::bad_putback());
  604.             }
  605.             return true;
  606.         }
  607.         void putback(const string_type& s)
  608.         {
  609.             putback_.replace(0, offset_, s);
  610.             offset_ = 0;
  611.         }
  612.  
  613.         // Returns true if some characters have been putback but not re-read.
  614.         bool has_unconsumed_input() const
  615.         {
  616.             return offset_ < static_cast<std::streamsize>(putback_.size());
  617.         }
  618.  
  619.         // Returns the sequence of characters that have been put back but not re-read.
  620.         string_type unconsumed_input() const
  621.         {
  622.             return string_type(putback_, offset_, putback_.size() - offset_);
  623.         }
  624.         Source&          src_;
  625.         string_type      putback_;
  626.         std::streamsize  offset_;
  627.     };
  628.  
  629.     enum state_type {
  630.         s_start   = 1,
  631.         s_header  = s_start + 1,
  632.         s_body    = s_header + 1,
  633.         s_footer  = s_body + 1,
  634.         s_done    = s_footer + 1
  635.     };
  636.     detail::gzip_header  header_;
  637.     detail::gzip_footer  footer_;
  638.     string_type          putback_;
  639.     int                  state_;
  640. };
  641. BOOST_IOSTREAMS_PIPABLE(basic_gzip_decompressor, 1)
  642.  
  643. typedef basic_gzip_decompressor<> gzip_decompressor;
  644.  
  645. //------------------Implementation of gzip_compressor-------------------------//
  646.  
  647. template<typename Alloc>
  648. basic_gzip_compressor<Alloc>::basic_gzip_compressor
  649.     (const gzip_params& p, int buffer_size)
  650.     : base_type(normalize_params(p), buffer_size),
  651.       offset_(0), flags_(0)
  652. {
  653.     // Calculate gzip header.
  654.     bool has_name = !p.file_name.empty();
  655.     bool has_comment = !p.comment.empty();
  656.  
  657.     std::string::size_type length =
  658.         10 +
  659.         (has_name ? p.file_name.size() + 1 : 0) +
  660.         (has_comment ? p.comment.size() + 1 : 0);
  661.         // + 2; // Header crc confuses gunzip.
  662.     int flags =
  663.         //gzip::flags::header_crc +
  664.         (has_name ? gzip::flags::name : 0) +
  665.         (has_comment ? gzip::flags::comment : 0);
  666.     int extra_flags =
  667.         ( p.level == zlib::best_compression ?
  668.               gzip::extra_flags::best_compression :
  669.               0 ) +
  670.         ( p.level == zlib::best_speed ?
  671.               gzip::extra_flags::best_speed :
  672.               0 );
  673.     header_.reserve(length);
  674.     header_ += gzip::magic::id1;                         // ID1.
  675.     header_ += gzip::magic::id2;                         // ID2.
  676.     header_ += gzip::method::deflate;                    // CM.
  677.     header_ += static_cast<char>(flags);                 // FLG.
  678.     header_ += static_cast<char>(0xFF & p.mtime);        // MTIME.
  679.     header_ += static_cast<char>(0xFF & (p.mtime >> 8));
  680.     header_ += static_cast<char>(0xFF & (p.mtime >> 16));
  681.     header_ += static_cast<char>(0xFF & (p.mtime >> 24));
  682.     header_ += static_cast<char>(extra_flags);           // XFL.
  683.     header_ += static_cast<char>(gzip::os_unknown);      // OS.
  684.     if (has_name) {
  685.         header_ += p.file_name;
  686.         header_ += '\0';
  687.     }
  688.     if (has_comment) {
  689.         header_ += p.comment;
  690.         header_ += '\0';
  691.     }
  692. }
  693.  
  694. template<typename Alloc>
  695. gzip_params basic_gzip_compressor<Alloc>::normalize_params(gzip_params p)
  696. {
  697.     p.noheader = true;
  698.     p.calculate_crc = true;
  699.     return p;
  700. }
  701.  
  702. template<typename Alloc>
  703. void basic_gzip_compressor<Alloc>::prepare_footer()
  704. {
  705.     mars_boost::iostreams::back_insert_device<std::string> out(footer_);
  706.     write_long(this->crc(), out);
  707.     write_long(this->total_in(), out);
  708.     flags_ |= f_body_done;
  709.     offset_ = 0;
  710. }
  711.  
  712. template<typename Alloc>
  713. std::streamsize basic_gzip_compressor<Alloc>::read_string
  714.     (char* s, std::streamsize n, std::string& str)
  715. {
  716.     std::streamsize avail =
  717.         static_cast<std::streamsize>(str.size() - offset_);
  718.     std::streamsize amt = (std::min)(avail, n);
  719.     std::copy( str.data() + offset_,
  720.                str.data() + offset_ + amt,
  721.                s );
  722.     offset_ += amt;
  723.     if ( !(flags_ & f_header_done) &&
  724.          offset_ == static_cast<std::size_t>(str.size()) )
  725.     {
  726.         flags_ |= f_header_done;
  727.     }
  728.     return amt;
  729. }
  730.  
  731. //------------------Implementation of gzip_decompressor-----------------------//
  732.  
  733. template<typename Alloc>
  734. basic_gzip_decompressor<Alloc>::basic_gzip_decompressor
  735.     (int window_bits, int buffer_size)
  736.     : base_type(make_params(window_bits), buffer_size),
  737.       state_(s_start)
  738.     { }
  739.  
  740. template<typename Alloc>
  741. gzip_params basic_gzip_decompressor<Alloc>::make_params(int window_bits)
  742. {
  743.     gzip_params p;
  744.     p.window_bits = window_bits;
  745.     p.noheader = true;
  746.     p.calculate_crc = true;
  747.     return p;
  748. }
  749.  
  750. //----------------------------------------------------------------------------//
  751.  
  752. } } // End namespaces iostreams, boost.
  753.  
  754. #if defined(BOOST_MSVC)
  755. # pragma warning(pop)
  756. #endif
  757.  
  758. #endif // #ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED
  759.  
downloadgzip.hpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top