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
21namespace boost { namespace iostreams {
22
23//------------------Implementation of gzip_header-----------------------------//
24
25namespace detail {
26
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(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
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
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
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

source code of boost/libs/iostreams/src/gzip.cpp