28 #include <QSharedData>
31 class QuaZipDirPrivate:
public QSharedData {
34 QuaZipDirPrivate(
QuaZip *zip,
const QString &dir = QString()):
43 template<
typename TFileInfoList>
45 QDir::SortFlags sort, TFileInfoList &result)
const;
46 inline QString simplePath()
const {
return QDir::cleanPath(dir);}
56 d(new QuaZipDirPrivate(zip, dir))
58 if (
d->dir.startsWith(
'/'))
59 d->dir =
d->dir.mid(1);
68 return d->zip == that.
d->zip &&
d->dir == that.
d->dir;
84 return d->caseSensitivity;
89 if (directoryName ==
"/") {
93 QString
dirName = directoryName;
94 if (dirName.endsWith(
'/'))
96 if (dirName.contains(
'/')) {
98 if (dirName.startsWith(
'/')) {
99 #ifdef QUAZIP_QUAZIPDIR_DEBUG
100 qDebug(
"QuaZipDir::cd(%s): going to /",
101 dirName.toUtf8().constData());
106 QStringList
path = dirName.split(
'/', QString::SkipEmptyParts);
107 for (QStringList::const_iterator i = path.constBegin();
110 const QString &step = *i;
111 #ifdef QUAZIP_QUAZIPDIR_DEBUG
112 qDebug(
"QuaZipDir::cd(%s): going to %s",
113 dirName.toUtf8().constData(),
114 step.toUtf8().constData());
122 if (dirName ==
".") {
124 }
else if (dirName ==
"..") {
128 int slashPos =
d->dir.lastIndexOf(
'/');
129 if (slashPos == -1) {
132 d->dir =
d->dir.left(slashPos);
162 return QDir(
d->dir).dirName();
166 const QString &relativeName,
184 info.
name = relativeName;
189 QList<QuaZipFileInfo64> &to)
198 for (QList<QuaZipFileInfo64>::const_iterator i = from.constBegin();
199 i != from.constEnd();
206 QList<QuaZipFileInfo> &to)
209 for (QList<QuaZipFileInfo64>::const_iterator i = from.constBegin();
210 i != from.constEnd();
213 i->toQuaZipFileInfo(info32);
222 class QuaZipDirRestoreCurrent {
224 inline QuaZipDirRestoreCurrent(
QuaZip *zip):
225 zip(zip), currentFile(zip->getCurrentFileName()) {}
226 inline ~QuaZipDirRestoreCurrent()
237 class QuaZipDirComparator
240 QDir::SortFlags sort;
241 static QString getExtension(
const QString &name);
242 int compareStrings(
const QString &string1,
const QString &string2);
244 inline QuaZipDirComparator(QDir::SortFlags sort): sort(sort) {}
248 QString QuaZipDirComparator::getExtension(
const QString &name)
250 if (name.endsWith(
'.') || name.indexOf(
'.', 1) == -1) {
253 return name.mid(name.lastIndexOf(
'.') + 1);
258 int QuaZipDirComparator::compareStrings(
const QString &string1,
259 const QString &string2)
261 if (sort & QDir::LocaleAware) {
262 if (sort & QDir::IgnoreCase) {
263 return string1.toLower().localeAwareCompare(string2.toLower());
265 return string1.localeAwareCompare(string2);
268 return string1.compare(string2, (sort & QDir::IgnoreCase)
269 ? Qt::CaseInsensitive : Qt::CaseSensitive);
276 QDir::SortFlags order = sort
277 & (QDir::Name | QDir::Time | QDir::Size | QDir::Type);
278 if ((sort & QDir::DirsFirst) == QDir::DirsFirst
279 || (sort & QDir::DirsLast) == QDir::DirsLast) {
280 if (info1.
name.endsWith(
'/') && !info2.
name.endsWith(
'/'))
281 return (sort & QDir::DirsFirst) == QDir::DirsFirst;
282 else if (!info1.
name.endsWith(
'/') && info2.
name.endsWith(
'/'))
283 return (sort & QDir::DirsLast) == QDir::DirsLast;
289 result = compareStrings(info1.
name, info2.
name) < 0;
292 extDiff = compareStrings(getExtension(info1.
name),
293 getExtension(info2.
name));
295 result = compareStrings(info1.
name, info2.
name) < 0;
297 result = extDiff < 0;
302 result = compareStrings(info1.
name, info2.
name) < 0;
309 result = compareStrings(info1.
name, info2.
name) < 0;
315 qWarning(
"QuaZipDirComparator(): Invalid sort mode 0x%2X",
316 static_cast<unsigned>(sort));
319 return (sort & QDir::Reversed) ? !result : result;
322 template<
typename TFileInfoList>
323 bool QuaZipDirPrivate::entryInfoList(QStringList nameFilters,
324 QDir::Filters filter, QDir::SortFlags sort, TFileInfoList &result)
const
326 QString basePath = simplePath();
327 if (!basePath.isEmpty())
329 int baseLength = basePath.length();
331 QuaZipDirRestoreCurrent saveCurrent(zip);
332 if (!zip->goToFirstFile()) {
333 return zip->getZipError() ==
UNZ_OK;
335 QDir::Filters fltr = filter;
336 if (fltr == QDir::NoFilter)
338 if (fltr == QDir::NoFilter)
339 fltr = QDir::AllEntries;
340 QStringList nmfltr = nameFilters;
341 if (nmfltr.isEmpty())
342 nmfltr = this->nameFilters;
343 QSet<QString> dirsFound;
344 QList<QuaZipFileInfo64> list;
346 QString name = zip->getCurrentFileName();
347 if (!name.startsWith(basePath))
349 QString relativeName = name.mid(baseLength);
350 if (relativeName.isEmpty())
354 if (relativeName.contains(
'/')) {
355 int indexOfSlash = relativeName.indexOf(
'/');
357 isReal = indexOfSlash == relativeName.length() - 1;
358 relativeName = relativeName.left(indexOfSlash + 1);
359 if (dirsFound.contains(relativeName))
363 dirsFound.insert(relativeName);
364 if ((fltr & QDir::Dirs) == 0 && isDir)
366 if ((fltr & QDir::Files) == 0 && !isDir)
368 if (!nmfltr.isEmpty() && !QDir::match(nmfltr, relativeName))
377 }
while (zip->goToNextFile());
378 QDir::SortFlags srt = sort;
379 if (srt == QDir::NoSort)
381 #ifdef QUAZIP_QUAZIPDIR_DEBUG
382 qDebug(
"QuaZipDirPrivate::entryInfoList(): before sort:");
384 qDebug(
"%s\t%s", info.
name.toUtf8().constData(),
385 info.
dateTime.toString(Qt::ISODate).toUtf8().constData());
388 if (srt != QDir::NoSort && (srt & QDir::Unsorted) != QDir::Unsorted) {
390 == Qt::CaseInsensitive)
391 srt |= QDir::IgnoreCase;
392 QuaZipDirComparator lessThan(srt);
393 qSort(list.begin(), list.end(), lessThan);
402 QDir::Filters filters, QDir::SortFlags sort)
const
404 QList<QuaZipFileInfo> result;
405 if (
d->entryInfoList(nameFilters, filters, sort, result))
408 return QList<QuaZipFileInfo>();
412 QDir::SortFlags sort)
const
418 QDir::Filters filters, QDir::SortFlags sort)
const
420 QList<QuaZipFileInfo64> result;
421 if (
d->entryInfoList(nameFilters, filters, sort, result))
424 return QList<QuaZipFileInfo64>();
428 QDir::SortFlags sort)
const
434 QDir::Filters filters, QDir::SortFlags sort)
const
437 if (
d->entryInfoList(nameFilters, filters, sort, result))
440 return QStringList();
444 QDir::SortFlags sort)
const
446 return entryList(QStringList(), filters, sort);
451 if (filePath ==
"/" || filePath.isEmpty())
454 if (fileName.endsWith(
'/'))
456 if (fileName.contains(
'/')) {
457 QFileInfo fileInfo(fileName);
458 #ifdef QUAZIP_QUAZIPDIR_DEBUG
459 qDebug(
"QuaZipDir::exists(): fileName=%s, fileInfo.fileName()=%s, "
460 "fileInfo.path()=%s", fileName.toUtf8().constData(),
461 fileInfo.fileName().toUtf8().constData(),
462 fileInfo.path().toUtf8().constData());
465 return dir.cd(fileInfo.path()) && dir.exists(fileInfo.fileName());
467 if (fileName ==
"..") {
469 }
else if (fileName ==
".") {
472 QStringList entries =
entryList(QDir::AllEntries, QDir::NoSort);
473 #ifdef QUAZIP_QUAZIPDIR_DEBUG
474 qDebug(
"QuaZipDir::exists(): looking for %s",
475 fileName.toUtf8().constData());
476 for (QStringList::const_iterator i = entries.constBegin();
477 i != entries.constEnd();
479 qDebug(
"QuaZipDir::exists(): entry: %s",
480 i->toUtf8().constData());
485 if (filePath.endsWith(
'/')) {
486 return entries.contains(filePath, cs);
488 return entries.contains(fileName, cs)
489 || entries.contains(fileName +
"/", cs);
502 return QDir(
d->dir).filePath(fileName);
512 return d->simplePath().isEmpty();
517 return d->nameFilters;
527 return QDir(
"/" +
d->dir).relativeFilePath(fileName);
547 QString newDir =
path;
551 if (newDir.endsWith(
'/'))
553 if (newDir.startsWith(
'/'))
554 newDir = newDir.mid(1);
static Qt::CaseSensitivity convertCaseSensitivity(CaseSensitivity cs)
Returns the actual case sensitivity for the specified QuaZIP one.
bool operator==(const QuaZipDir &that)
The assignment operator.
quint16 diskNumberStart
Disk number start.
QStringList nameFilters() const
Return the default name filter.
bool exists() const
Return true if the directory pointed by this QuaZipDir exists.
quint16 versionCreated
Version created by.
QList< QuaZipFileInfo64 > entryInfoList64(const QStringList &nameFilters, QDir::Filters filters=QDir::NoFilter, QDir::SortFlags sort=QDir::NoSort) const
Returns the list of the entries in the directory with zip64 support.
quint32 externalAttr
External file attributes.
quint16 versionNeeded
Version needed to extract.
QString operator[](int pos) const
Returns the name of the entry at the specified position.
QDir::Filters filter()
Returns the default filter.
QuaZipDir(const QuaZipDir &that)
The copy constructor.
Information about a file inside archive.
bool isRoot() const
Returns if the QuaZipDir points to the root of the archive.
QuaZipDir & operator=(const QuaZipDir &that)
operator==
QString relativeFilePath(const QString &fileName) const
Returns the path to the specified file relative to the current dir.
quint64 compressedSize
Compressed file size.
void setSorting(QDir::SortFlags sort)
Sets the default sorting mode.
static void QuaZipDir_convertInfoList(const QList< QuaZipFileInfo64 > &from, QList< QuaZipFileInfo64 > &to)
QString path() const
Returns the path to the current dir.
void setNameFilters(const QStringList &nameFilters)
Sets the default name filter.
QStringList entryList(const QStringList &nameFilters, QDir::Filters filters=QDir::NoFilter, QDir::SortFlags sort=QDir::NoSort) const
Returns the list of the entry names in the directory.
Information about a file inside archive (with zip64 support).
bool setCurrentFile(const QString &fileName, CaseSensitivity cs=csDefault)
Sets current file by its name.
quint16 method
Compression method.
void setFilter(QDir::Filters filters)
Sets the default filter.
quint64 uncompressedSize
Uncompressed file size.
bool cd(const QString &dirName)
Changes the 'current' directory.
QSharedDataPointer< QuaZipDirPrivate > d
void setCaseSensitivity(QuaZip::CaseSensitivity caseSensitivity)
Sets the default case sensitivity mode.
CaseSensitivity
Case sensitivity for the file names.
Provides ZIP archive navigation.
uint count() const
Returns the number of entries in the directory.
QDateTime dateTime
Last modification date and time.
quint16 flags
General purpose flags.
QString filePath(const QString &fileName) const
Returns the full path to the specified file.
QString dirName() const
Returns the current directory name.
QList< QuaZipFileInfo > entryInfoList(const QStringList &nameFilters, QDir::Filters filters=QDir::NoFilter, QDir::SortFlags sort=QDir::NoSort) const
Returns the list of the entries in the directory.
void setPath(const QString &path)
Goes to the specified path.
QuaZipFileInfo64 QuaZipDir_getFileInfo(QuaZip *zip, bool *ok, const QString &relativeName, bool isReal)
QuaZip::CaseSensitivity caseSensitivity() const
Returns the current case sensitivity mode.
QDir::SortFlags sorting() const
Returns the default sorting mode.
quint16 internalAttr
Internal file attributes.
bool getCurrentFileInfo(QuaZipFileInfo *info) const
Retrieves information about the current file.