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 *)
qint64 compressedSize() const
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.
qint64 position() const
Position of the data in the [uncompressed] archive.
KArchive * archive() const
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)
unsigned long crc32() const
CRC: only used when writing.
Compression compression() const
The current compression mode that will be used for new files.
QIODevice * device() const
The underlying device.
static time_t transformFromMsDos(const char *buffer)
QString fileName() const
The name of the archive file, as passed to the constructor that takes a fileName, or an empty string ...
static void transformToMsDos(const QDateTime &dt, char *buffer)
virtual bool close()
Closes the archive.
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.
void setHeaderStart(qint64 headerstart)
Header start: only used when writing.
virtual bool closeArchive()
Closes the archive.
QDateTime datetime() const
Creation date of the file.
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
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.
ExtraField extraField() const
The current type of "extra field" that will be used for new files.
virtual bool doFinishWriting(qint64 size)
Write data to a file that has been created using prepareWriting().
const QString & path() const
Name with complete path - KArchiveFile::name() is the filename only (no path)
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.
virtual QIODevice * createDevice() const
This method returns a QIODevice to read the file contents.
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().
const KArchiveEntry * entry(const QString &name) const
Returns the entry with the given name.
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 isDirectory() const
Checks whether the entry is a directory.
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.
bool isOpen() const
Checks whether the archive is open.
~KZipFileEntry()
Destructor.
qint64 headerStart() const
QIODevice::OpenMode mode() const
Returns the mode in which the archive was opened.
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.
void setCompressedSize(qint64 compressedSize)
Only used when writing.
A KZipFileEntry represents an file in a zip archive.
Modification time ("extended timestamp" header)
virtual QByteArray data() const