| 1 | // (C) Copyright Jonathan Turkanis 2003. | 
|---|
| 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | 
|---|
| 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) | 
|---|
| 4 |  | 
|---|
| 5 | // See http://www.boost.org/libs/iostreams for documentation. | 
|---|
| 6 |  | 
|---|
| 7 | // To configure Boost to work with libbz2, see the  | 
|---|
| 8 | // installation instructions here: | 
|---|
| 9 | // http://boost.org/libs/iostreams/doc/index.html?path=7 | 
|---|
| 10 |  | 
|---|
| 11 | // Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp>  | 
|---|
| 12 | // knows that we are building the library (possibly exporting code), rather  | 
|---|
| 13 | // than using it (possibly importing code). | 
|---|
| 14 | #define BOOST_IOSTREAMS_SOURCE  | 
|---|
| 15 |  | 
|---|
| 16 | #include <boost/iostreams/detail/config/dyn_link.hpp> | 
|---|
| 17 | #include <boost/iostreams/filter/bzip2.hpp>  | 
|---|
| 18 | #include "bzlib.h"  // Julian Seward's "bzip.h" header. | 
|---|
| 19 |                     // To configure Boost to work with libbz2, see the  | 
|---|
| 20 |                     // installation instructions here: | 
|---|
| 21 |                     // http://boost.org/libs/iostreams/doc/index.html?path=7 | 
|---|
| 22 |                      | 
|---|
| 23 | namespace boost { namespace iostreams { | 
|---|
| 24 |  | 
|---|
| 25 | namespace bzip2 { | 
|---|
| 26 |  | 
|---|
| 27 |                     // Status codes | 
|---|
| 28 |  | 
|---|
| 29 | const int ok                   = BZ_OK; | 
|---|
| 30 | const int run_ok               = BZ_RUN_OK; | 
|---|
| 31 | const int flush_ok             = BZ_FLUSH_OK; | 
|---|
| 32 | const int finish_ok            = BZ_FINISH_OK; | 
|---|
| 33 | const int stream_end           = BZ_STREAM_END; | 
|---|
| 34 | const int sequence_error       = BZ_SEQUENCE_ERROR; | 
|---|
| 35 | const int param_error          = BZ_PARAM_ERROR; | 
|---|
| 36 | const int mem_error            = BZ_MEM_ERROR; | 
|---|
| 37 | const int data_error           = BZ_DATA_ERROR; | 
|---|
| 38 | const int data_error_magic     = BZ_DATA_ERROR_MAGIC; | 
|---|
| 39 | const int io_error             = BZ_IO_ERROR; | 
|---|
| 40 | const int unexpected_eof       = BZ_UNEXPECTED_EOF; | 
|---|
| 41 | const int outbuff_full         = BZ_OUTBUFF_FULL; | 
|---|
| 42 | const int config_error         = BZ_CONFIG_ERROR; | 
|---|
| 43 |  | 
|---|
| 44 |                     // Action codes | 
|---|
| 45 |  | 
|---|
| 46 | const int finish               = BZ_FINISH; | 
|---|
| 47 | const int run                  = BZ_RUN; | 
|---|
| 48 |  | 
|---|
| 49 | } // End namespace bzip2.  | 
|---|
| 50 |  | 
|---|
| 51 | //------------------Implementation of bzip2_error-----------------------------// | 
|---|
| 52 |                      | 
|---|
| 53 | bzip2_error::bzip2_error(int error) | 
|---|
| 54 |     : BOOST_IOSTREAMS_FAILURE("bzip2 error"), error_(error)  | 
|---|
| 55 |     { } | 
|---|
| 56 |  | 
|---|
| 57 | void bzip2_error::check(int error) | 
|---|
| 58 | { | 
|---|
| 59 |     switch (error) { | 
|---|
| 60 |     case BZ_OK:  | 
|---|
| 61 |     case BZ_RUN_OK:  | 
|---|
| 62 |     case BZ_FLUSH_OK: | 
|---|
| 63 |     case BZ_FINISH_OK: | 
|---|
| 64 |     case BZ_STREAM_END: | 
|---|
| 65 |         return; | 
|---|
| 66 |     case BZ_MEM_ERROR:  | 
|---|
| 67 |         throw std::bad_alloc(); | 
|---|
| 68 |     default: | 
|---|
| 69 |         throw bzip2_error(error); | 
|---|
| 70 |     } | 
|---|
| 71 | } | 
|---|
| 72 |  | 
|---|
| 73 | //------------------Implementation of bzip2_base------------------------------// | 
|---|
| 74 |  | 
|---|
| 75 | namespace detail { | 
|---|
| 76 |  | 
|---|
| 77 | bzip2_base::bzip2_base(const bzip2_params& params) | 
|---|
| 78 |     : params_(params), stream_(new bz_stream), ready_(false)  | 
|---|
| 79 |     { } | 
|---|
| 80 |  | 
|---|
| 81 | bzip2_base::~bzip2_base() { delete static_cast<bz_stream*>(stream_); } | 
|---|
| 82 |  | 
|---|
| 83 | void bzip2_base::before( const char*& src_begin, const char* src_end, | 
|---|
| 84 |                          char*& dest_begin, char* dest_end ) | 
|---|
| 85 | { | 
|---|
| 86 |     bz_stream* s = static_cast<bz_stream*>(stream_); | 
|---|
| 87 |     s->next_in = const_cast<char*>(src_begin); | 
|---|
| 88 |     s->avail_in = static_cast<unsigned>(src_end - src_begin); | 
|---|
| 89 |     s->next_out = reinterpret_cast<char*>(dest_begin); | 
|---|
| 90 |     s->avail_out= static_cast<unsigned>(dest_end - dest_begin); | 
|---|
| 91 | } | 
|---|
| 92 |  | 
|---|
| 93 | void bzip2_base::after(const char*& src_begin, char*& dest_begin) | 
|---|
| 94 | { | 
|---|
| 95 |     bz_stream* s = static_cast<bz_stream*>(stream_); | 
|---|
| 96 |     src_begin = const_cast<char*>(s->next_in); | 
|---|
| 97 |     dest_begin = s->next_out; | 
|---|
| 98 | } | 
|---|
| 99 |  | 
|---|
| 100 | void bzip2_base::end(bool compress) | 
|---|
| 101 | { | 
|---|
| 102 |     ready_ = false; | 
|---|
| 103 |     bz_stream* s = static_cast<bz_stream*>(stream_); | 
|---|
| 104 |     bzip2_error::check( | 
|---|
| 105 |         compress ? | 
|---|
| 106 |             BZ2_bzCompressEnd(s) :  | 
|---|
| 107 |             BZ2_bzDecompressEnd(s) | 
|---|
| 108 |     );  | 
|---|
| 109 | } | 
|---|
| 110 |  | 
|---|
| 111 | int bzip2_base::compress(int action) | 
|---|
| 112 | { | 
|---|
| 113 |     return BZ2_bzCompress(static_cast<bz_stream*>(stream_), action); | 
|---|
| 114 | } | 
|---|
| 115 |  | 
|---|
| 116 | int bzip2_base::decompress() | 
|---|
| 117 | { | 
|---|
| 118 |     return BZ2_bzDecompress(static_cast<bz_stream*>(stream_)); | 
|---|
| 119 | } | 
|---|
| 120 |  | 
|---|
| 121 | void bzip2_base::do_init | 
|---|
| 122 |     ( bool compress,  | 
|---|
| 123 |       #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) | 
|---|
| 124 |           bzip2::alloc_func alloc,  | 
|---|
| 125 |           bzip2::free_func free,  | 
|---|
| 126 |       #endif | 
|---|
| 127 |       void* derived ) | 
|---|
| 128 | { | 
|---|
| 129 |     bz_stream* s = static_cast<bz_stream*>(stream_); | 
|---|
| 130 |  | 
|---|
| 131 |     // Current interface for customizing memory management  | 
|---|
| 132 |     // is non-conforming and has been disabled: | 
|---|
| 133 |     //#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) | 
|---|
| 134 |     //    s->bzalloc = alloc; | 
|---|
| 135 |     //    s->bzfree = free; | 
|---|
| 136 |     //#else | 
|---|
| 137 |         s->bzalloc = 0; | 
|---|
| 138 |         s->bzfree = 0; | 
|---|
| 139 |     //#endif | 
|---|
| 140 |     s->opaque = derived; | 
|---|
| 141 |     bzip2_error::check(  | 
|---|
| 142 |         compress ? | 
|---|
| 143 |             BZ2_bzCompressInit( s, | 
|---|
| 144 |                                 params_.block_size,  | 
|---|
| 145 |                                 0,  | 
|---|
| 146 |                                 params_.work_factor ) : | 
|---|
| 147 |             BZ2_bzDecompressInit( s,  | 
|---|
| 148 |                                   0,  | 
|---|
| 149 |                                   params_.small ) | 
|---|
| 150 |     ); | 
|---|
| 151 |     ready_ = true; | 
|---|
| 152 | } | 
|---|
| 153 |  | 
|---|
| 154 | } // End namespace detail. | 
|---|
| 155 |  | 
|---|
| 156 | //----------------------------------------------------------------------------// | 
|---|
| 157 |  | 
|---|
| 158 | } } // End namespaces iostreams, boost. | 
|---|