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 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 : */
21 :
22 : /** \file
23 : * \brief Various functions used throughout the library.
24 : *
25 : * This fiel 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 1138278 : void zipRead(std::istream& is, uint32_t& value)
75 : {
76 : unsigned char buf[sizeof(value)];
77 :
78 1138278 : 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 1138277 : 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 1138277 : value = (buf[0] << 0)
89 1138277 : | (buf[1] << 8)
90 1138277 : | (buf[2] << 16)
91 1138277 : | (buf[3] << 24);
92 1138277 : }
93 :
94 :
95 1277028 : void zipRead(std::istream& is, uint16_t& value)
96 : {
97 : unsigned char buf[sizeof(value)];
98 :
99 1277028 : 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 1277027 : 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 1277027 : value = (buf[0] << 0)
110 1277027 : | (buf[1] << 8);
111 1277027 : }
112 :
113 :
114 7 : void zipRead(std::istream& is, uint8_t& value)
115 : {
116 : unsigned char buf[sizeof(value)];
117 :
118 7 : 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 6 : 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 6 : value = buf[0];
129 6 : }
130 :
131 :
132 200291 : void zipRead(std::istream& is, buffer_t& buffer, ssize_t const count)
133 : {
134 200291 : buffer.resize(count);
135 200291 : if(count > 0)
136 : {
137 9779 : 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 9778 : 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 200290 : }
147 :
148 :
149 269286 : void zipRead(std::istream& is, std::string& str, ssize_t const count)
150 : {
151 269286 : str.resize(count);
152 269286 : if(count > 0)
153 : {
154 199884 : 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 199883 : 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 269285 : }
164 :
165 :
166 2409 : void zipRead(buffer_t const& is, size_t& pos, uint32_t& value)
167 : {
168 2409 : if(pos + sizeof(value) > is.size())
169 : {
170 1 : throw IOException("EOF reached while reading zip archive data from file.");
171 : }
172 :
173 2408 : value = (is[pos + 0] << 0)
174 2408 : | (is[pos + 1] << 8)
175 2408 : | (is[pos + 2] << 16)
176 2408 : | (is[pos + 3] << 24);
177 :
178 2408 : pos += sizeof(value);
179 2408 : }
180 :
181 :
182 1740 : void zipRead(buffer_t const& is, size_t& pos, uint16_t& value)
183 : {
184 1740 : if(pos + sizeof(value) > is.size())
185 : {
186 1 : throw IOException("EOF reached while reading zip archive data from file.");
187 : }
188 :
189 1739 : value = (is[pos + 0] << 0)
190 1739 : | (is[pos + 1] << 8);
191 :
192 1739 : pos += sizeof(value);
193 1739 : }
194 :
195 :
196 7 : void zipRead(buffer_t const& is, size_t& pos, uint8_t& value)
197 : {
198 7 : if(pos + sizeof(value) > is.size())
199 : {
200 1 : throw IOException("EOF reached while reading zip archive data from file.");
201 : }
202 :
203 6 : value = is[pos];
204 :
205 6 : pos += sizeof(value);
206 6 : }
207 :
208 :
209 3 : void zipRead(buffer_t const& is, size_t& pos, buffer_t& buffer, ssize_t const count)
210 : {
211 3 : if(pos + count > is.size())
212 : {
213 1 : throw IOException("EOF reached while reading zip archive data from file.");
214 : }
215 :
216 2 : buffer.clear();
217 2 : buffer.insert(buffer.begin(), is.begin() + pos, is.begin() + pos + count);
218 :
219 2 : pos += count;
220 2 : }
221 :
222 :
223 348 : void zipRead(buffer_t const& is, size_t& pos, std::string& str, ssize_t const count)
224 : {
225 348 : if(pos + count > is.size())
226 : {
227 11 : throw IOException("EOF reached while reading zip archive data from file.");
228 : }
229 :
230 337 : str.clear();
231 337 : str.insert(str.begin(), is.begin() + pos, is.begin() + pos + count);
232 :
233 337 : pos += count;
234 337 : }
235 :
236 :
237 2262881 : void zipWrite(std::ostream& os, uint32_t const& value)
238 : {
239 : char buf[sizeof(value)];
240 :
241 2262881 : buf[0] = value >> 0;
242 2262881 : buf[1] = value >> 8;
243 2262881 : buf[2] = value >> 16;
244 2262881 : buf[3] = value >> 24;
245 :
246 2262881 : 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 2262880 : }
251 :
252 :
253 2529501 : void zipWrite(std::ostream& os, uint16_t const& value)
254 : {
255 : char buf[sizeof(value)];
256 :
257 2529501 : buf[0] = value >> 0;
258 2529501 : buf[1] = value >> 8;
259 :
260 2529501 : 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 2529500 : }
265 :
266 :
267 7 : void zipWrite(std::ostream& os, uint8_t const& value)
268 : {
269 : char buf[sizeof(value)];
270 :
271 7 : buf[0] = value;
272 :
273 7 : 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 6 : }
278 :
279 :
280 399197 : void zipWrite(std::ostream& os, buffer_t const& buffer)
281 : {
282 399197 : 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 399196 : }
287 :
288 :
289 532523 : void zipWrite(std::ostream& os, std::string const& str)
290 : {
291 532523 : 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 532522 : }
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
|