1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) 2 // (C) Copyright 2003-2007 Jonathan Turkanis 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) 5 6 // See http://www.boost.org/libs/iostreams for documentation. 7 8 // To configure Boost to work with libbz2, see the 9 // installation instructions here: 10 // http://boost.org/libs/iostreams/doc/index.html?path=7 11 12 // Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp> 13 // knows that we are building the library (possibly exporting code), rather 14 // than using it (possibly importing code). 15 #define BOOST_IOSTREAMS_SOURCE 16 17 #include <boost/iostreams/detail/config/dyn_link.hpp> 18 #include <boost/iostreams/filter/gzip.hpp> 19 #include <boost/throw_exception.hpp> 20 21 namespace boost { namespace iostreams { 22 23 //------------------Implementation of gzip_header-----------------------------// 24 25 namespace detail { 26 process(char c)27void gzip_header::process(char c) 28 { 29 uint8_t value = static_cast<uint8_t>(c); 30 switch (state_) { 31 case s_id1: 32 if (value != gzip::magic::id1) 33 boost::throw_exception(gzip_error(gzip::bad_header)); 34 state_ = s_id2; 35 break; 36 case s_id2: 37 if (value != gzip::magic::id2) 38 boost::throw_exception(gzip_error(gzip::bad_header)); 39 state_ = s_cm; 40 break; 41 case s_cm: 42 if (value != gzip::method::deflate) 43 boost::throw_exception(gzip_error(gzip::bad_method)); 44 state_ = s_flg; 45 break; 46 case s_flg: 47 flags_ = value; 48 state_ = s_mtime; 49 break; 50 case s_mtime: 51 mtime_ += value << (offset_ * 8); 52 if (offset_ == 3) { 53 state_ = s_xfl; 54 offset_ = 0; 55 } else { 56 ++offset_; 57 } 58 break; 59 case s_xfl: 60 state_ = s_os; 61 break; 62 case s_os: 63 os_ = value; 64 if (flags_ & gzip::flags::extra) { 65 state_ = s_xlen; 66 } else if (flags_ & gzip::flags::name) { 67 state_ = s_name; 68 } else if (flags_ & gzip::flags::comment) { 69 state_ = s_comment; 70 } else if (flags_ & gzip::flags::header_crc) { 71 state_ = s_hcrc; 72 } else { 73 state_ = s_done; 74 } 75 break; 76 case s_xlen: 77 xlen_ += value << (offset_ * 8); 78 if (offset_ == 1) { 79 state_ = s_extra; 80 offset_ = 0; 81 } else { 82 ++offset_; 83 } 84 break; 85 case s_extra: 86 if (--xlen_ == 0) { 87 if (flags_ & gzip::flags::name) { 88 state_ = s_name; 89 } else if (flags_ & gzip::flags::comment) { 90 state_ = s_comment; 91 } else if (flags_ & gzip::flags::header_crc) { 92 state_ = s_hcrc; 93 } else { 94 state_ = s_done; 95 } 96 } 97 break; 98 case s_name: 99 if (c != 0) { 100 file_name_ += c; 101 } else if (flags_ & gzip::flags::comment) { 102 state_ = s_comment; 103 } else if (flags_ & gzip::flags::header_crc) { 104 state_ = s_hcrc; 105 } else { 106 state_ = s_done; 107 } 108 break; 109 case s_comment: 110 if (c != 0) { 111 comment_ += c; 112 } else if (flags_ & gzip::flags::header_crc) { 113 state_ = s_hcrc; 114 } else { 115 state_ = s_done; 116 } 117 break; 118 case s_hcrc: 119 if (offset_ == 1) { 120 state_ = s_done; 121 offset_ = 0; 122 } else { 123 ++offset_; 124 } 125 break; 126 default: 127 BOOST_ASSERT(0); 128 } 129 } 130 reset()131void gzip_header::reset() 132 { 133 file_name_.clear(); 134 comment_.clear(); 135 os_ = flags_ = offset_ = xlen_ = 0; 136 mtime_ = 0; 137 state_ = s_id1; 138 } 139 140 //------------------Implementation of gzip_footer-----------------------------// 141 process(char c)142void gzip_footer::process(char c) 143 { 144 uint8_t value = static_cast<uint8_t>(c); 145 if (state_ == s_crc) { 146 crc_ += value << (offset_ * 8); 147 if (offset_ == 3) { 148 state_ = s_isize; 149 offset_ = 0; 150 } else { 151 ++offset_; 152 } 153 } else if (state_ == s_isize) { 154 isize_ += value << (offset_ * 8); 155 if (offset_ == 3) { 156 state_ = s_done; 157 offset_ = 0; 158 } else { 159 ++offset_; 160 } 161 } else { 162 BOOST_ASSERT(0); 163 } 164 } 165 reset()166void gzip_footer::reset() 167 { 168 crc_ = isize_ = offset_ = 0; 169 state_ = s_crc; 170 } 171 172 } // End namespace boost::iostreams::detail. 173 174 } } // End namespaces iostreams, boost. 175