25 #include <QtCore/QHash>
26 #include <QtCore/QByteArray>
27 #include <QtCore/QFile>
28 #include <QtCore/QDir>
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 );
88 struct ParseFileInfo {
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;
204 #if 0 // not needed yet
213 static 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";
269 #if 0 // not needed yet
271 if (!parseInfoZipUnixNew(buffer, fieldsize, islocal, pfi))
return false;
288 class KZip::KZipPrivate
314 :
KArchive( fileName ),d(new KZipPrivate)
319 :
KArchive( dev ),d(new KZipPrivate)
334 d->m_fileList.clear();
336 if ( mode == QIODevice::WriteOnly )
353 bool startOfFile =
true;
359 n = dev->read( buffer, 4 );
363 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#1)";
368 if ( !memcmp( buffer,
"PK\5\6", 4 ) )
375 if ( !memcmp( buffer,
"PK\3\4", 4 ) )
380 dev->seek( dev->pos() + 2 );
383 n = dev->read( buffer, 24 );
385 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#4)";
389 int gpf = (uchar)buffer[0];
390 int compression_mode = (uchar)buffer[2] | (uchar)buffer[3] << 8;
393 const qint64 compr_size = uint(uchar(buffer[12])) | uint(uchar(buffer[13])) << 8 |
394 uint(uchar(buffer[14])) << 16 | uint(uchar(buffer[15])) << 24;
395 const qint64 uncomp_size = uint(uchar(buffer[16])) | uint(uchar(buffer[17])) << 8 |
396 uint(uchar(buffer[18])) << 16 | uint(uchar(buffer[19])) << 24;
397 const int namelen = uint(uchar(buffer[20])) | uint(uchar(buffer[21])) << 8;
398 const int extralen = uint(uchar(buffer[22])) | uint(uchar(buffer[23])) << 8;
410 Q_ASSERT( namelen > 0 );
411 QByteArray
fileName = dev->read(namelen);
412 if ( fileName.size() < namelen ) {
413 kWarning(7040) <<
"Invalid ZIP file. Name not completely read (#2)";
422 unsigned int extraFieldEnd = dev->pos() + extralen;
423 pfi.extralen = extralen;
424 int handledextralen = qMin(extralen, (
int)
sizeof buffer);
429 n = dev->read(buffer, handledextralen);
433 kWarning(7040) <<
"Invalid ZIP File. Broken ExtraField.";
438 dev->seek( extraFieldEnd );
448 bool foundSignature =
false;
450 while (!foundSignature)
452 n = dev->read( buffer, 1 );
455 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#2)";
459 if ( buffer[0] !=
'P' )
462 n = dev->read( buffer, 3 );
465 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#3)";
474 if ( buffer[0] ==
'K' && buffer[1] == 7 && buffer[2] == 8 )
476 foundSignature =
true;
477 dev->seek( dev->pos() + 12 );
479 else if ( ( buffer[0] ==
'K' && buffer[1] == 1 && buffer[2] == 2 )
480 || ( buffer[0] ==
'K' && buffer[1] == 3 && buffer[2] == 4 ) )
482 foundSignature =
true;
483 dev->seek( dev->pos() - 4 );
485 else if ( buffer[0] ==
'P' || buffer[1] ==
'P' || buffer[2] ==
'P' )
488 dev->seek( dev->pos() - 3 );
500 && uncomp_size > 0) {
503 pfi.guessed_symlink = dev->read(uncomp_size);
504 if (pfi.guessed_symlink.size() < uncomp_size) {
505 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#5)";
510 if ( compr_size > dev->size() )
514 bool foundSignature =
false;
516 while (!foundSignature)
518 n = dev->read( buffer, 1 );
521 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#2)";
525 if ( buffer[0] !=
'P' )
528 n = dev->read( buffer, 3 );
531 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#3)";
540 if ( buffer[0] ==
'K' && buffer[1] == 7 && buffer[2] == 8 )
542 foundSignature =
true;
543 dev->seek( dev->pos() + 12 );
546 if ( ( buffer[0] ==
'K' && buffer[1] == 1 && buffer[2] == 2 )
547 || ( buffer[0] ==
'K' && buffer[1] == 3 && buffer[2] == 4 ) )
549 foundSignature =
true;
550 dev->seek( dev->pos() - 4 );
559 bool success = dev->seek( dev->pos() + compr_size );
577 pfi_map.insert(fileName, pfi);
579 else if ( !memcmp( buffer,
"PK\1\2", 4 ) )
587 offset = dev->pos() - 4;
590 if ( d->m_offset == 0L ) d->m_offset = offset;
592 n = dev->read( buffer + 4, 42 );
594 kWarning(7040) <<
"Invalid ZIP file, central entry too short";
601 int namelen = (uchar)buffer[29] << 8 | (uchar)buffer[28];
602 Q_ASSERT( namelen > 0 );
603 QByteArray bufferName = dev->read( namelen );
604 if ( bufferName.size() < namelen )
605 kWarning(7040) <<
"Invalid ZIP file. Name not completely read";
607 ParseFileInfo pfi = pfi_map.value( bufferName, ParseFileInfo() );
609 QString name( QFile::decodeName(bufferName) );
614 int extralen = (uchar)buffer[31] << 8 | (uchar)buffer[30];
616 int commlen = (uchar)buffer[33] << 8 | (uchar)buffer[32];
618 int cmethod = (uchar)buffer[11] << 8 | (uchar)buffer[10];
624 uint crc32 = (uchar)buffer[19] << 24 | (uchar)buffer[18] << 16 |
625 (uchar)buffer[17] << 8 | (uchar)buffer[16];
628 uint ucsize = (uchar)buffer[27] << 24 | (uchar)buffer[26] << 16 |
629 (uchar)buffer[25] << 8 | (uchar)buffer[24];
631 uint csize = (uchar)buffer[23] << 24 | (uchar)buffer[22] << 16 |
632 (uchar)buffer[21] << 8 | (uchar)buffer[20];
635 uint localheaderoffset = (uchar)buffer[45] << 24 | (uchar)buffer[44] << 16 |
636 (uchar)buffer[43] << 8 | (uchar)buffer[42];
642 int localextralen = pfi.extralen;
648 uint dataoffset = localheaderoffset + 30 + localextralen + namelen;
654 int os_madeby = (uchar)buffer[5];
658 if (os_madeby == 3) {
659 access = (uchar)buffer[40] | (uchar)buffer[41] << 8;
664 if (name.endsWith(QLatin1Char(
'/'))) {
666 name = name.left( name.length() - 1 );
667 if (os_madeby != 3) access = S_IFDIR | 0755;
668 else Q_ASSERT(access & S_IFDIR);
671 int pos = name.lastIndexOf(QLatin1Char(
'/'));
675 entryName = name.mid( pos + 1 );
676 Q_ASSERT( !entryName.isEmpty() );
681 QString path = QDir::cleanPath( name );
697 if (S_ISLNK(access)) {
698 symlink = QFile::decodeName(pfi.guessed_symlink);
700 entry =
new KZipFileEntry(
this, entryName, access, pfi.mtime,
702 symlink, name, dataoffset,
703 ucsize, cmethod, csize );
704 static_cast<KZipFileEntry *
>(entry)->setHeaderStart( localheaderoffset );
707 d->m_fileList.append( static_cast<KZipFileEntry *>( entry ) );
719 QString path = QDir::cleanPath( name.left( pos ) );
722 tdir->addEntry(entry);
727 offset += 46 + commlen + extralen + namelen;
728 bool b = dev->seek(offset);
733 else if ( startOfFile )
739 bool foundSignature =
false;
741 while (!foundSignature)
743 n = dev->read( buffer, 1 );
746 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. " ;
750 if ( buffer[0] !=
'P' )
753 n = dev->read( buffer, 3 );
756 kWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. " ;
765 if ( buffer[0] ==
'K' && buffer[1] == 3 && buffer[2] == 4 )
767 foundSignature =
true;
768 dev->seek( dev->pos() - 4 );
770 else if ( buffer[0] ==
'P' || buffer[1] ==
'P' || buffer[2] ==
'P' )
773 dev->seek( dev->pos() - 3 );
779 kWarning(7040) <<
"Invalid ZIP file. Unrecognized header at offset " << offset;
790 if ( ! (
mode() & QIODevice::WriteOnly ) )
801 uLong crc = crc32(0L, Z_NULL, 0);
805 qint64 atbackup = centraldiroffset;
806 QMutableListIterator<KZipFileEntry*> it( d->m_fileList );
811 if ( !
device()->seek( it.value()->headerStart() + 14 ) )
817 uLong mycrc = it.value()->crc32();
818 buffer[0] = char(mycrc);
819 buffer[1] = char(mycrc >> 8);
820 buffer[2] = char(mycrc >> 16);
821 buffer[3] = char(mycrc >> 24);
823 int mysize1 = it.value()->compressedSize();
824 buffer[4] = char(mysize1);
825 buffer[5] = char(mysize1 >> 8);
826 buffer[6] = char(mysize1 >> 16);
827 buffer[7] = char(mysize1 >> 24);
829 int myusize = it.value()->size();
830 buffer[8] = char(myusize);
831 buffer[9] = char(myusize >> 8);
832 buffer[10] = char(myusize >> 16);
833 buffer[11] = char(myusize >> 24);
835 if (
device()->write( buffer, 12 ) != 12 )
838 device()->seek( atbackup );
847 QByteArray path = QFile::encodeName(it.value()->path());
849 const int extra_field_len = 9;
850 int bufferSize = extra_field_len + path.length() + 46;
851 char* buffer =
new char[ bufferSize ];
853 memset(buffer, 0, 46);
864 memmove(buffer, head,
sizeof(head));
866 buffer[ 10 ] = char(it.value()->encoding());
867 buffer[ 11 ] = char(it.value()->encoding() >> 8);
871 uLong mycrc = it.value()->crc32();
872 buffer[ 16 ] = char(mycrc);
873 buffer[ 17 ] = char(mycrc >> 8);
874 buffer[ 18 ] = char(mycrc >> 16);
875 buffer[ 19 ] = char(mycrc >> 24);
877 int mysize1 = it.value()->compressedSize();
878 buffer[ 20 ] = char(mysize1);
879 buffer[ 21 ] = char(mysize1 >> 8);
880 buffer[ 22 ] = char(mysize1 >> 16);
881 buffer[ 23 ] = char(mysize1 >> 24);
883 int mysize = it.value()->size();
884 buffer[ 24 ] = char(mysize);
885 buffer[ 25 ] = char(mysize >> 8);
886 buffer[ 26 ] = char(mysize >> 16);
887 buffer[ 27 ] = char(mysize >> 24);
889 buffer[ 28 ] = char(path.length());
890 buffer[ 29 ] = char(path.length() >> 8);
892 buffer[ 30 ] = char(extra_field_len);
893 buffer[ 31 ] = char(extra_field_len >> 8);
895 buffer[ 40 ] = char(it.value()->permissions());
896 buffer[ 41 ] = char(it.value()->permissions() >> 8);
898 int myhst = it.value()->headerStart();
899 buffer[ 42 ] = char(myhst);
900 buffer[ 43 ] = char(myhst >> 8);
901 buffer[ 44 ] = char(myhst >> 16);
902 buffer[ 45 ] = char(myhst >> 24);
905 strncpy( buffer + 46, path, path.length() );
909 char *extfield = buffer + 46 + path.length();
914 extfield[4] = 1 | 2 | 4;
917 unsigned long time = (
unsigned long)it.value()->date();
918 extfield[5] = char(time);
919 extfield[6] = char(time >> 8);
920 extfield[7] = char(time >> 16);
921 extfield[8] = char(time >> 24);
923 crc = crc32(crc, (Bytef *)buffer, bufferSize );
924 bool ok = (
device()->write( buffer, bufferSize ) == bufferSize );
945 int count = d->m_fileList.count();
949 buffer[ 8 ] = char(count);
950 buffer[ 9 ] = char(count >> 8);
952 buffer[ 10 ] = buffer[ 8 ];
953 buffer[ 11 ] = buffer[ 9 ];
955 int cdsize = centraldirendoffset - centraldiroffset;
956 buffer[ 12 ] = char(cdsize);
957 buffer[ 13 ] = char(cdsize >> 8);
958 buffer[ 14 ] = char(cdsize >> 16);
959 buffer[ 15 ] = char(cdsize >> 24);
964 buffer[ 16 ] = char(centraldiroffset);
965 buffer[ 17 ] = char(centraldiroffset >> 8);
966 buffer[ 18 ] = char(centraldiroffset >> 16);
967 buffer[ 19 ] = char(centraldiroffset >> 24);
972 if (
device()->write( buffer, 22 ) != 22 )
979 mode_t perm, time_t atime, time_t mtime, time_t ctime ) {
984 if (!name.endsWith(QLatin1Char(
'/')))
985 dirName = dirName.append(QLatin1Char(
'/'));
986 return writeFile(dirName, user, group, 0, 0, perm, atime, mtime, ctime);
991 time_t atime, time_t mtime, time_t ctime) {
995 qWarning(
"KZip::writeFile: You must open the zip file before writing to it\n");
999 if ( ! (
mode() & QIODevice::WriteOnly ) )
1001 qWarning(
"KZip::writeFile: You must open the zip file for writing\n");
1008 if ( !
device()->seek( d->m_offset ) ) {
1009 kWarning(7040) <<
"doPrepareWriting: cannot seek in ZIP file. Disk full?";
1016 int i = name.lastIndexOf(QLatin1Char(
'/'));
1019 fileName = name.mid( i + 1 );
1028 QMutableListIterator<KZipFileEntry*> it( d->m_fileList );
1034 if (name == it.value()->path() )
1047 name,
device()->pos() + 30 + name.length(),
1048 0 , d->m_compression, 0 );
1053 d->m_currentFile = e;
1054 d->m_fileList.append( e );
1056 int extra_field_len = 0;
1058 extra_field_len = 17;
1061 QByteArray encodedName = QFile::encodeName(name);
1062 int bufferSize = extra_field_len + encodedName.length() + 30;
1064 char* buffer =
new char[ bufferSize ];
1078 buffer[ 9 ] = char(e->
encoding() >> 8);
1097 buffer[ 26 ] = (uchar)(encodedName.length());
1098 buffer[ 27 ] = (uchar)(encodedName.length() >> 8);
1100 buffer[ 28 ] = (uchar)(extra_field_len);
1101 buffer[ 29 ] = (uchar)(extra_field_len >> 8);
1104 strncpy( buffer + 30, encodedName, encodedName.length() );
1109 char *extfield = buffer + 30 + encodedName.length();
1115 extfield[4] = 1 | 2 | 4;
1117 extfield[5] = char(mtime);
1118 extfield[6] = char(mtime >> 8);
1119 extfield[7] = char(mtime >> 16);
1120 extfield[8] = char(mtime >> 24);
1122 extfield[9] = char(atime);
1123 extfield[10] = char(atime >> 8);
1124 extfield[11] = char(atime >> 16);
1125 extfield[12] = char(atime >> 24);
1127 extfield[13] = char(ctime);
1128 extfield[14] = char(ctime >> 8);
1129 extfield[15] = char(ctime >> 16);
1130 extfield[16] = char(ctime >> 24);
1134 bool b = (
device()->write( buffer, bufferSize ) == bufferSize );
1145 if ( d->m_compression == 0 ) {
1146 d->m_currentDev =
device();
1151 Q_ASSERT( d->m_currentDev );
1152 if ( !d->m_currentDev ) {
1155 static_cast<KFilterDev *
>(d->m_currentDev)->setSkipHeaders();
1157 b = d->m_currentDev->open( QIODevice::WriteOnly );
1164 if ( d->m_currentFile->encoding() == 8 ) {
1166 (void)d->m_currentDev->write( 0, 0 );
1167 delete d->m_currentDev;
1170 d->m_currentDev = 0L;
1172 Q_ASSERT( d->m_currentFile );
1175 d->m_currentFile->setSize(size);
1176 int extra_field_len = 0;
1178 extra_field_len = 17;
1180 const QByteArray encodedName = QFile::encodeName(d->m_currentFile->path());
1181 int csize =
device()->pos() -
1182 d->m_currentFile->headerStart() - 30 -
1183 encodedName.length() - extra_field_len;
1184 d->m_currentFile->setCompressedSize(csize);
1190 d->m_currentFile->setCRC32( d->m_crc );
1192 d->m_currentFile = 0L;
1195 d->m_offset =
device()->pos();
1201 mode_t perm, time_t atime, time_t mtime, time_t ctime) {
1209 kWarning() <<
"prepareWriting failed";
1214 QByteArray symlink_target = QFile::encodeName(target);
1215 if (!
writeData(symlink_target, symlink_target.length())) {
1222 kWarning() <<
"finishWriting failed";
1238 Q_ASSERT( d->m_currentFile );
1239 Q_ASSERT( d->m_currentDev );
1240 if (!d->m_currentFile || !d->m_currentDev) {
1246 d->m_crc = crc32(d->m_crc, (
const Bytef *) data , size);
1248 qint64 written = d->m_currentDev->write( data, size );
1250 return written == size;
1265 d->m_extraField = ef;
1270 return d->m_extraField;
1276 class KZipFileEntry::KZipFileEntryPrivate
1279 KZipFileEntryPrivate()
1295 int encoding,
qint64 compressedSize)
1296 :
KArchiveFile(zip, name, access, date, user, group, symlink, start, uncompressedSize ),
1297 d(new KZipFileEntryPrivate)
1316 return d->compressedSize;
1326 d->headerStart = headerstart;
1331 return d->headerStart;
1354 arr = dev->readAll();
1374 static_cast<KFilterDev *
>(filterDev)->setSkipHeaders();
1375 bool b = filterDev->open( QIODevice::ReadOnly );
1381 kError() <<
"This zip file contains files compressed with method"
1382 <<
encoding() <<
", this method is currently not supported by KZip,"
1383 <<
"please use a command-line tool to handle this file.";
ExtraField
Describes the contents of the "extra field" for a given file in the Zip archive.
void removeEntry(KArchiveEntry *)
void setCompression(Compression c)
Call this before writeFile or prepareWriting, to define whether the next files to be written should b...
virtual void virtual_hook(int id, void *data)
virtual KArchiveDirectory * rootDir()
Retrieves or create the root directory.
virtual bool isDirectory() const
Checks whether the entry is a directory.
QIODevice * device() const
The underlying device.
KArchive is a base class for reading and writing archives.
void setCRC32(unsigned long crc32)
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
virtual QByteArray data() const
qint64 headerStart() const
static time_t transformFromMsDos(const char *buffer)
unsigned long crc32() const
CRC: only used when writing.
static void transformToMsDos(const QDateTime &dt, char *buffer)
virtual bool close()
Closes the archive.
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.
qint64 position() const
Position of the data in the [uncompressed] archive.
void setHeaderStart(qint64 headerstart)
Header start: only used when writing.
virtual bool closeArchive()
Closes the archive.
qint64 compressedSize() const
const QString & path() const
Name with complete path - KArchiveFile::name() is the filename only (no path)
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.
static bool parseExtraField(const char *buffer, int size, bool islocal, ParseFileInfo &pfi)
parses the extra field
QString fileName() const
The name of the archive file, as passed to the constructor that takes a fileName, or an empty string ...
A class for reading and writing compressed data onto a device (e.g.
virtual void virtual_hook(int id, void *data)
A base class for entries in an KArchive.
virtual bool finishWriting(qint64 size)
Call finishWriting after writing the data.
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.
virtual bool openArchive(QIODevice::OpenMode mode)
Opens the archive for reading.
A readonly device that reads from an underlying device from a given point to another (e...
A class for reading / writing zip archives.
Deflate compression method.
virtual bool doFinishWriting(qint64 size)
Write data to a file that has been created using prepareWriting().
Compression compression() const
The current compression mode that will be used for new files.
bool isOpen() const
Checks whether the archive is open.
const KArchiveEntry * entry(const QString &name) const
Returns the entry with the given name.
void addEntry(KArchiveEntry *)
Compression
Describes the compression type for a given file in the Zip archive.
KZip(const QString &filename)
Creates an instance that operates on the given filename.
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...
KArchiveDirectory * findOrCreate(const QString &path)
Ensures that path exists, create otherwise.
Represents a directory entry in a KArchive.
int access(const QString &path, int mode)
void setExtraField(ExtraField ef)
Call this before writeFile or prepareWriting, to define what the next file to be written should have ...
static bool parseExtTimestamp(const char *buffer, int size, bool islocal, ParseFileInfo &pfi)
updates the parse information with the given extended timestamp extra field.
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 bool writeData(const char *data, qint64 size)
Write data to a file that has been created using prepareWriting().
Represents a file entry in a KArchive.
virtual ~KZip()
If the zip file is still opened, then it will be closed automatically by the destructor.
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.
~KZipFileEntry()
Destructor.
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.
QDateTime datetime() const
Creation date of the file.
void setCompressedSize(qint64 compressedSize)
Only used when writing.
A KZipFileEntry represents an file in a zip archive.
KArchive * archive() const
Modification time ("extended timestamp" header)
ExtraField extraField() const
The current type of "extra field" that will be used for new files.
virtual QIODevice * createDevice() const
This method returns a QIODevice to read the file contents.