zipios 2.2.0
Zipios -- a small C++ library that provides easy access to .zip files.
zipendofcentraldirectory.cpp
Go to the documentation of this file.
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
29
31
33
34
35namespace zipios
36{
37
38
47
48
54namespace
55{
56
57
68uint32_t const g_signature = 0x06054b50;
69
70
71} // no name namespace
72
73
83 //: m_central_directory_entries(0) -- auto-init
84 //, m_central_directory_size(0) -- auto-init
85 //, m_central_directory_offset(0) -- auto-init
86 : m_zip_comment(zip_comment)
87{
88}
89
90
106
107
125
126
146
147
164
165
180{
182}
183
184
201{
202 m_central_directory_offset = start_offset;
203}
204
205
229{
230 // the number of bytes we are going to read in the buffer
231 // (including the signature)
232 ssize_t const HEADER_SIZE(static_cast<ssize_t>(sizeof(uint32_t) * 3 + sizeof(uint16_t) * 5));
233
234 // enough data in the buffer?
235 //
236 // Note: this quick check assumes a 0 length comment which is possible;
237 // if there is a comment and we find the signature too early, then
238 // it will throw
239 //
240 if(static_cast<ssize_t>(buf.size() - pos) < HEADER_SIZE)
241 {
242 return false;
243 }
244
245 // first read and check the signature
246 uint32_t signature;
247 zipRead(buf, pos, signature); // 32
248 if(signature != g_signature)
249 {
250 return false;
251 }
252
253 // next we read the other parameters
254 uint16_t disk_number;
255 uint16_t central_directory_entries;
256 uint16_t central_directory_total_entries;
257 uint32_t central_directory_size;
258 uint32_t central_directory_offset;
259 uint16_t comment_len;
260
261 zipRead(buf, pos, disk_number); // 16
262 zipRead(buf, pos, disk_number); // 16
263 zipRead(buf, pos, central_directory_entries); // 16
264 zipRead(buf, pos, central_directory_total_entries); // 16
265 zipRead(buf, pos, central_directory_size); // 32
266 zipRead(buf, pos, central_directory_offset); // 32
267 zipRead(buf, pos, comment_len); // 16
268 zipRead(buf, pos, m_zip_comment, comment_len); // string
269
270 // note that if disk_number is defined, then these following two
271 // numbers should differ too
272 if(central_directory_entries != central_directory_total_entries)
273 {
274 throw FileCollectionException("ZipEndOfCentralDirectory with a number of entries and total entries that differ is not supported, spanned zip files are not supported");
275 }
276
277 m_central_directory_entries = central_directory_entries;
278 m_central_directory_size = central_directory_size;
279 m_central_directory_offset = central_directory_offset;
280
281 return true;
282}
283
284
308{
313 if(m_zip_comment.length() > 65535)
314 {
315 throw InvalidStateException("the Zip archive comment is too large");
316 }
318 {
319 throw InvalidStateException("the number of entries in the Zip archive is too large");
320 }
321// Solaris defines _ILP32 for 32 bit platforms
322#if !defined(_ILP32)
323 if(m_central_directory_size >= 0x100000000UL
324 || m_central_directory_offset >= 0x100000000L)
325 {
326 throw FileCollectionException("the Zip archive size or offset are too large"); // LCOV_EXCL_LINE
327 }
328#endif
329
330 uint16_t const disk_number(0);
331 uint16_t const central_directory_entries(m_central_directory_entries);
332 uint32_t const central_directory_size(m_central_directory_size);
333 uint32_t const central_directory_offset(m_central_directory_offset);
334 uint16_t const comment_len(m_zip_comment.length());
335
336 // the total number of entries, across all disks is the same in our
337 // case so we use one number for both fields
338
339 zipWrite(os, g_signature); // 32
340 zipWrite(os, disk_number); // 16
341 zipWrite(os, disk_number); // 16
342 zipWrite(os, central_directory_entries); // 16
343 zipWrite(os, central_directory_entries); // 16
344 zipWrite(os, central_directory_size); // 32
345 zipWrite(os, central_directory_offset); // 32
346 zipWrite(os, comment_len); // 16
347 zipWrite(os, m_zip_comment); // string
348}
349
350
351} // zipios namespace
352
353// Local Variables:
354// mode: cpp
355// indent-tabs-mode: nil
356// c-basic-offset: 4
357// tab-width: 4
358// End:
359
360// vim: ts=4 sw=4 et
FileCollectionException is used to signal a FileCollection problem.
Exception used when it is not possible to move forward.
size_t getCentralDirectorySize() const
Retrieve the size of the Central Directory in bytes.
void setOffset(offset_t new_offset)
Offset of the Central Directory.
size_t getCount() const
Retrieve the number of entries.
offset_t getOffset() const
Retrieve the offset of the Central Directory.
ZipEndOfCentralDirectory(std::string const &zip_comment="")
Initialize an ZipEndOfCentralDirectory object.
void write(std::ostream &os)
Write the ZipEndOfCentralDirectory structure to a stream.
bool read(::zipios::buffer_t const &buf, size_t pos)
Attempt to read an ZipEndOfCentralDirectory structure.
void setCentralDirectorySize(size_t size)
Define the size of the central directory.
void setCount(size_t c)
Set the number of entries.
uint32_t const g_signature
Signature of the ZipEndOfCentralDirectory structure block.
The zipios namespace includes the Zipios library definitions.
std::vector< unsigned char > buffer_t
A buffer of characters.
std::streamoff offset_t
void zipRead(std::istream &is, uint32_t &value)
void zipWrite(std::ostream &os, uint32_t const &value)
Declaration of the zipios::ZipEndOfCentralDirectory class.
Various exceptions used throughout the Zipios library, all based on zipios::Exception.