/Src/Dependencies/Boost/boost/iostreams/filter/gzip.hpp

http://hadesmem.googlecode.com/ · C++ Header · 757 lines · 601 code · 89 blank · 67 comment · 104 complexity · 02a8335b257da6bf49b5e38da710d579 MD5 · raw file

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