zipios 2.3.4
Zipios -- a small C++ library providing 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-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
31
33
34
35namespace zipios
36{
37
38
54namespace
55{
56
57
68uint32_t const g_signature = 0x06054b50;
69
70
71} // no name namespace
72
73
83 : m_zip_comment(zip_comment)
84{
85}
86
87
103
104
122
123
143
144
161
162
177{
179}
180
181
198{
199 m_central_directory_offset = start_offset;
200}
201
202
226{
227 // the number of bytes we are going to read in the buffer
228 // (including the signature)
229 ssize_t const HEADER_SIZE(static_cast<ssize_t>(sizeof(uint32_t) * 3 + sizeof(uint16_t) * 5));
230
231 // enough data in the buffer?
232 //
233 // Note: this quick check assumes a 0 length comment which is possible;
234 // if there is a comment and we find the signature too early, then
235 // it will throw
236 //
237 if(static_cast<ssize_t>(buf.size() - pos) < HEADER_SIZE)
238 {
239 return false;
240 }
241
242 // first read and check the signature
243 uint32_t signature;
244 zipRead(buf, pos, signature); // 32
245 if(signature != g_signature)
246 {
247 return false;
248 }
249
250 // next we read the other parameters
251 uint16_t disk_number;
252 uint16_t central_directory_entries;
253 uint16_t central_directory_total_entries;
254 uint32_t central_directory_size;
255 uint32_t central_directory_offset;
256 uint16_t comment_len;
257
258 zipRead(buf, pos, disk_number); // 16
259 zipRead(buf, pos, disk_number); // 16
260 zipRead(buf, pos, central_directory_entries); // 16
261 zipRead(buf, pos, central_directory_total_entries); // 16
262 zipRead(buf, pos, central_directory_size); // 32
263 zipRead(buf, pos, central_directory_offset); // 32
264 zipRead(buf, pos, comment_len); // 16
265 zipRead(buf, pos, m_zip_comment, comment_len); // string
266
267 // note that if disk_number is defined, then these following two
268 // numbers should differ too
269 if(central_directory_entries != central_directory_total_entries)
270 {
271 throw FileCollectionException("ZipEndOfCentralDirectory with a number of entries and total entries that differ is not supported, spanned zip files are not supported");
272 }
273
274 m_central_directory_entries = central_directory_entries;
275 m_central_directory_size = central_directory_size;
276 m_central_directory_offset = central_directory_offset;
277
278 return true;
279}
280
281
304void ZipEndOfCentralDirectory::write(std::ostream & os)
305{
310 if(m_zip_comment.length() > 65535)
311 {
312 throw InvalidStateException("the Zip archive comment is too large");
313 }
315 {
316 throw InvalidStateException("the number of entries in the Zip archive is too large");
317 }
318// Solaris defines _ILP32 for 32 bit platforms
319#if INTPTR_MAX != INT32_MAX
320 if(m_central_directory_size >= 0x100000000UL
321 || m_central_directory_offset >= 0x100000000L)
322 {
323 throw FileCollectionException("the Zip archive size or offset are too large"); // LCOV_EXCL_LINE
324 }
325#endif
326
327 uint16_t const disk_number(0);
328 uint16_t const central_directory_entries(m_central_directory_entries);
329 uint32_t const central_directory_size(m_central_directory_size);
330 uint32_t const central_directory_offset(m_central_directory_offset);
331 uint16_t const comment_len(m_zip_comment.length());
332
333 // the total number of entries, across all disks is the same in our
334 // case so we use one number for both fields
335
336 zipWrite(os, g_signature); // 32
337 zipWrite(os, disk_number); // 16
338 zipWrite(os, disk_number); // 16
339 zipWrite(os, central_directory_entries); // 16
340 zipWrite(os, central_directory_entries); // 16
341 zipWrite(os, central_directory_size); // 32
342 zipWrite(os, central_directory_offset); // 32
343 zipWrite(os, comment_len); // 16
344 zipWrite(os, m_zip_comment); // string
345}
346
347
348} // zipios namespace
349
350// Local Variables:
351// mode: cpp
352// indent-tabs-mode: nil
353// c-basic-offset: 4
354// tab-width: 4
355// End:
356
357// 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.
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.
ZipEndOfCentralDirectory(std::string const &zip_comment=std::string())
Initialize an ZipEndOfCentralDirectory object.
void setCentralDirectorySize(size_t size)
Define the size of the central directory.
void setCount(size_t c)
Set the number of entries.
The zipios namespace includes the Zipios library definitions.
std::streamoff offset_t
void zipRead(std::istream &is, uint32_t &value)
std::vector< unsigned char > buffer_t
A buffer of characters.
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.