25#include <QtCore/QHash>
26#include <QtCore/QByteArray>
27#include <QtCore/QFile>
29#include <QtCore/QDate>
30#include <QtCore/QList>
43 ( dt.time().hour() << 11 )
44 | ( dt.time().minute() << 5 )
45 | ( dt.time().second() >> 1 );
47 buffer[0] = char(time);
48 buffer[1] = char(time >> 8);
51 ( ( dt.date().year() - 1980 ) << 9 )
52 | ( dt.date().month() << 5 )
53 | ( dt.date().day() );
55 buffer[2] = char(date);
56 buffer[3] = char(date >> 8);
69 quint16 time = (uchar)buffer[0] | ( (uchar)buffer[1] << 8 );
71 int m = ( time & 0x7ff ) >> 5;
72 int s = ( time & 0x1f ) * 2 ;
75 quint16 date = (uchar)buffer[2] | ( (uchar)buffer[3] << 8 );
76 int y = ( date >> 9 ) + 1980;
77 int o = ( date & 0x1ff ) >> 5;
78 int d = ( date & 0x1f );
96 QByteArray guessed_symlink;
100 bool exttimestamp_seen;
102 bool newinfounix_seen;
105 ParseFileInfo() : perm(0100644), uid(-1), gid(-1), extralen(0),
106 exttimestamp_seen(false), newinfounix_seen(false) {
107 ctime = mtime = atime = time(0);
120 ParseFileInfo &pfi) {
122 kDebug(7040) <<
"premature end of extended timestamp (#1)";
131 kDebug(7040) <<
"premature end of extended timestamp (#2)";
134 pfi.mtime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
135 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
142 pfi.exttimestamp_seen =
true;
148 kDebug(7040) <<
"premature end of extended timestamp (#3)";
151 pfi.atime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
152 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
159 kDebug(7040) <<
"premature end of extended timestamp (#4)";
162 pfi.ctime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
163 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
167 pfi.exttimestamp_seen =
true;
180 ParseFileInfo &pfi) {
182 if (pfi.exttimestamp_seen || pfi.newinfounix_seen)
return true;
185 kDebug(7040) <<
"premature end of Info-ZIP unix extra field old";
189 pfi.atime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
190 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
192 pfi.mtime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
193 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
195 if (islocal && size >= 12) {
196 pfi.uid = (uchar)buffer[0] | (uchar)buffer[1] << 8;
198 pfi.gid = (uchar)buffer[0] | (uchar)buffer[1] << 8;
213static bool parseInfoZipUnixNew(const char *buffer, int size, bool islocal,
214 ParseFileInfo &pfi) {
216 pfi.newinfounix =
true;
221 kDebug(7040) <<
"premature end of Info-ZIP unix extra field new";
225 pfi.uid = (uchar)buffer[0] | (uchar)buffer[1] << 8;
227 pfi.gid = (uchar)buffer[0] | (uchar)buffer[1] << 8;
230 pfi.newinfounix =
true;
244 ParseFileInfo &pfi) {
247 if (!islocal)
return true;
250 int magic = (uchar)buffer[0] | (uchar)buffer[1] << 8;
252 int fieldsize = (uchar)buffer[0] | (uchar)buffer[1] << 8;
256 if (fieldsize > size) {
258 kDebug(7040) <<
"premature end of extra fields reached";
271 if (!parseInfoZipUnixNew(buffer, fieldsize, islocal, pfi))
return false;
304 if (buffer[0] ==
'K') {
305 if (buffer[1] == 7 && buffer[2] == 8) {
307 dev->seek(dev->pos() + 12);
311 if ((buffer[1] == 1 && buffer[2] == 2)
312 || (buffer[1] == 3 && buffer[2] == 4)) {
314 dev->seek(dev->pos() - 4);
331 bool headerTokenFound =
false;
334 while (!headerTokenFound) {
335 int n = dev->read(buffer, 1);
341 if (buffer[0] !=
'P') {
345 n = dev->read(buffer, 3);
352 headerTokenFound =
true;
354 for (
int i = 0; i < 3; ++i) {
355 if (buffer[i] ==
'P') {
357 dev->seek(dev->pos() - 3 + i);
370class KZip::KZipPrivate
396 :
KArchive( fileName ),d(new KZipPrivate)
401 :
KArchive( dev ),d(new KZipPrivate)
416 d->m_fileList.clear();
418 if ( mode == QIODevice::WriteOnly )
435 bool startOfFile =
true;
441 n = dev->read( buffer, 4 );
445 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#1)";
450 if ( !memcmp( buffer,
"PK\5\6", 4 ) )
457 if ( !memcmp( buffer,
"PK\3\4", 4 ) )
462 dev->seek( dev->pos() + 2 );
465 n = dev->read( buffer, 24 );
467 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#4)";
471 int gpf = (uchar)buffer[0];
472 int compression_mode = (uchar)buffer[2] | (uchar)buffer[3] << 8;
475 const qint64 compr_size = uint(uchar(buffer[12])) | uint(uchar(buffer[13])) << 8 |
476 uint(uchar(buffer[14])) << 16 | uint(uchar(buffer[15])) << 24;
477 const qint64 uncomp_size = uint(uchar(buffer[16])) | uint(uchar(buffer[17])) << 8 |
478 uint(uchar(buffer[18])) << 16 | uint(uchar(buffer[19])) << 24;
479 const int namelen = uint(uchar(buffer[20])) | uint(uchar(buffer[21])) << 8;
480 const int extralen = uint(uchar(buffer[22])) | uint(uchar(buffer[23])) << 8;
492 Q_ASSERT( namelen > 0 );
493 QByteArray
fileName = dev->read(namelen);
494 if ( fileName.size() < namelen ) {
495 kWarning(7040) <<
"Invalid ZIP file. Name not completely read (#2)";
504 unsigned int extraFieldEnd = dev->pos() + extralen;
505 pfi.extralen = extralen;
506 int handledextralen = qMin(extralen, (
int)
sizeof buffer);
511 n = dev->read(buffer, handledextralen);
515 kWarning(7040) <<
"Invalid ZIP File. Broken ExtraField.";
520 dev->seek( extraFieldEnd );
537 bool foundSignature =
false;
541 && uncomp_size > 0) {
544 pfi.guessed_symlink = dev->read(uncomp_size);
545 if (pfi.guessed_symlink.size() < uncomp_size) {
546 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#5)";
551 if ( compr_size > dev->size() )
559 foundSignature =
true;
564 bool success = dev->seek( dev->pos() + compr_size );
576 if (!foundSignature) {
579 n = dev->read(buffer, 4);
587 dev->seek(dev->pos() + 8);
597 pfi_map.insert(fileName, pfi);
599 else if ( !memcmp( buffer,
"PK\1\2", 4 ) )
607 offset = dev->pos() - 4;
610 if ( d->m_offset == 0L ) d->m_offset = offset;
612 n = dev->read( buffer + 4, 42 );
614 kWarning(7040) <<
"Invalid ZIP file, central entry too short";
621 int namelen = (uchar)buffer[29] << 8 | (uchar)buffer[28];
622 Q_ASSERT( namelen > 0 );
623 QByteArray bufferName = dev->read( namelen );
624 if ( bufferName.size() < namelen )
625 kWarning(7040) <<
"Invalid ZIP file. Name not completely read";
627 ParseFileInfo pfi = pfi_map.value( bufferName, ParseFileInfo() );
629 QString name( QFile::decodeName(bufferName) );
634 int extralen = (uchar)buffer[31] << 8 | (uchar)buffer[30];
636 int commlen = (uchar)buffer[33] << 8 | (uchar)buffer[32];
638 int cmethod = (uchar)buffer[11] << 8 | (uchar)buffer[10];
644 uint crc32 = (uchar)buffer[19] << 24 | (uchar)buffer[18] << 16 |
645 (uchar)buffer[17] << 8 | (uchar)buffer[16];
648 uint ucsize = (uchar)buffer[27] << 24 | (uchar)buffer[26] << 16 |
649 (uchar)buffer[25] << 8 | (uchar)buffer[24];
651 uint csize = (uchar)buffer[23] << 24 | (uchar)buffer[22] << 16 |
652 (uchar)buffer[21] << 8 | (uchar)buffer[20];
655 uint localheaderoffset = (uchar)buffer[45] << 24 | (uchar)buffer[44] << 16 |
656 (uchar)buffer[43] << 8 | (uchar)buffer[42];
662 int localextralen = pfi.extralen;
668 uint dataoffset = localheaderoffset + 30 + localextralen + namelen;
674 int os_madeby = (uchar)buffer[5];
676 int access = 0100644;
678 if (os_madeby == 3) {
679 access = (uchar)buffer[40] | (uchar)buffer[41] << 8;
684 if (name.endsWith(QLatin1Char(
'/'))) {
686 name = name.left( name.length() - 1 );
687 if (os_madeby != 3) access = S_IFDIR | 0755;
688 else Q_ASSERT(access & S_IFDIR);
691 int pos = name.lastIndexOf(QLatin1Char(
'/'));
695 entryName = name.mid( pos + 1 );
696 Q_ASSERT( !entryName.isEmpty() );
701 QString path = QDir::cleanPath( name );
717 if (S_ISLNK(access)) {
718 symlink = QFile::decodeName(pfi.guessed_symlink);
720 entry =
new KZipFileEntry(
this, entryName, access, pfi.mtime,
722 symlink, name, dataoffset,
723 ucsize, cmethod, csize );
724 static_cast<KZipFileEntry *
>(entry)->setHeaderStart( localheaderoffset );
727 d->m_fileList.append(
static_cast<KZipFileEntry *
>( entry ) );
739 QString path = QDir::cleanPath( name.left( pos ) );
747 offset += 46 + commlen + extralen + namelen;
748 bool b = dev->seek(offset);
753 else if ( startOfFile )
759 bool foundSignature =
false;
761 while (!foundSignature)
763 n = dev->read( buffer, 1 );
766 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. " ;
770 if ( buffer[0] !=
'P' )
773 n = dev->read( buffer, 3 );
776 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. " ;
785 if ( buffer[0] ==
'K' && buffer[1] == 3 && buffer[2] == 4 )
787 foundSignature =
true;
788 dev->seek( dev->pos() - 4 );
790 for (
int i = 0; i < 3; ++i) {
791 if (buffer[i] ==
'P') {
793 dev->seek(dev->pos() - 3 + i);
802 kWarning(7040) <<
"Invalid ZIP file. Unrecognized header at offset " << offset;
813 if ( ! (
mode() & QIODevice::WriteOnly ) )
824 uLong crc = crc32(0L, Z_NULL, 0);
828 qint64 atbackup = centraldiroffset;
829 QMutableListIterator<KZipFileEntry*> it( d->m_fileList );
834 if ( !
device()->seek( it.value()->headerStart() + 14 ) )
840 uLong mycrc = it.value()->crc32();
841 buffer[0] = char(mycrc);
842 buffer[1] = char(mycrc >> 8);
843 buffer[2] = char(mycrc >> 16);
844 buffer[3] = char(mycrc >> 24);
846 int mysize1 = it.value()->compressedSize();
847 buffer[4] = char(mysize1);
848 buffer[5] = char(mysize1 >> 8);
849 buffer[6] = char(mysize1 >> 16);
850 buffer[7] = char(mysize1 >> 24);
852 int myusize = it.value()->size();
853 buffer[8] = char(myusize);
854 buffer[9] = char(myusize >> 8);
855 buffer[10] = char(myusize >> 16);
856 buffer[11] = char(myusize >> 24);
858 if (
device()->write( buffer, 12 ) != 12 )
861 device()->seek( atbackup );
870 QByteArray path = QFile::encodeName(it.value()->path());
873 const int bufferSize = extra_field_len + path.length() + 46;
874 char* buffer =
new char[ bufferSize ];
876 memset(buffer, 0, 46);
887 memmove(buffer, head,
sizeof(head));
889 buffer[ 10 ] = char(it.value()->encoding());
890 buffer[ 11 ] = char(it.value()->encoding() >> 8);
894 uLong mycrc = it.value()->crc32();
895 buffer[ 16 ] = char(mycrc);
896 buffer[ 17 ] = char(mycrc >> 8);
897 buffer[ 18 ] = char(mycrc >> 16);
898 buffer[ 19 ] = char(mycrc >> 24);
900 int mysize1 = it.value()->compressedSize();
901 buffer[ 20 ] = char(mysize1);
902 buffer[ 21 ] = char(mysize1 >> 8);
903 buffer[ 22 ] = char(mysize1 >> 16);
904 buffer[ 23 ] = char(mysize1 >> 24);
906 int mysize = it.value()->size();
907 buffer[ 24 ] = char(mysize);
908 buffer[ 25 ] = char(mysize >> 8);
909 buffer[ 26 ] = char(mysize >> 16);
910 buffer[ 27 ] = char(mysize >> 24);
912 buffer[ 28 ] = char(path.length());
913 buffer[ 29 ] = char(path.length() >> 8);
915 buffer[ 30 ] = char(extra_field_len);
916 buffer[ 31 ] = char(extra_field_len >> 8);
918 buffer[ 40 ] = char(it.value()->permissions());
919 buffer[ 41 ] = char(it.value()->permissions() >> 8);
921 int myhst = it.value()->headerStart();
922 buffer[ 42 ] = char(myhst);
923 buffer[ 43 ] = char(myhst >> 8);
924 buffer[ 44 ] = char(myhst >> 16);
925 buffer[ 45 ] = char(myhst >> 24);
928 strncpy( buffer + 46, path, path.length() );
933 char *extfield = buffer + 46 + path.length();
939 extfield[4] = 1 | 2 | 4;
942 unsigned long time = (
unsigned long)it.value()->date();
943 extfield[5] = char(time);
944 extfield[6] = char(time >> 8);
945 extfield[7] = char(time >> 16);
946 extfield[8] = char(time >> 24);
949 crc = crc32(crc, (Bytef *)buffer, bufferSize );
950 bool ok = (
device()->write( buffer, bufferSize ) == bufferSize );
971 int count = d->m_fileList.count();
975 buffer[ 8 ] = char(count);
976 buffer[ 9 ] = char(count >> 8);
978 buffer[ 10 ] = buffer[ 8 ];
979 buffer[ 11 ] = buffer[ 9 ];
981 int cdsize = centraldirendoffset - centraldiroffset;
982 buffer[ 12 ] = char(cdsize);
983 buffer[ 13 ] = char(cdsize >> 8);
984 buffer[ 14 ] = char(cdsize >> 16);
985 buffer[ 15 ] = char(cdsize >> 24);
990 buffer[ 16 ] = char(centraldiroffset);
991 buffer[ 17 ] = char(centraldiroffset >> 8);
992 buffer[ 18 ] = char(centraldiroffset >> 16);
993 buffer[ 19 ] = char(centraldiroffset >> 24);
998 if (
device()->write( buffer, 22 ) != 22 )
1005 mode_t perm, time_t atime, time_t mtime, time_t ctime ) {
1010 if (!name.endsWith(QLatin1Char(
'/')))
1011 dirName = dirName.append(QLatin1Char(
'/'));
1012 return writeFile(dirName, user, group, 0, 0, perm, atime, mtime, ctime);
1017 time_t atime, time_t mtime, time_t ctime) {
1021 qWarning(
"KZip::writeFile: You must open the zip file before writing to it\n");
1025 if ( ! (
mode() & QIODevice::WriteOnly ) )
1027 qWarning(
"KZip::writeFile: You must open the zip file for writing\n");
1034 if ( !
device()->seek( d->m_offset ) ) {
1035 kWarning(7040) <<
"doPrepareWriting: cannot seek in ZIP file. Disk full?";
1042 int i = name.lastIndexOf(QLatin1Char(
'/'));
1045 fileName = name.mid( i + 1 );
1054 QMutableListIterator<KZipFileEntry*> it( d->m_fileList );
1060 if (name == it.value()->path() )
1073 name,
device()->pos() + 30 + name.length(),
1074 0 , d->m_compression, 0 );
1079 d->m_currentFile = e;
1080 d->m_fileList.append( e );
1082 int extra_field_len = 0;
1084 extra_field_len = 17;
1087 QByteArray encodedName = QFile::encodeName(name);
1088 int bufferSize = extra_field_len + encodedName.length() + 30;
1090 char* buffer =
new char[ bufferSize ];
1104 buffer[ 9 ] = char(e->
encoding() >> 8);
1123 buffer[ 26 ] = (uchar)(encodedName.length());
1124 buffer[ 27 ] = (uchar)(encodedName.length() >> 8);
1126 buffer[ 28 ] = (uchar)(extra_field_len);
1127 buffer[ 29 ] = (uchar)(extra_field_len >> 8);
1130 strncpy( buffer + 30, encodedName, encodedName.length() );
1135 char *extfield = buffer + 30 + encodedName.length();
1141 extfield[4] = 1 | 2 | 4;
1143 extfield[5] = char(mtime);
1144 extfield[6] = char(mtime >> 8);
1145 extfield[7] = char(mtime >> 16);
1146 extfield[8] = char(mtime >> 24);
1148 extfield[9] = char(atime);
1149 extfield[10] = char(atime >> 8);
1150 extfield[11] = char(atime >> 16);
1151 extfield[12] = char(atime >> 24);
1153 extfield[13] = char(ctime);
1154 extfield[14] = char(ctime >> 8);
1155 extfield[15] = char(ctime >> 16);
1156 extfield[16] = char(ctime >> 24);
1160 bool b = (
device()->write( buffer, bufferSize ) == bufferSize );
1171 if ( d->m_compression == 0 ) {
1172 d->m_currentDev =
device();
1177 Q_ASSERT( d->m_currentDev );
1178 if ( !d->m_currentDev ) {
1181 static_cast<KFilterDev *
>(d->m_currentDev)->setSkipHeaders();
1183 b = d->m_currentDev->open( QIODevice::WriteOnly );
1190 if ( d->m_currentFile->encoding() == 8 ) {
1192 (void)d->m_currentDev->write( 0, 0 );
1193 delete d->m_currentDev;
1196 d->m_currentDev = 0L;
1198 Q_ASSERT( d->m_currentFile );
1201 d->m_currentFile->setSize(size);
1202 int extra_field_len = 0;
1204 extra_field_len = 17;
1206 const QByteArray encodedName = QFile::encodeName(d->m_currentFile->path());
1207 int csize =
device()->pos() -
1208 d->m_currentFile->headerStart() - 30 -
1209 encodedName.length() - extra_field_len;
1210 d->m_currentFile->setCompressedSize(csize);
1216 d->m_currentFile->setCRC32( d->m_crc );
1218 d->m_currentFile = 0L;
1221 d->m_offset =
device()->pos();
1227 mode_t perm, time_t atime, time_t mtime, time_t ctime) {
1235 kWarning() <<
"prepareWriting failed";
1240 QByteArray symlink_target = QFile::encodeName(target);
1241 if (!
writeData(symlink_target, symlink_target.length())) {
1248 kWarning() <<
"finishWriting failed";
1264 Q_ASSERT( d->m_currentFile );
1265 Q_ASSERT( d->m_currentDev );
1266 if (!d->m_currentFile || !d->m_currentDev) {
1272 d->m_crc = crc32(d->m_crc, (
const Bytef *) data , size);
1274 qint64 written = d->m_currentDev->write( data, size );
1276 return written == size;
1291 d->m_extraField = ef;
1296 return d->m_extraField;
1302class KZipFileEntry::KZipFileEntryPrivate
1305 KZipFileEntryPrivate()
1321 int encoding,
qint64 compressedSize)
1322 :
KArchiveFile(zip, name, access, date, user, group, symlink, start, uncompressedSize ),
1323 d(new KZipFileEntryPrivate)
1326 d->encoding = encoding;
1327 d->compressedSize = compressedSize;
1342 return d->compressedSize;
1347 d->compressedSize = compressedSize;
1352 d->headerStart = headerstart;
1357 return d->headerStart;
1380 arr = dev->readAll();
1400 static_cast<KFilterDev *
>(filterDev)->setSkipHeaders();
1401 bool b = filterDev->open( QIODevice::ReadOnly );
1407 kError() <<
"This zip file contains files compressed with method"
1408 <<
encoding() <<
", this method is currently not supported by KZip,"
1409 <<
"please use a command-line tool to handle this file.";
Represents a directory entry in a KArchive.
void addEntry(KArchiveEntry *)
void removeEntry(KArchiveEntry *)
const KArchiveEntry * entry(const QString &name) const
Returns the entry with the given name.
A base class for entries in an KArchive.
KArchive * archive() const
virtual bool isDirectory() const
Checks whether the entry is a directory.
QDateTime datetime() const
Creation date of the file.
Represents a file entry in a KArchive.
qint64 position() const
Position of the data in the [uncompressed] archive.
KArchive is a base class for reading and writing archives.
QIODevice * device() const
The underlying device.
virtual bool close()
Closes the archive.
virtual KArchiveDirectory * rootDir()
Retrieves or create the root directory.
virtual bool finishWriting(qint64 size)
Call finishWriting after writing the data.
virtual void virtual_hook(int id, void *data)
KArchiveDirectory * findOrCreate(const QString &path)
Ensures that path exists, create otherwise.
QIODevice::OpenMode mode() const
Returns the mode in which the archive was opened.
virtual bool writeFile(const QString &name, const QString &user, const QString &group, const char *data, qint64 size, mode_t perm=0100644, time_t atime=UnknownTime, time_t mtime=UnknownTime, time_t ctime=UnknownTime)
If an archive is opened for writing then you can add a new file using this function.
QString fileName() const
The name of the archive file, as passed to the constructor that takes a fileName, or an empty string ...
bool isOpen() const
Checks whether the archive is open.
A class for reading and writing compressed data onto a device (e.g.
static QIODevice * device(QIODevice *inDevice, const QString &mimetype, bool autoDeleteInDevice=true)
Creates an i/o device that is able to read from the QIODevice inDevice, whether the data is compresse...
A readonly device that reads from an underlying device from a given point to another (e....
A KZipFileEntry represents an file in a zip archive.
KZipFileEntry(KZip *zip, const QString &name, int access, int date, const QString &user, const QString &group, const QString &symlink, const QString &path, qint64 start, qint64 uncompressedSize, int encoding, qint64 compressedSize)
Creates a new zip file entry.
qint64 compressedSize() const
void setCompressedSize(qint64 compressedSize)
Only used when writing.
void setCRC32(unsigned long crc32)
unsigned long crc32() const
CRC: only used when writing.
const QString & path() const
Name with complete path - KArchiveFile::name() is the filename only (no path)
virtual QByteArray data() const
virtual QIODevice * createDevice() const
This method returns a QIODevice to read the file contents.
qint64 headerStart() const
void setHeaderStart(qint64 headerstart)
Header start: only used when writing.
~KZipFileEntry()
Destructor.
A class for reading / writing zip archives.
void setCompression(Compression c)
Call this before writeFile or prepareWriting, to define whether the next files to be written should b...
virtual bool doPrepareWriting(const QString &name, const QString &user, const QString &group, qint64 size, mode_t perm, time_t atime, time_t mtime, time_t ctime)
Reimplemented from KArchive.
ExtraField
Describes the contents of the "extra field" for a given file in the Zip archive.
@ ModificationTime
Modification time ("extended timestamp" header)
@ NoExtraField
No extra field.
virtual bool closeArchive()
Closes the archive.
void setExtraField(ExtraField ef)
Call this before writeFile or prepareWriting, to define what the next file to be written should have ...
KZip(const QString &filename)
Creates an instance that operates on the given filename.
virtual bool openArchive(QIODevice::OpenMode mode)
Opens the archive for reading.
virtual bool doWriteDir(const QString &name, const QString &user, const QString &group, mode_t perm, time_t atime, time_t mtime, time_t ctime)
Reimplemented from KArchive.
virtual ~KZip()
If the zip file is still opened, then it will be closed automatically by the destructor.
virtual void virtual_hook(int id, void *data)
Compression
Describes the compression type for a given file in the Zip archive.
@ DeflateCompression
Deflate compression method.
@ NoCompression
Uncompressed.
Compression compression() const
The current compression mode that will be used for new files.
virtual bool doWriteSymLink(const QString &name, const QString &target, const QString &user, const QString &group, mode_t perm, time_t atime, time_t mtime, time_t ctime)
Reimplemented from KArchive.
virtual bool writeData(const char *data, qint64 size)
Write data to a file that has been created using prepareWriting().
virtual bool doFinishWriting(qint64 size)
Write data to a file that has been created using prepareWriting().
ExtraField extraField() const
The current type of "extra field" that will be used for new files.
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
static time_t transformFromMsDos(const char *buffer)
static void transformToMsDos(const QDateTime &dt, char *buffer)
static bool parseExtraField(const char *buffer, int size, bool islocal, ParseFileInfo &pfi)
parses the extra field
static bool parseInfoZipUnixOld(const char *buffer, int size, bool islocal, ParseFileInfo &pfi)
updates the parse information with the given Info-ZIP Unix old extra field.
static bool seekToNextHeaderToken(QIODevice *dev)
Reads the device forwards from the current pos until a token for a central or local header has been f...
static bool parseExtTimestamp(const char *buffer, int size, bool islocal, ParseFileInfo &pfi)
updates the parse information with the given extended timestamp extra field.
static bool handlePossibleHeaderBegin(const char *buffer, QIODevice *dev)
Checks if a token for a central or local header has been found and resets the device to the begin of ...