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-2022 Made to Order Software Corp. All Rights Reserved
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 "inadvertently" 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 975542 : void zipRead(std::istream & is, uint32_t & value)
75 : {
76 : unsigned char buf[sizeof(value)];
77 :
78 975542 : 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 975541 : 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 975541 : value = (buf[0] << 0)
89 975541 : | (buf[1] << 8)
90 975541 : | (buf[2] << 16)
91 975541 : | (buf[3] << 24);
92 975541 : }
93 :
94 :
95 1093887 : void zipRead(std::istream & is, uint16_t & value)
96 : {
97 : unsigned char buf[sizeof(value)];
98 :
99 1093887 : 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 1093886 : 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 1093886 : value = (buf[0] << 0)
110 1093886 : | (buf[1] << 8);
111 1093886 : }
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 171832 : void zipRead(std::istream & is, buffer_t & buffer, ssize_t const count)
133 : {
134 171832 : buffer.resize(count);
135 171832 : if(count > 0)
136 : {
137 8346 : 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 8345 : 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 171831 : }
147 :
148 :
149 230616 : void zipRead(std::istream & is, std::string & str, ssize_t const count)
150 : {
151 230616 : str.resize(count);
152 230616 : if(count > 0)
153 : {
154 171425 : 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 171424 : 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 230615 : }
164 :
165 :
166 2342 : void zipRead(buffer_t const & is, size_t & pos, uint32_t & value)
167 : {
168 2342 : if(pos + sizeof(value) > is.size())
169 : {
170 1 : throw IOException("EOF reached while reading zip archive data from file.");
171 : }
172 :
173 2341 : value = (is[pos + 0] << 0)
174 2341 : | (is[pos + 1] << 8)
175 2341 : | (is[pos + 2] << 16)
176 2341 : | (is[pos + 3] << 24);
177 :
178 2341 : pos += sizeof(value);
179 2341 : }
180 :
181 :
182 1733 : void zipRead(buffer_t const & is, size_t & pos, uint16_t & value)
183 : {
184 1733 : if(pos + sizeof(value) > is.size())
185 : {
186 1 : throw IOException("EOF reached while reading zip archive data from file.");
187 : }
188 :
189 1732 : value = (is[pos + 0] << 0)
190 1732 : | (is[pos + 1] << 8);
191 :
192 1732 : pos += sizeof(value);
193 1732 : }
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 347 : void zipRead(buffer_t const & is, size_t & pos, std::string & str, ssize_t const count)
224 : {
225 347 : if(pos + count > is.size())
226 : {
227 11 : throw IOException("EOF reached while reading zip archive data from file.");
228 : }
229 :
230 336 : str.clear();
231 336 : str.insert(str.begin(), is.begin() + pos, is.begin() + pos + count);
232 :
233 336 : pos += count;
234 336 : }
235 :
236 :
237 2070516 : void zipWrite(std::ostream & os, uint32_t const & value)
238 : {
239 : char buf[sizeof(value)];
240 :
241 2070516 : buf[0] = value >> 0;
242 2070516 : buf[1] = value >> 8;
243 2070516 : buf[2] = value >> 16;
244 2070516 : buf[3] = value >> 24;
245 :
246 2070516 : 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 2070515 : }
251 :
252 :
253 2314514 : void zipWrite(std::ostream & os, uint16_t const & value)
254 : {
255 : char buf[sizeof(value)];
256 :
257 2314514 : buf[0] = value >> 0;
258 2314514 : buf[1] = value >> 8;
259 :
260 2314514 : 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 2314513 : }
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 365251 : void zipWrite(std::ostream & os, buffer_t const & buffer)
281 : {
282 365251 : 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 365250 : }
287 :
288 :
289 487258 : void zipWrite(std::ostream & os, std::string const & str)
290 : {
291 487258 : 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 487257 : }
296 :
297 :
298 : } // 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
|