Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qzip.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:data-parser
4
5#include "qzipwriter_p.h"
6
7#include <qdatetime.h>
8#include <qendian.h>
9#include <qdebug.h>
10#include <qdir.h>
11
12#include <memory>
13
14#include <zlib.h>
15
16// Zip standard version for archives handled by this API
17// (actually, the only basic support of this version is implemented but it is enough for now)
18#define ZIP_VERSION 20
19
20#if 0
21#define ZDEBUG qDebug
22#else
23#define ZDEBUG if (0) qDebug
24#endif
25
27
28static inline void writeUInt(uchar *data, uint i)
29{
30 data[0] = i & 0xff;
31 data[1] = (i>>8) & 0xff;
32 data[2] = (i>>16) & 0xff;
33 data[3] = (i>>24) & 0xff;
34}
35
36static inline void writeUShort(uchar *data, ushort i)
37{
38 data[0] = i & 0xff;
39 data[1] = (i>>8) & 0xff;
40}
41
42static inline void copyUInt(uchar *dest, const uchar *src)
43{
44 dest[0] = src[0];
45 dest[1] = src[1];
46 dest[2] = src[2];
47 dest[3] = src[3];
48}
49
50static inline void copyUShort(uchar *dest, const uchar *src)
51{
52 dest[0] = src[0];
53 dest[1] = src[1];
54}
55
56static void writeMSDosDate(uchar *dest, const QDateTime& dt)
57{
58 if (dt.isValid()) {
59 quint16 time =
60 (dt.time().hour() << 11) // 5 bit hour
61 | (dt.time().minute() << 5) // 6 bit minute
62 | (dt.time().second() >> 1); // 5 bit double seconds
63
64 dest[0] = time & 0xff;
65 dest[1] = time >> 8;
66
67 quint16 date =
68 ((dt.date().year() - 1980) << 9) // 7 bit year 1980-based
69 | (dt.date().month() << 5) // 4 bit month
70 | (dt.date().day()); // 5 bit day
71
72 dest[2] = char(date);
73 dest[3] = char(date >> 8);
74 } else {
75 dest[0] = 0;
76 dest[1] = 0;
77 dest[2] = 0;
78 dest[3] = 0;
79 }
80}
81
82static int deflate (Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)
83{
84 z_stream stream;
85 int err;
86
87 stream.next_in = const_cast<Bytef*>(source);
88 stream.avail_in = (uInt)sourceLen;
89 stream.next_out = dest;
90 stream.avail_out = (uInt)*destLen;
91 if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
92
93 stream.zalloc = (alloc_func)nullptr;
94 stream.zfree = (free_func)nullptr;
95 stream.opaque = (voidpf)nullptr;
96
97 err = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
98 if (err != Z_OK) return err;
99
100 err = deflate(&stream, Z_FINISH);
101 if (err != Z_STREAM_END) {
102 deflateEnd(&stream);
103 return err == Z_OK ? Z_BUF_ERROR : err;
104 }
105 *destLen = stream.total_out;
106
107 err = deflateEnd(&stream);
108 return err;
109}
110
111
113enum {
114 Dir = 0x10, // FILE_ATTRIBUTE_DIRECTORY
115 File = 0x80, // FILE_ATTRIBUTE_NORMAL
116 TypeMask = 0x90,
117
118 ReadOnly = 0x01, // FILE_ATTRIBUTE_READONLY
119 PermMask = 0x01
120};
121}
122
124enum {
125 Dir = 0040000, // __S_IFDIR
126 File = 0100000, // __S_IFREG
127 SymLink = 0120000, // __S_IFLNK
128 TypeMask = 0170000, // __S_IFMT
129
130 ReadUser = 0400, // __S_IRUSR
131 WriteUser = 0200, // __S_IWUSR
132 ExeUser = 0100, // __S_IXUSR
133 ReadGroup = 0040, // __S_IRGRP
134 WriteGroup = 0020, // __S_IWGRP
135 ExeGroup = 0010, // __S_IXGRP
136 ReadOther = 0004, // __S_IROTH
137 WriteOther = 0002, // __S_IWOTH
138 ExeOther = 0001, // __S_IXOTH
139 PermMask = 0777
140};
141}
142
143static quint32 permissionsToMode(QFile::Permissions perms)
144{
145 quint32 mode = 0;
146 if (perms & (QFile::ReadOwner | QFile::ReadUser))
148 if (perms & (QFile::WriteOwner | QFile::WriteUser))
150 if (perms & (QFile::ExeOwner | QFile::ExeUser))
152 if (perms & QFile::ReadGroup)
154 if (perms & QFile::WriteGroup)
156 if (perms & QFile::ExeGroup)
158 if (perms & QFile::ReadOther)
160 if (perms & QFile::WriteOther)
162 if (perms & QFile::ExeOther)
164 return mode;
165}
166
167// for details, see http://www.pkware.com/documents/casestudies/APPNOTE.TXT
168
169enum HostOS {
172 HostVMS = 2, // VAX/VMS
175 HostAtari = 5, // what if it's a minix filesystem? [cjh]
176 HostHPFS = 6, // filesystem used by OS/2 (and NT 3.x)
180 HostTOPS20 = 10, // pkzip 2.50 NTFS
181 HostNTFS = 11, // filesystem used by Windows NT
182 HostQDOS = 12, // SMS/QDOS
183 HostAcorn = 13, // Archimedes Acorn RISC OS
184 HostVFAT = 14, // filesystem used by Windows 95, NT
186 HostBeOS = 16, // hybrid POSIX/database filesystem
190};
192
204
231
246
254
275
288
297
299{
300public:
301 QZipPrivate(QIODevice *device, bool ownDev)
303 {
304 }
305
307 {
308 if (ownDevice)
309 delete device;
310 }
311
318};
319
321{
322public:
323 QZipWriterPrivate(QIODevice *device, bool ownDev)
324 : QZipPrivate(device, ownDev),
328 {
329 }
330
334
336
337 void addEntry(EntryType type, const QString &fileName, const QByteArray &contents);
338};
339
341{
343 writeUInt(h.signature, 0x04034b50);
344 copyUShort(h.version_needed, ch.version_needed);
345 copyUShort(h.general_purpose_bits, ch.general_purpose_bits);
346 copyUShort(h.compression_method, ch.compression_method);
347 copyUInt(h.last_mod_file, ch.last_mod_file);
348 copyUInt(h.crc_32, ch.crc_32);
349 copyUInt(h.compressed_size, ch.compressed_size);
350 copyUInt(h.uncompressed_size, ch.uncompressed_size);
351 copyUShort(h.file_name_length, ch.file_name_length);
352 copyUShort(h.extra_field_length, ch.extra_field_length);
353 return h;
354}
355
356void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const QByteArray &contents/*, QFile::Permissions permissions, QZip::Method m*/)
357{
358#ifndef NDEBUG
359 static const char *const entryTypes[] = {
360 "directory",
361 "file ",
362 "symlink " };
363 ZDEBUG() << "adding" << entryTypes[type] <<":" << fileName.toUtf8().data() << (type == 2 ? QByteArray(" -> " + contents).constData() : "");
364#endif
365
366 if (! (device->isOpen() || device->open(QIODevice::WriteOnly))) {
367 status = QZipWriter::FileOpenError;
368 return;
369 }
370 device->seek(start_of_directory);
371
372 // don't compress small files
373 QZipWriter::CompressionPolicy compression = compressionPolicy;
374 if (compressionPolicy == QZipWriter::AutoCompress) {
375 if (contents.size() < 64)
376 compression = QZipWriter::NeverCompress;
377 else
378 compression = QZipWriter::AlwaysCompress;
379 }
380
381 FileHeader header;
382 memset(&header.h, 0, sizeof(CentralFileHeader));
383 writeUInt(header.h.signature, 0x02014b50);
384
385 writeUShort(header.h.version_needed, ZIP_VERSION);
386 writeUInt(header.h.uncompressed_size, contents.size());
387 writeMSDosDate(header.h.last_mod_file, QDateTime::currentDateTime());
388 QByteArray data = contents;
389 if (compression == QZipWriter::AlwaysCompress) {
390 writeUShort(header.h.compression_method, CompressionMethodDeflated);
391
392 ulong len = contents.size();
393 // shamelessly copied form zlib
394 len += (len >> 12) + (len >> 14) + 11;
395 int res;
396 do {
397 data.resize(len);
398 res = deflate((uchar*)data.data(), &len, (const uchar*)contents.constData(), contents.size());
399
400 switch (res) {
401 case Z_OK:
402 data.resize(len);
403 break;
404 case Z_MEM_ERROR:
405 qWarning("QZip: Z_MEM_ERROR: Not enough memory to compress file, skipping");
406 data.resize(0);
407 break;
408 case Z_BUF_ERROR:
409 len *= 2;
410 break;
411 }
412 } while (res == Z_BUF_ERROR);
413 }
414// TODO add a check if data.length() > contents.length(). Then try to store the original and revert the compression method to be uncompressed
415 writeUInt(header.h.compressed_size, data.size());
416 uint crc_32 = ::crc32(0, nullptr, 0);
417 crc_32 = ::crc32(crc_32, (const uchar *)contents.constData(), contents.size());
418 writeUInt(header.h.crc_32, crc_32);
419
420 // if bit 11 is set, the filename and comment fields must be encoded using UTF-8
421 ushort general_purpose_bits = Utf8Names; // always use utf-8
422 writeUShort(header.h.general_purpose_bits, general_purpose_bits);
423
424 const bool inUtf8 = (general_purpose_bits & Utf8Names) != 0;
425 header.file_name = inUtf8 ? fileName.toUtf8() : fileName.toLocal8Bit();
426 if (header.file_name.size() > 0xffff) {
427 qWarning("QZip: Filename is too long, chopping it to 65535 bytes");
428 header.file_name = header.file_name.left(0xffff); // ### don't break the utf-8 sequence, if any
429 }
430 if (header.file_comment.size() + header.file_name.size() > 0xffff) {
431 qWarning("QZip: File comment is too long, chopping it to 65535 bytes");
432 header.file_comment.truncate(0xffff - header.file_name.size()); // ### don't break the utf-8 sequence, if any
433 }
434 writeUShort(header.h.file_name_length, header.file_name.size());
435 //h.extra_field_length[2];
436
437 writeUShort(header.h.version_made, HostUnix << 8);
438 //uchar internal_file_attributes[2];
439 //uchar external_file_attributes[4];
440 quint32 mode = permissionsToMode(permissions);
441 switch (type) {
442 case Symlink:
444 break;
445 case Directory:
447 break;
448 case File:
450 break;
451 default:
452 Q_UNREACHABLE();
453 break;
454 }
455 writeUInt(header.h.external_file_attributes, mode << 16);
456 writeUInt(header.h.offset_local_header, start_of_directory);
457
458
459 fileHeaders.append(header);
460
461 LocalFileHeader h = toLocalHeader(header.h);
462 device->write((const char *)&h, sizeof(LocalFileHeader));
463 device->write(header.file_name);
464 device->write(data);
465 start_of_directory = device->pos();
466 dirtyFileTree = true;
467}
468
469////////////////////////////// Writer
470
471/*!
472 \class QZipWriter
473 \internal
474 \since 4.5
475
476 \brief the QZipWriter class provides a way to create a new zip archive.
477
478 QZipWriter can be used to create a zip archive containing any number of files
479 and directories. The files in the archive will be compressed in a way that is
480 compatible with common zip reader applications.
481*/
482
483
484/*!
485 Create a new zip archive that operates on the \a archive filename. The file will
486 be opened with the \a mode.
487 \sa isValid()
488*/
489QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode)
490{
491 auto f = std::make_unique<QFile>(fileName);
492 QZipWriter::Status status;
493 if (f->open(mode) && f->error() == QFile::NoError)
494 status = QZipWriter::NoError;
495 else {
496 if (f->error() == QFile::WriteError)
497 status = QZipWriter::FileWriteError;
498 else if (f->error() == QFile::OpenError)
499 status = QZipWriter::FileOpenError;
500 else if (f->error() == QFile::PermissionsError)
501 status = QZipWriter::FilePermissionsError;
502 else
503 status = QZipWriter::FileError;
504 }
505
506 d = new QZipWriterPrivate(f.get(), /*ownDevice=*/true);
507 Q_UNUSED(f.release());
508 d->status = status;
509}
510
511/*!
512 Create a new zip archive that operates on the archive found in \a device.
513 You have to open the device previous to calling the constructor and
514 only a device that is readable will be scanned for zip filecontent.
515 */
516QZipWriter::QZipWriter(QIODevice *device)
517 : d(new QZipWriterPrivate(device, /*ownDevice=*/false))
518{
519 Q_ASSERT(device);
520}
521
522QZipWriter::~QZipWriter()
523{
524 close();
525 delete d;
526}
527
528/*!
529 Returns device used for writing zip archive.
530*/
531QIODevice* QZipWriter::device() const
532{
533 return d->device;
534}
535
536/*!
537 Returns \c true if the user can write to the archive; otherwise returns \c false.
538*/
539bool QZipWriter::isWritable() const
540{
541 return d->device->isWritable();
542}
543
544/*!
545 Returns \c true if the file exists; otherwise returns \c false.
546*/
547bool QZipWriter::exists() const
548{
549 QFile *f = qobject_cast<QFile*> (d->device);
550 if (f == nullptr)
551 return true;
552 return f->exists();
553}
554
555/*!
556 \enum QZipWriter::Status
557
558 The following status values are possible:
559
560 \value NoError No error occurred.
561 \value FileWriteError An error occurred when writing to the device.
562 \value FileOpenError The file could not be opened.
563 \value FilePermissionsError The file could not be accessed.
564 \value FileError Another file error occurred.
565*/
566
567/*!
568 Returns a status code indicating the first error that was met by QZipWriter,
569 or QZipWriter::NoError if no error occurred.
570*/
571QZipWriter::Status QZipWriter::status() const
572{
573 return d->status;
574}
575
576/*!
577 \enum QZipWriter::CompressionPolicy
578
579 \value AlwaysCompress A file that is added is compressed.
580 \value NeverCompress A file that is added will be stored without changes.
581 \value AutoCompress A file that is added will be compressed only if that will give a smaller file.
582*/
583
584/*!
585 Sets the policy for compressing newly added files to the new \a policy.
586
587 \note the default policy is AlwaysCompress
588
589 \sa compressionPolicy()
590 \sa addFile()
591*/
592void QZipWriter::setCompressionPolicy(CompressionPolicy policy)
593{
594 d->compressionPolicy = policy;
595}
596
597/*!
598 Returns the currently set compression policy.
599 \sa setCompressionPolicy()
600 \sa addFile()
601*/
602QZipWriter::CompressionPolicy QZipWriter::compressionPolicy() const
603{
604 return d->compressionPolicy;
605}
606
607/*!
608 Sets the permissions that will be used for newly added files.
609
610 \note the default permissions are QFile::ReadOwner | QFile::WriteOwner.
611
612 \sa creationPermissions()
613 \sa addFile()
614*/
615void QZipWriter::setCreationPermissions(QFile::Permissions permissions)
616{
617 d->permissions = permissions;
618}
619
620/*!
621 Returns the currently set creation permissions.
622
623 \sa setCreationPermissions()
624 \sa addFile()
625*/
626QFile::Permissions QZipWriter::creationPermissions() const
627{
628 return d->permissions;
629}
630
631/*!
632 Add a file to the archive with \a data as the file contents.
633 The file will be stored in the archive using the \a fileName which
634 includes the full path in the archive.
635
636 The new file will get the file permissions based on the current
637 creationPermissions and it will be compressed using the zip compression
638 based on the current compression policy.
639
640 \sa setCreationPermissions()
641 \sa setCompressionPolicy()
642*/
643void QZipWriter::addFile(const QString &fileName, const QByteArray &data)
644{
645 d->addEntry(QZipWriterPrivate::File, QDir::fromNativeSeparators(fileName), data);
646}
647
648/*!
649 Add a file to the archive with \a device as the source of the contents.
650 The contents returned from QIODevice::readAll() will be used as the
651 filedata.
652 The file will be stored in the archive using the \a fileName which
653 includes the full path in the archive.
654*/
655void QZipWriter::addFile(const QString &fileName, QIODevice *device)
656{
657 Q_ASSERT(device);
658 QIODevice::OpenMode mode = device->openMode();
659 bool opened = false;
660 if ((mode & QIODevice::ReadOnly) == 0) {
661 opened = true;
662 if (! device->open(QIODevice::ReadOnly)) {
663 d->status = FileOpenError;
664 return;
665 }
666 }
667 d->addEntry(QZipWriterPrivate::File, QDir::fromNativeSeparators(fileName), device->readAll());
668 if (opened)
669 device->close();
670}
671
672/*!
673 Create a new directory in the archive with the specified \a dirName and
674 the \a permissions;
675*/
676void QZipWriter::addDirectory(const QString &dirName)
677{
678 QString name(QDir::fromNativeSeparators(dirName));
679 // separator is mandatory
680 if (!name.endsWith(u'/'))
681 name.append(u'/');
682 d->addEntry(QZipWriterPrivate::Directory, name, QByteArray());
683}
684
685/*!
686 Create a new symbolic link in the archive with the specified \a dirName
687 and the \a permissions;
688 A symbolic link contains the destination (relative) path and name.
689*/
690void QZipWriter::addSymLink(const QString &fileName, const QString &destination)
691{
692 d->addEntry(QZipWriterPrivate::Symlink, QDir::fromNativeSeparators(fileName), QFile::encodeName(destination));
693}
694
695/*!
696 Closes the zip file.
697*/
698void QZipWriter::close()
699{
700 if (!(d->device->openMode() & QIODevice::WriteOnly)) {
701 d->device->close();
702 return;
703 }
704
705 //qDebug("QZip::close writing directory, %d entries", d->fileHeaders.size());
706 d->device->seek(d->start_of_directory);
707 // write new directory
708 for (int i = 0; i < d->fileHeaders.size(); ++i) {
709 const FileHeader &header = d->fileHeaders.at(i);
710 d->device->write((const char *)&header.h, sizeof(CentralFileHeader));
711 d->device->write(header.file_name);
712 d->device->write(header.extra_field);
713 d->device->write(header.file_comment);
714 }
715 int dir_size = d->device->pos() - d->start_of_directory;
716 // write end of directory
717 EndOfDirectory eod;
718 memset(&eod, 0, sizeof(EndOfDirectory));
719 writeUInt(eod.signature, 0x06054b50);
720 //uchar this_disk[2];
721 //uchar start_of_directory_disk[2];
722 writeUShort(eod.num_dir_entries_this_disk, d->fileHeaders.size());
723 writeUShort(eod.num_dir_entries, d->fileHeaders.size());
724 writeUInt(eod.directory_size, dir_size);
725 writeUInt(eod.dir_start_offset, d->start_of_directory);
726 writeUShort(eod.comment_length, d->comment.size());
727
728 d->device->write((const char *)&eod, sizeof(EndOfDirectory));
729 d->device->write(d->comment);
730 d->device->close();
731}
732
733QT_END_NAMESPACE
~QZipPrivate()
Definition qzip.cpp:306
QByteArray comment
Definition qzip.cpp:316
QList< FileHeader > fileHeaders
Definition qzip.cpp:315
QIODevice * device
Definition qzip.cpp:312
uint start_of_directory
Definition qzip.cpp:317
QZipPrivate(QIODevice *device, bool ownDev)
Definition qzip.cpp:301
bool ownDevice
Definition qzip.cpp:313
bool dirtyFileTree
Definition qzip.cpp:314
void addEntry(EntryType type, const QString &fileName, const QByteArray &contents)
Definition qzip.cpp:356
QFile::Permissions permissions
Definition qzip.cpp:332
QZipWriterPrivate(QIODevice *device, bool ownDev)
Definition qzip.cpp:323
#define ZIP_VERSION
Definition qzip.cpp:18
static void copyUShort(uchar *dest, const uchar *src)
Definition qzip.cpp:50
Q_DECLARE_TYPEINFO(HostOS, Q_PRIMITIVE_TYPE)
static void copyUInt(uchar *dest, const uchar *src)
Definition qzip.cpp:42
CompressionMethod
Definition qzip.cpp:205
@ CompressionMethodBZip2
Definition qzip.cpp:218
@ CompressionMethodJpeg
Definition qzip.cpp:225
@ CompressionMethodReduced1
Definition qzip.cpp:208
@ CompressionMethodReduced4
Definition qzip.cpp:211
@ CompressionMethodTerse
Definition qzip.cpp:222
@ CompressionMethodDeflated
Definition qzip.cpp:214
@ CompressionMethodReduced2
Definition qzip.cpp:209
@ CompressionMethodWzAES
Definition qzip.cpp:228
@ CompressionMethodStored
Definition qzip.cpp:206
@ CompressionMethodReduced3
Definition qzip.cpp:210
@ CompressionMethodReservedTokenizing
Definition qzip.cpp:213
@ CompressionMethodWavPack
Definition qzip.cpp:226
@ CompressionMethodShrunk
Definition qzip.cpp:207
@ CompressionMethodLz77
Definition qzip.cpp:223
@ CompressionMethodDeflated64
Definition qzip.cpp:215
@ CompressionMethodImploded
Definition qzip.cpp:212
@ CompressionMethodPPMd
Definition qzip.cpp:227
@ CompressionMethodLZMA
Definition qzip.cpp:220
@ CompressionMethodPKImploding
Definition qzip.cpp:216
Q_DECLARE_TYPEINFO(FileHeader, Q_RELOCATABLE_TYPE)
Q_DECLARE_TYPEINFO(CompressionMethod, Q_PRIMITIVE_TYPE)
#define ZDEBUG
Definition qzip.cpp:23
static void writeMSDosDate(uchar *dest, const QDateTime &dt)
Definition qzip.cpp:56
Q_DECLARE_TYPEINFO(CentralFileHeader, Q_PRIMITIVE_TYPE)
static LocalFileHeader toLocalHeader(const CentralFileHeader &ch)
Definition qzip.cpp:340
HostOS
Definition qzip.cpp:169
@ HostFAT
Definition qzip.cpp:170
@ HostOS400
Definition qzip.cpp:188
@ HostVMS
Definition qzip.cpp:172
@ HostVFAT
Definition qzip.cpp:184
@ HostQDOS
Definition qzip.cpp:182
@ HostTandem
Definition qzip.cpp:187
@ HostVM_CMS
Definition qzip.cpp:174
@ HostMac
Definition qzip.cpp:177
@ HostCPM
Definition qzip.cpp:179
@ HostZ_System
Definition qzip.cpp:178
@ HostMVS
Definition qzip.cpp:185
@ HostAcorn
Definition qzip.cpp:183
@ HostTOPS20
Definition qzip.cpp:180
@ HostAtari
Definition qzip.cpp:175
@ HostUnix
Definition qzip.cpp:173
@ HostHPFS
Definition qzip.cpp:176
@ HostBeOS
Definition qzip.cpp:186
@ HostOSX
Definition qzip.cpp:189
@ HostAMIGA
Definition qzip.cpp:171
@ HostNTFS
Definition qzip.cpp:181
Q_DECLARE_TYPEINFO(LocalFileHeader, Q_PRIMITIVE_TYPE)
static quint32 permissionsToMode(QFile::Permissions perms)
Definition qzip.cpp:143
static void writeUShort(uchar *data, ushort i)
Definition qzip.cpp:36
GeneralPurposeFlag
Definition qzip.cpp:193
@ CentralDirectoryEncrypted
Definition qzip.cpp:201
@ AlgTune2
Definition qzip.cpp:196
@ StrongEncrypted
Definition qzip.cpp:199
@ HasDataDescriptor
Definition qzip.cpp:197
@ Utf8Names
Definition qzip.cpp:200
@ PatchedData
Definition qzip.cpp:198
@ Encrypted
Definition qzip.cpp:194
@ AlgTune1
Definition qzip.cpp:195
static int deflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)
Definition qzip.cpp:82
Q_DECLARE_TYPEINFO(DataDescriptor, Q_PRIMITIVE_TYPE)
Q_DECLARE_TYPEINFO(EndOfDirectory, Q_PRIMITIVE_TYPE)
Q_DECLARE_TYPEINFO(GeneralPurposeFlag, Q_PRIMITIVE_TYPE)
static QT_BEGIN_NAMESPACE void writeUInt(uchar *data, uint i)
Definition qzip.cpp:28
uchar last_mod_file[4]
Definition qzip.cpp:262
uchar crc_32[4]
Definition qzip.cpp:263
uchar version_made[2]
Definition qzip.cpp:258
uchar extra_field_length[2]
Definition qzip.cpp:267
uchar signature[4]
Definition qzip.cpp:257
uchar version_needed[2]
Definition qzip.cpp:259
uchar disk_start[2]
Definition qzip.cpp:269
uchar uncompressed_size[4]
Definition qzip.cpp:265
uchar compressed_size[4]
Definition qzip.cpp:264
uchar internal_file_attributes[2]
Definition qzip.cpp:270
uchar file_name_length[2]
Definition qzip.cpp:266
uchar offset_local_header[4]
Definition qzip.cpp:272
uchar external_file_attributes[4]
Definition qzip.cpp:271
uchar compression_method[2]
Definition qzip.cpp:261
uchar file_comment_length[2]
Definition qzip.cpp:268
uchar general_purpose_bits[2]
Definition qzip.cpp:260
uchar crc_32[4]
Definition qzip.cpp:249
uchar uncompressed_size[4]
Definition qzip.cpp:251
uchar compressed_size[4]
Definition qzip.cpp:250
uchar num_dir_entries_this_disk[2]
Definition qzip.cpp:281
uchar signature[4]
Definition qzip.cpp:278
uchar comment_length[2]
Definition qzip.cpp:285
uchar this_disk[2]
Definition qzip.cpp:279
uchar start_of_directory_disk[2]
Definition qzip.cpp:280
uchar dir_start_offset[4]
Definition qzip.cpp:284
uchar num_dir_entries[2]
Definition qzip.cpp:282
uchar directory_size[4]
Definition qzip.cpp:283
QByteArray extra_field
Definition qzip.cpp:293
QByteArray file_name
Definition qzip.cpp:292
CentralFileHeader h
Definition qzip.cpp:291
QByteArray file_comment
Definition qzip.cpp:294
uchar extra_field_length[2]
Definition qzip.cpp:243
uchar general_purpose_bits[2]
Definition qzip.cpp:236
uchar last_mod_file[4]
Definition qzip.cpp:238
uchar version_needed[2]
Definition qzip.cpp:235
uchar compressed_size[4]
Definition qzip.cpp:240
uchar signature[4]
Definition qzip.cpp:234
uchar crc_32[4]
Definition qzip.cpp:239
uchar uncompressed_size[4]
Definition qzip.cpp:241
uchar file_name_length[2]
Definition qzip.cpp:242
uchar compression_method[2]
Definition qzip.cpp:237