bzip2.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 398 行
HPP
398 行
// (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_BZIP2_HPP_INCLUDED#define BOOST_IOSTREAMS_BZIP2_HPP_INCLUDED#if defined(_MSC_VER) && (_MSC_VER >= 1020)# pragma once#endif #include <cassert> #include <memory> // allocator.#include <new> // bad_alloc.#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/bzip2.hpp>#include <boost/iostreams/detail/config/dyn_link.hpp>#include <boost/iostreams/detail/config/wide_streams.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)#endif#include <boost/config/abi_prefix.hpp> // Temporary fix.#undef smallnamespace boost { namespace iostreams {namespace bzip2 { // Typedefs.typedef void* (*alloc_func)(void*, int, int);typedef void (*free_func)(void*, void*); // Status codesBOOST_IOSTREAMS_DECL extern const int ok;BOOST_IOSTREAMS_DECL extern const int run_ok;BOOST_IOSTREAMS_DECL extern const int flush_ok;BOOST_IOSTREAMS_DECL extern const int finish_ok;BOOST_IOSTREAMS_DECL extern const int stream_end; BOOST_IOSTREAMS_DECL extern const int sequence_error;BOOST_IOSTREAMS_DECL extern const int param_error;BOOST_IOSTREAMS_DECL extern const int mem_error;BOOST_IOSTREAMS_DECL extern const int data_error;BOOST_IOSTREAMS_DECL extern const int data_error_magic;BOOST_IOSTREAMS_DECL extern const int io_error;BOOST_IOSTREAMS_DECL extern const int unexpected_eof;BOOST_IOSTREAMS_DECL extern const int outbuff_full;BOOST_IOSTREAMS_DECL extern const int config_error; // Action codesBOOST_IOSTREAMS_DECL extern const int finish;BOOST_IOSTREAMS_DECL extern const int run; // Default valuesconst int default_block_size = 9;const int default_work_factor = 30;const bool default_small = false;} // End namespace bzip2. //// Class name: bzip2_params.// Description: Encapsulates the parameters passed to deflateInit2// to customize compression.//struct bzip2_params { // Non-explicit constructor for compression. bzip2_params( int block_size = bzip2::default_block_size, int work_factor = bzip2::default_work_factor ) : block_size(block_size), work_factor(work_factor) { } // Constructor for decompression. bzip2_params(bool small) : small(small), work_factor(0) { } union { int block_size; // For compression. bool small; // For decompression. }; int work_factor;};//// Class name: bzip2_error.// Description: Subclass of std::ios_base::failure thrown to indicate// bzip2 errors other than out-of-memory conditions.//class BOOST_IOSTREAMS_DECL bzip2_error : public BOOST_IOSTREAMS_FAILURE {public: explicit bzip2_error(int error); int error() const { return error_; } static void check(int error);private: int error_;};namespace detail {template<typename Alloc>struct bzip2_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 bzip2_allocator_traits<Alloc>::type >struct bzip2_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 bzip2_allocator_traits<Alloc>::type allocator_type; static void* allocate(void* self, int items, int size); static void deallocate(void* self, void* address);};class BOOST_IOSTREAMS_DECL bzip2_base { public: typedef char char_type;protected: bzip2_base(const bzip2_params& params); ~bzip2_base(); bzip2_params& params() { return params_; } bool& ready() { return ready_; } template<typename Alloc> void init( bool compress, bzip2_allocator<Alloc>& alloc ) { bool custom = bzip2_allocator<Alloc>::custom; do_init( compress, #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) custom ? bzip2_allocator<Alloc>::allocate : 0, custom ? bzip2_allocator<Alloc>::deallocate : 0, #endif custom ? &alloc : 0 ); } 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); int compress(int action); int decompress(); void end(bool compress);private: void do_init( bool compress, #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) bzip2::alloc_func, bzip2::free_func, #endif void* derived ); bzip2_params params_; void* stream_; // Actual type: bz_stream*. bool ready_;};//// Template name: bzip2_compressor_impl// Description: Model of SymmetricFilter implementing compression by// delegating to the libbzip2 function BZ_bzCompress.//template<typename Alloc = std::allocator<char> >class bzip2_compressor_impl : public bzip2_base, #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) public #endif bzip2_allocator<Alloc> {public: bzip2_compressor_impl(const bzip2_params&); bool filter( const char*& src_begin, const char* src_end, char*& dest_begin, char* dest_end, bool flush ); void close();private: void init();};//// Template name: bzip2_compressor// Description: Model of SymmetricFilter implementing decompression by// delegating to the libbzip2 function BZ_bzDecompress.//template<typename Alloc = std::allocator<char> >class bzip2_decompressor_impl : public bzip2_base, #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) public #endif bzip2_allocator<Alloc> { public: bzip2_decompressor_impl(bool small = bzip2::default_small); bool filter( const char*& begin_in, const char* end_in, char*& begin_out, char* end_out, bool flush ); void close();private: void init(); bool eof_; // Guard to make sure filter() isn't called after it returns false.};} // End namespace detail.//// Template name: bzip2_compressor// Description: Model of InputFilter and OutputFilter implementing// compression using libbzip2.//template<typename Alloc = std::allocator<char> >struct basic_bzip2_compressor : symmetric_filter<detail::bzip2_compressor_impl<Alloc>, Alloc> {private: typedef detail::bzip2_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_bzip2_compressor( const bzip2_params& = bzip2::default_block_size, int buffer_size = default_device_buffer_size );};BOOST_IOSTREAMS_PIPABLE(basic_bzip2_compressor, 1)typedef basic_bzip2_compressor<> bzip2_compressor;//// Template name: bzip2_decompressor// Description: Model of InputFilter and OutputFilter implementing// decompression using libbzip2.//template<typename Alloc = std::allocator<char> >struct basic_bzip2_decompressor : symmetric_filter<detail::bzip2_decompressor_impl<Alloc>, Alloc> {private: typedef detail::bzip2_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_bzip2_decompressor( bool small = bzip2::default_small, int buffer_size = default_device_buffer_size );};BOOST_IOSTREAMS_PIPABLE(basic_bzip2_decompressor, 1)typedef basic_bzip2_decompressor<> bzip2_decompressor;//----------------------------------------------------------------------------////------------------Implementation of bzip2_allocator-------------------------//namespace detail {template<typename Alloc, typename Base>void* bzip2_allocator<Alloc, Base>::allocate(void* self, int items, int 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 bzip2_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 bzip2_compressor_impl-------------------//template<typename Alloc>bzip2_compressor_impl<Alloc>::bzip2_compressor_impl(const bzip2_params& p) : bzip2_base(p) { }template<typename Alloc>bool bzip2_compressor_impl<Alloc>::filter ( const char*& src_begin, const char* src_end, char*& dest_begin, char* dest_end, bool flush ){ if (!ready()) init(); before(src_begin, src_end, dest_begin, dest_end); int result = compress(flush ? bzip2::finish : bzip2::run); after(src_begin, dest_begin); bzip2_error::check(result); return result != bzip2::stream_end;}template<typename Alloc>void bzip2_compressor_impl<Alloc>::close() { end(true); }template<typename Alloc>inline void bzip2_compressor_impl<Alloc>::init() { bzip2_base::init(true, static_cast<bzip2_allocator<Alloc>&>(*this)); }//------------------Implementation of bzip2_decompressor_impl-----------------//template<typename Alloc>bzip2_decompressor_impl<Alloc>::bzip2_decompressor_impl(bool small) : bzip2_base(bzip2_params(small)), eof_(false) { }template<typename Alloc>bool bzip2_decompressor_impl<Alloc>::filter ( const char*& src_begin, const char* src_end, char*& dest_begin, char* dest_end, bool /* flush */ ){ if (!ready()) init(); if (eof_) return false; before(src_begin, src_end, dest_begin, dest_end); int result = decompress(); after(src_begin, dest_begin); bzip2_error::check(result); return !(eof_ = result == bzip2::stream_end); }template<typename Alloc>void bzip2_decompressor_impl<Alloc>::close() { try { end(false); } catch (...) { eof_ = false; throw; } eof_ = false;}template<typename Alloc>inline void bzip2_decompressor_impl<Alloc>::init(){ bzip2_base::init(false, static_cast<bzip2_allocator<Alloc>&>(*this)); }} // End namespace detail.//------------------Implementation of bzip2_decompressor----------------------//template<typename Alloc>basic_bzip2_compressor<Alloc>::basic_bzip2_compressor (const bzip2_params& p, int buffer_size) : base_type(buffer_size, p) { }//------------------Implementation of bzip2_decompressor----------------------//template<typename Alloc>basic_bzip2_decompressor<Alloc>::basic_bzip2_decompressor (bool small, int buffer_size) : base_type(buffer_size, small) { }//----------------------------------------------------------------------------//} } // 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_BZIP2_HPP_INCLUDED
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?