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 + -
显示快捷键?