gzip.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 605 行 · 第 1/2 页
HPP
605 行
// (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 <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/operations.hpp>#include <boost/iostreams/device/back_inserter.hpp>#include <boost/iostreams/filter/zlib.hpp>#include <boost/iostreams/pipeline.hpp> // Must come last.#if defined(BOOST_MSVC)# pragma warning(push)# pragma warning(disable: 4309) // Truncation of constant value.#endif#ifdef BOOST_NO_STDC_NAMESPACEnamespace std { using ::time_t; }#endifnamespace boost { namespace iostreams {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.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.//// 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;};//// 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_;};//// 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) { if (m == BOOST_IOS::out) { try { // Close zlib compressor. base_type::close(snk, 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(); } else { 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::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))); } 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 flag_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;//// Template name: basic_gzip_decompressor// Description: Model of InputFilter implementing compression in the// gzip format.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?