Line data Source code
1 : /*
2 : Zipios -- a small C++ library that provides easy access to .zip files.
3 :
4 : Copyright (C) 2000-2007 Thomas Sondergaard
5 : Copyright (C) 2015-2019 Made to Order Software Corporation
6 :
7 : This library is free software; you can redistribute it and/or
8 : modify it under the terms of the GNU Lesser General Public
9 : License as published by the Free Software Foundation; either
10 : version 2.1 of the License, or (at your option) any later version.
11 :
12 : This library is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : Lesser General Public License for more details.
16 :
17 : You should have received a copy of the GNU Lesser General Public
18 : License along with this library; if not, write to the Free Software
19 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 : */
21 :
22 : /** \file
23 : * \brief Various functions used throughout the library.
24 : *
25 : * This file defines the Zipios common functions that are used
26 : * throughout the zipios library. At this point it is mainly the
27 : * low level I/O function to read and write to files or buffers.
28 : */
29 :
30 : #include "zipios_common.hpp"
31 :
32 : #include "zipios/zipiosexceptions.hpp"
33 :
34 :
35 : namespace zipios
36 : {
37 :
38 :
39 : /** \brief The character used as the filename separator.
40 : *
41 : * This character is used to separate filename segments in a path
42 : * in a Zip archive.
43 : *
44 : * \todo
45 : * It is "inadvertendly" also used as the separator
46 : * between filename segments of the file system. We
47 : * certainly want to support both "/" and "\\" to
48 : * make sure MS-Windows is fully supported. The FilePath
49 : * should take care of that work though.
50 : */
51 : char const g_separator = '/';
52 :
53 :
54 : /** \typedef std::ostringstream OutputStringStream;
55 : * \brief An output stream using strings.
56 : *
57 : * This object is used whenever we want to output a buffer from
58 : * a string and convert that to a string.
59 : */
60 :
61 :
62 : /** \typedef std::vector<unsigned char> buffer_t;
63 : * \brief A buffer of characters.
64 : *
65 : * This type is used to declare a buffer of characters. It is used in many
66 : * places.
67 : *
68 : * \todo
69 : * Move to the zipios-config.hpp file so we can also use it in our public
70 : * definitions?
71 : */
72 :
73 :
74 1787020 : void zipRead(std::istream& is, uint32_t& value)
75 : {
76 : unsigned char buf[sizeof(value)];
77 :
78 1787020 : if(!is.read(reinterpret_cast<char *>(buf), sizeof(value)))
79 : {
80 1 : throw IOException("an I/O error while reading zip archive data from file.");
81 : }
82 1787019 : if(is.gcount() != sizeof(value))
83 : {
84 : throw IOException("EOF or an I/O error while reading zip archive data from file."); // LCOV_EXCL_LINE
85 : }
86 :
87 : // zip data is always in little endian
88 1787019 : value = (buf[0] << 0)
89 1787019 : | (buf[1] << 8)
90 1787019 : | (buf[2] << 16)
91 1787019 : | (buf[3] << 24);
92 1787019 : }
93 :
94 :
95 2004193 : void zipRead(std::istream& is, uint16_t& value)
96 : {
97 : unsigned char buf[sizeof(value)];
98 :
99 2004193 : if(!is.read(reinterpret_cast<char *>(buf), sizeof(value)))
100 : {
101 1 : throw IOException("an I/O error while reading zip archive data from file.");
102 : }
103 2004192 : if(is.gcount() != sizeof(value))
104 : {
105 : throw IOException("EOF or an I/O error while reading zip archive data from file."); // LCOV_EXCL_LINE
106 : }
107 :
108 : // zip data is always in little endian
109 2004192 : value = (buf[0] << 0)
110 2004192 : | (buf[1] << 8);
111 2004192 : }
112 :
113 :
114 4 : void zipRead(std::istream& is, uint8_t& value)
115 : {
116 : unsigned char buf[sizeof(value)];
117 :
118 4 : if(!is.read(reinterpret_cast<char *>(buf), sizeof(value)))
119 : {
120 1 : throw IOException("an I/O error while reading zip archive data from file.");
121 : }
122 3 : if(is.gcount() != sizeof(value))
123 : {
124 : throw IOException("EOF or an I/O error while reading zip archive data from file."); // LCOV_EXCL_LINE
125 : }
126 :
127 : // zip data is always in little endian
128 3 : value = buf[0];
129 3 : }
130 :
131 :
132 314350 : void zipRead(std::istream& is, buffer_t& buffer, ssize_t const count)
133 : {
134 314350 : buffer.resize(count);
135 314350 : if(count > 0)
136 : {
137 6978 : if(!is.read(reinterpret_cast<char *>(&buffer[0]), count))
138 : {
139 1 : throw IOException("an I/O error while reading zip archive data from file.");
140 : }
141 6977 : if(is.gcount() != count)
142 : {
143 : throw IOException("EOF or an I/O error while reading zip archive data from file."); // LCOV_EXCL_LINE
144 : }
145 : }
146 314349 : }
147 :
148 :
149 422560 : void zipRead(std::istream& is, std::string& str, ssize_t const count)
150 : {
151 422560 : str.resize(count);
152 422560 : if(count > 0)
153 : {
154 313955 : if(!is.read(reinterpret_cast<char *>(&str[0]), count))
155 : {
156 1 : throw IOException("an I/O error while reading zip archive data from file.");
157 : }
158 313954 : if(is.gcount() != count)
159 : {
160 : throw IOException("EOF or an I/O error while reading zip archive data from file."); // LCOV_EXCL_LINE
161 : }
162 : }
163 422559 : }
164 :
165 :
166 2186 : void zipRead(buffer_t const& is, size_t& pos, uint32_t& value)
167 : {
168 2186 : if(pos + sizeof(value) > is.size())
169 : {
170 1 : throw IOException("EOF reached while reading zip archive data from file.");
171 : }
172 :
173 2185 : value = (is[pos + 0] << 0)
174 2185 : | (is[pos + 1] << 8)
175 2185 : | (is[pos + 2] << 16)
176 2185 : | (is[pos + 3] << 24);
177 :
178 2185 : pos += sizeof(value);
179 2185 : }
180 :
181 :
182 1673 : void zipRead(buffer_t const& is, size_t& pos, uint16_t& value)
183 : {
184 1673 : if(pos + sizeof(value) > is.size())
185 : {
186 1 : throw IOException("EOF reached while reading zip archive data from file.");
187 : }
188 :
189 1672 : value = (is[pos + 0] << 0)
190 1672 : | (is[pos + 1] << 8);
191 :
192 1672 : pos += sizeof(value);
193 1672 : }
194 :
195 :
196 4 : void zipRead(buffer_t const& is, size_t& pos, uint8_t& value)
197 : {
198 4 : if(pos + sizeof(value) > is.size())
199 : {
200 1 : throw IOException("EOF reached while reading zip archive data from file.");
201 : }
202 :
203 3 : value = is[pos];
204 :
205 3 : pos += sizeof(value);
206 3 : }
207 :
208 :
209 2 : void zipRead(buffer_t const& is, size_t& pos, buffer_t& buffer, ssize_t const count)
210 : {
211 2 : if(pos + count > is.size())
212 : {
213 1 : throw IOException("EOF reached while reading zip archive data from file.");
214 : }
215 :
216 1 : buffer.clear();
217 1 : buffer.insert(buffer.begin(), is.begin() + pos, is.begin() + pos + count);
218 :
219 1 : pos += count;
220 1 : }
221 :
222 :
223 335 : void zipRead(buffer_t const& is, size_t& pos, std::string& str, ssize_t const count)
224 : {
225 335 : if(pos + count > is.size())
226 : {
227 11 : throw IOException("EOF reached while reading zip archive data from file.");
228 : }
229 :
230 324 : str.clear();
231 324 : str.insert(str.begin(), is.begin() + pos, is.begin() + pos + count);
232 :
233 324 : pos += count;
234 324 : }
235 :
236 :
237 2915646 : void zipWrite(std::ostream& os, uint32_t const& value)
238 : {
239 : char buf[sizeof(value)];
240 :
241 2915646 : buf[0] = value >> 0;
242 2915646 : buf[1] = value >> 8;
243 2915646 : buf[2] = value >> 16;
244 2915646 : buf[3] = value >> 24;
245 :
246 2915646 : if(!os.write(buf, sizeof(value)))
247 : {
248 1 : throw IOException("an I/O error occurred while writing to a zip archive file.");
249 : }
250 2915645 : }
251 :
252 :
253 3259048 : void zipWrite(std::ostream& os, uint16_t const& value)
254 : {
255 : char buf[sizeof(value)];
256 :
257 3259048 : buf[0] = value >> 0;
258 3259048 : buf[1] = value >> 8;
259 :
260 3259048 : if(!os.write(buf, sizeof(value)))
261 : {
262 1 : throw IOException("an I/O error occurred while writing to a zip archive file.");
263 : }
264 3259047 : }
265 :
266 :
267 4 : void zipWrite(std::ostream& os, uint8_t const& value)
268 : {
269 : char buf[sizeof(value)];
270 :
271 4 : buf[0] = value;
272 :
273 4 : if(!os.write(buf, sizeof(value)))
274 : {
275 1 : throw IOException("an I/O error occurred while writing to a zip archive file.");
276 : }
277 3 : }
278 :
279 :
280 514399 : void zipWrite(std::ostream& os, buffer_t const& buffer)
281 : {
282 514399 : if(!os.write(reinterpret_cast<char const *>(&buffer[0]), buffer.size()))
283 : {
284 1 : throw IOException("an I/O error occurred while writing to a zip archive file.");
285 : }
286 514398 : }
287 :
288 :
289 686108 : void zipWrite(std::ostream& os, std::string const& str)
290 : {
291 686108 : if(!os.write(&str[0], str.length()))
292 : {
293 1 : throw IOException("an I/O error occurred while writing to a zip archive file.");
294 : }
295 686107 : }
296 :
297 :
298 3 : } // zipios namespace
299 :
300 : // Local Variables:
301 : // mode: cpp
302 : // indent-tabs-mode: nil
303 : // c-basic-offset: 4
304 : // tab-width: 4
305 : // End:
306 :
307 : // vim: ts=4 sw=4 et
|