25 #include <QtCore/QHash>
26 #include <QtCore/QByteArray>
27 #include <QtCore/QFile>
28 #include <QtCore/QDir>
29 #include <QtCore/QDate>
30 #include <QtCore/QList>
47 buffer[0] = char(time);
48 buffer[1] = char(time >> 8);
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 {
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;
304 if (buffer[0] ==
'K') {
305 if (buffer[1] == 7 && buffer[2] == 8) {
311 if ((buffer[1] == 1 && buffer[2] == 2)
312 || (buffer[1] == 3 && buffer[2] == 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') {
370 class 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 ) )
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 );
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);
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 );
624 if ( bufferName.
size() < namelen )
625 kWarning(7040) <<
"Invalid ZIP file. Name not completely read";
627 ParseFileInfo pfi = pfi_map.
value( bufferName, ParseFileInfo() );
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];
678 if (os_madeby == 3) {
679 access = (uchar)buffer[40] | (uchar)buffer[41] << 8;
687 if (os_madeby != 3) access = S_IFDIR | 0755;
688 else Q_ASSERT(access & S_IFDIR);
695 entryName = name.
mid( pos + 1 );
696 Q_ASSERT( !entryName.
isEmpty() );
717 if (S_ISLNK(access)) {
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 ) );
742 tdir->addEntry(entry);
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;
790 for (
int i = 0; i < 3; ++i) {
791 if (buffer[i] ==
'P') {
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;
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 )
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 ) {
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?";
1045 fileName = name.
mid( i + 1 );
1060 if (name == it.
value()->path() )
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;
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;
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;
1227 mode_t perm, time_t atime, time_t mtime, time_t ctime) {
1235 kWarning() <<
"prepareWriting failed";
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;
1302 class KZipFileEntry::KZipFileEntryPrivate
1305 KZipFileEntryPrivate()
1321 int encoding,
qint64 compressedSize)
1322 :
KArchiveFile(zip, name, access, date, user, group, symlink, start, uncompressedSize ),
1323 d(new KZipFileEntryPrivate)
1342 return d->compressedSize;
1352 d->headerStart = headerstart;
1357 return d->headerStart;
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.";
ExtraField
Describes the contents of the "extra field" for a given file in the Zip archive.
void removeEntry(KArchiveEntry *)
QString & append(QChar ch)
void setCompression(Compression c)
Call this before writeFile or prepareWriting, to define whether the next files to be written should b...
iterator insert(const Key &key, const T &value)
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.
virtual bool seek(qint64 pos)
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
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
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.
virtual qint64 pos() const
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
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 qint64 size() const
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.
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 ...
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.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
virtual bool openArchive(QIODevice::OpenMode mode)
Opens the archive for reading.
qint64 read(char *data, qint64 maxSize)
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.
const T value(const Key &key) const
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...
QString cleanPath(const QString &path)
KArchiveDirectory * findOrCreate(const QString &path)
Ensures that path exists, create otherwise.
Represents a directory entry in a KArchive.
QString mid(int position, int n) const
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...
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.
QString left(int n) const
qint64 write(const char *data, qint64 maxSize)
QString fromLatin1(const char *str, int size)
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.
QByteArray encodeName(const QString &fileName)
QString decodeName(const QByteArray &localFileName)
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.