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 | |
27 | void 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(e: 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(e: 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(e: 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 | |
131 | void 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 | |
142 | void 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 | |
166 | void 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 |