zlib.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 417 行
HPP
417 行
// (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.// Note: custom allocators are not supported on VC6, since that compiler// had trouble finding the function zlib_base::do_init.#ifndef BOOST_IOSTREAMS_ZLIB_HPP_INCLUDED#define BOOST_IOSTREAMS_ZLIB_HPP_INCLUDED#if defined(_MSC_VER) && (_MSC_VER >= 1020)# pragma once#endif #include <cassert> #include <iosfwd> // streamsize. #include <memory> // allocator, bad_alloc.#include <new> #include <boost/config.hpp> // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM.#include <boost/detail/workaround.hpp>#include <boost/iostreams/constants.hpp> // buffer size.#include <boost/iostreams/detail/config/auto_link.hpp>#include <boost/iostreams/detail/config/dyn_link.hpp>#include <boost/iostreams/detail/config/wide_streams.hpp>#include <boost/iostreams/detail/config/zlib.hpp>#include <boost/iostreams/detail/ios.hpp> // failure, streamsize.#include <boost/iostreams/filter/symmetric.hpp> #include <boost/iostreams/pipeline.hpp> #include <boost/type_traits/is_same.hpp>// Must come last.#ifdef BOOST_MSVC# pragma warning(push)# pragma warning(disable:4251 4231 4660) // Dependencies not exported.#endif#include <boost/config/abi_prefix.hpp> namespace boost { namespace iostreams {namespace zlib { // Typedefstypedef unsigned int uint;typedef unsigned char byte;typedef unsigned long ulong;typedef void* (*alloc_func)(void*, zlib::uint, zlib::uint);typedef void (*free_func)(void*, void*); // Compression levelsBOOST_IOSTREAMS_DECL extern const int no_compression;BOOST_IOSTREAMS_DECL extern const int best_speed;BOOST_IOSTREAMS_DECL extern const int best_compression;BOOST_IOSTREAMS_DECL extern const int default_compression; // Compression methodsBOOST_IOSTREAMS_DECL extern const int deflated; // Compression strategiesBOOST_IOSTREAMS_DECL extern const int default_strategy;BOOST_IOSTREAMS_DECL extern const int filtered;BOOST_IOSTREAMS_DECL extern const int huffman_only; // Status codesBOOST_IOSTREAMS_DECL extern const int okay;BOOST_IOSTREAMS_DECL extern const int stream_end;BOOST_IOSTREAMS_DECL extern const int stream_error;BOOST_IOSTREAMS_DECL extern const int version_error;BOOST_IOSTREAMS_DECL extern const int data_error;BOOST_IOSTREAMS_DECL extern const int mem_error;BOOST_IOSTREAMS_DECL extern const int buf_error; // Flush codesBOOST_IOSTREAMS_DECL extern const int finish;BOOST_IOSTREAMS_DECL extern const int no_flush;BOOST_IOSTREAMS_DECL extern const int sync_flush; // Code for current OS//BOOST_IOSTREAMS_DECL extern const int os_code; // Null pointer constant.const int null = 0; // Default valuesconst int default_window_bits = 15;const int default_mem_level = 8;const bool default_crc = false;const bool default_noheader = false;} // End namespace zlib. //// Class name: zlib_params.// Description: Encapsulates the parameters passed to deflateInit2// and inflateInit2 to customize compression and decompression.//struct zlib_params { // Non-explicit constructor. zlib_params( int level = zlib::default_compression, int method = zlib::deflated, int window_bits = zlib::default_window_bits, int mem_level = zlib::default_mem_level, int strategy = zlib::default_strategy, bool noheader = zlib::default_noheader, bool calculate_crc = zlib::default_crc ) : level(level), method(method), window_bits(window_bits), mem_level(mem_level), strategy(strategy), noheader(noheader), calculate_crc(calculate_crc) { } int level; int method; int window_bits; int mem_level; int strategy; bool noheader; bool calculate_crc;};//// Class name: zlib_error.// Description: Subclass of std::ios::failure thrown to indicate// zlib errors other than out-of-memory conditions.//class BOOST_IOSTREAMS_DECL zlib_error : public BOOST_IOSTREAMS_FAILURE {public: explicit zlib_error(int error); int error() const { return error_; } static void check(int error);private: int error_;};namespace detail {template<typename Alloc>struct zlib_allocator_traits {#ifndef BOOST_NO_STD_ALLOCATOR typedef typename Alloc::template rebind<char>::other type;#else typedef std::allocator<char> type;#endif};template< typename Alloc, typename Base = // VC6 workaround (C2516) BOOST_DEDUCED_TYPENAME zlib_allocator_traits<Alloc>::type >struct zlib_allocator : private Base {private: typedef typename Base::size_type size_type;public: BOOST_STATIC_CONSTANT(bool, custom = (!is_same<std::allocator<char>, Base>::value)); typedef typename zlib_allocator_traits<Alloc>::type allocator_type; static void* allocate(void* self, zlib::uint items, zlib::uint size); static void deallocate(void* self, void* address);};class BOOST_IOSTREAMS_DECL zlib_base { public: typedef char char_type;protected: zlib_base(); ~zlib_base(); void* stream() { return stream_; } template<typename Alloc> void init( const zlib_params& p, bool compress, zlib_allocator<Alloc>& zalloc ) { bool custom = zlib_allocator<Alloc>::custom; do_init( p, compress, #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) custom ? zlib_allocator<Alloc>::allocate : 0, custom ? zlib_allocator<Alloc>::deallocate : 0, #endif &zalloc ); } void before( const char*& src_begin, const char* src_end, char*& dest_begin, char* dest_end ); void after( const char*& src_begin, char*& dest_begin, bool compress ); int deflate(int flush); int inflate(int flush); void reset(bool compress, bool realloc);public: zlib::ulong crc() const { return crc_; } int total_in() const { return total_in_; } int total_out() const { return total_out_; }private: void do_init( const zlib_params& p, bool compress, #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) zlib::alloc_func, zlib::free_func, #endif void* derived ); void* stream_; // Actual type: z_stream*. bool calculate_crc_; zlib::ulong crc_; int total_in_; int total_out_;};//// Template name: zlib_compressor_impl// Description: Model of C-Style Filte implementing compression by// delegating to the zlib function deflate.//template<typename Alloc = std::allocator<char> >class zlib_compressor_impl : public zlib_base, public zlib_allocator<Alloc> { public: zlib_compressor_impl(const zlib_params& = zlib::default_compression); ~zlib_compressor_impl(); bool filter( const char*& src_begin, const char* src_end, char*& dest_begin, char* dest_end, bool flush ); void close();};//// Template name: zlib_compressor// Description: Model of C-Style Filte implementing decompression by// delegating to the zlib function inflate.//template<typename Alloc = std::allocator<char> >class zlib_decompressor_impl : public zlib_base, public zlib_allocator<Alloc> {public: zlib_decompressor_impl(const zlib_params&); zlib_decompressor_impl(int window_bits = zlib::default_window_bits); ~zlib_decompressor_impl(); bool filter( const char*& begin_in, const char* end_in, char*& begin_out, char* end_out, bool flush ); void close();};} // End namespace detail.//// Template name: zlib_compressor// Description: Model of InputFilter and OutputFilter implementing// compression using zlib.//template<typename Alloc = std::allocator<char> >struct basic_zlib_compressor : symmetric_filter<detail::zlib_compressor_impl<Alloc>, Alloc> {private: typedef detail::zlib_compressor_impl<Alloc> impl_type; typedef symmetric_filter<impl_type, Alloc> base_type;public: typedef typename base_type::char_type char_type; typedef typename base_type::category category; basic_zlib_compressor( const zlib_params& = zlib::default_compression, int buffer_size = default_device_buffer_size ); zlib::ulong crc() { return this->filter().crc(); } int total_in() { return this->filter().total_in(); }};BOOST_IOSTREAMS_PIPABLE(basic_zlib_compressor, 1)typedef basic_zlib_compressor<> zlib_compressor;//// Template name: zlib_decompressor// Description: Model of InputFilter and OutputFilter implementing// decompression using zlib.//template<typename Alloc = std::allocator<char> >struct basic_zlib_decompressor : symmetric_filter<detail::zlib_decompressor_impl<Alloc>, Alloc> {private: typedef detail::zlib_decompressor_impl<Alloc> impl_type; typedef symmetric_filter<impl_type, Alloc> base_type;public: typedef typename base_type::char_type char_type; typedef typename base_type::category category; basic_zlib_decompressor( int window_bits = zlib::default_window_bits, int buffer_size = default_device_buffer_size ); basic_zlib_decompressor( const zlib_params& p, int buffer_size = default_device_buffer_size ); zlib::ulong crc() { return this->filter().crc(); } int total_out() { return this->filter().total_out(); }};BOOST_IOSTREAMS_PIPABLE(basic_zlib_decompressor, 1)typedef basic_zlib_decompressor<> zlib_decompressor;//----------------------------------------------------------------------------////------------------Implementation of zlib_allocator--------------------------//namespace detail {template<typename Alloc, typename Base>void* zlib_allocator<Alloc, Base>::allocate (void* self, zlib::uint items, zlib::uint size){ size_type len = items * size; char* ptr = static_cast<allocator_type*>(self)->allocate (len + sizeof(size_type) #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) , (char*)0 #endif ); *reinterpret_cast<size_type*>(ptr) = len; return ptr + sizeof(size_type);}template<typename Alloc, typename Base>void zlib_allocator<Alloc, Base>::deallocate(void* self, void* address){ char* ptr = reinterpret_cast<char*>(address) - sizeof(size_type); size_type len = *reinterpret_cast<size_type*>(ptr) + sizeof(size_type); static_cast<allocator_type*>(self)->deallocate(ptr, len); }//------------------Implementation of zlib_compressor_impl--------------------//template<typename Alloc>zlib_compressor_impl<Alloc>::zlib_compressor_impl(const zlib_params& p){ init(p, true, static_cast<zlib_allocator<Alloc>&>(*this)); }template<typename Alloc>zlib_compressor_impl<Alloc>::~zlib_compressor_impl(){ reset(true, false); }template<typename Alloc>bool zlib_compressor_impl<Alloc>::filter ( const char*& src_begin, const char* src_end, char*& dest_begin, char* dest_end, bool flush ){ before(src_begin, src_end, dest_begin, dest_end); int result = deflate(flush ? zlib::finish : zlib::no_flush); after(src_begin, dest_begin, true); zlib_error::check(result); return result != zlib::stream_end; }template<typename Alloc>void zlib_compressor_impl<Alloc>::close() { reset(true, true); }//------------------Implementation of zlib_decompressor_impl------------------//template<typename Alloc>zlib_decompressor_impl<Alloc>::zlib_decompressor_impl(const zlib_params& p){ init(p, false, static_cast<zlib_allocator<Alloc>&>(*this)); }template<typename Alloc>zlib_decompressor_impl<Alloc>::~zlib_decompressor_impl(){ reset(false, false); }template<typename Alloc>zlib_decompressor_impl<Alloc>::zlib_decompressor_impl(int window_bits){ zlib_params p; p.window_bits = window_bits; init(p, false, static_cast<zlib_allocator<Alloc>&>(*this)); }template<typename Alloc>bool zlib_decompressor_impl<Alloc>::filter ( const char*& src_begin, const char* src_end, char*& dest_begin, char* dest_end, bool /* flush */ ){ before(src_begin, src_end, dest_begin, dest_end); int result = inflate(zlib::sync_flush); after(src_begin, dest_begin, false); zlib_error::check(result); return result != zlib::stream_end;}template<typename Alloc>void zlib_decompressor_impl<Alloc>::close() { reset(false, true); }} // End namespace detail.//------------------Implementation of zlib_decompressor-----------------------//template<typename Alloc>basic_zlib_compressor<Alloc>::basic_zlib_compressor (const zlib_params& p, int buffer_size) : base_type(buffer_size, p) { }//------------------Implementation of zlib_decompressor-----------------------//template<typename Alloc>basic_zlib_decompressor<Alloc>::basic_zlib_decompressor (int window_bits, int buffer_size) : base_type(buffer_size, window_bits) { }template<typename Alloc>basic_zlib_decompressor<Alloc>::basic_zlib_decompressor (const zlib_params& p, int buffer_size) : base_type(buffer_size, p) { }//----------------------------------------------------------------------------//} } // End namespaces iostreams, boost.#include <boost/config/abi_suffix.hpp> // Pops abi_suffix.hpp pragmas.#ifdef BOOST_MSVC# pragma warning(pop)#endif#endif // #ifndef BOOST_IOSTREAMS_ZLIB_HPP_INCLUDED
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?