28 #include <QSharedData>
33 #pragma warning(disable : 4996)
36 class QuaZipDirPrivate :
public QSharedData {
40 QuaZipDirPrivate(
QuaZip *zip,
const QString &dir = QString())
52 template <
typename TFileInfoList>
56 TFileInfoList &
result)
const;
57 inline QString simplePath()
const {
return QDir::cleanPath(dir); }
64 : d(new QuaZipDirPrivate(zip, dir)) {
65 if (d->dir.startsWith(
'/')) d->dir = d->dir.mid(1);
71 return d->zip == that.d->zip && d->dir == that.d->dir;
82 return d->caseSensitivity;
86 if (directoryName ==
"/") {
90 QString
dirName = directoryName;
95 #ifdef QUAZIP_QUAZIPDIR_DEBUG
96 qDebug(
"QuaZipDir::cd(%s): going to /",
99 if (!dir.
cd(
"/"))
return false;
102 for (QStringList::const_iterator i =
path.constBegin(); i !=
path.end();
104 const QString &step = *i;
105 #ifdef QUAZIP_QUAZIPDIR_DEBUG
106 qDebug(
"QuaZipDir::cd(%s): going to %s",
107 dirName.toUtf8().constData(), step.toUtf8().constData());
109 if (!dir.
cd(step))
return false;
120 int slashPos = d->dir.lastIndexOf(
'/');
121 if (slashPos == -1) {
124 d->dir = d->dir.left(slashPos);
150 const QString &relativeName,
167 info.
name = relativeName;
172 QList<QuaZipFileInfo64> &to) {
179 for (QList<QuaZipFileInfo64>::const_iterator i = from.constBegin();
180 i != from.constEnd(); ++i) {
186 QList<QuaZipFileInfo> &to) {
188 for (QList<QuaZipFileInfo64>::const_iterator i = from.constBegin();
189 i != from.constEnd(); ++i) {
191 i->toQuaZipFileInfo(info32);
200 class QuaZipDirRestoreCurrent {
202 inline QuaZipDirRestoreCurrent(
QuaZip *zip)
203 : zip(zip), currentFile(zip->getCurrentFileName()) {}
204 inline ~QuaZipDirRestoreCurrent() { zip->
setCurrentFile(currentFile); }
213 class QuaZipDirComparator {
215 QDir::SortFlags sort;
216 static QString getExtension(
const QString &
name);
217 int compareStrings(
const QString &string1,
const QString &string2);
220 inline QuaZipDirComparator(QDir::SortFlags sort) : sort(sort) {}
225 QString QuaZipDirComparator::getExtension(
const QString &
name) {
226 if (
name.endsWith(
'.') ||
name.indexOf(
'.', 1) == -1) {
229 return name.mid(
name.lastIndexOf(
'.') + 1);
233 int QuaZipDirComparator::compareStrings(
const QString &string1,
234 const QString &string2) {
235 if (sort & QDir::LocaleAware) {
236 if (sort & QDir::IgnoreCase) {
237 return string1.toLower().localeAwareCompare(string2.toLower());
239 return string1.localeAwareCompare(string2);
242 return string1.compare(string2, (sort & QDir::IgnoreCase)
244 : Qt::CaseSensitive);
250 QDir::SortFlags order =
251 sort & (QDir::Name |
QDir::Time | QDir::Size | QDir::Type);
252 if ((sort & QDir::DirsFirst) == QDir::DirsFirst ||
253 (sort & QDir::DirsLast) == QDir::DirsLast) {
254 if (info1.
name.endsWith(
'/') && !info2.
name.endsWith(
'/'))
255 return (sort & QDir::DirsFirst) == QDir::DirsFirst;
256 else if (!info1.
name.endsWith(
'/') && info2.
name.endsWith(
'/'))
257 return (sort & QDir::DirsLast) == QDir::DirsLast;
266 extDiff = compareStrings(getExtension(info1.
name),
267 getExtension(info2.
name));
289 qWarning(
"QuaZipDirComparator(): Invalid sort mode 0x%2X",
290 static_cast<unsigned>(sort));
296 template <
typename TFileInfoList>
297 bool QuaZipDirPrivate::entryInfoList(QStringList nameFilters,
298 QDir::Filters filter,
299 QDir::SortFlags sort,
300 TFileInfoList &
result)
const {
301 QString basePath = simplePath();
302 if (!basePath.isEmpty()) basePath +=
"/";
303 int baseLength = basePath.length();
305 QuaZipDirRestoreCurrent saveCurrent(zip);
306 if (!zip->goToFirstFile()) {
307 return zip->getZipError() ==
UNZ_OK;
309 QDir::Filters fltr = filter;
310 if (fltr == QDir::NoFilter) fltr = this->filter;
311 if (fltr == QDir::NoFilter) fltr = QDir::AllEntries;
312 QStringList nmfltr = nameFilters;
313 if (nmfltr.isEmpty()) nmfltr = this->nameFilters;
314 QSet<QString> dirsFound;
315 QList<QuaZipFileInfo64> list;
317 QString
name = zip->getCurrentFileName();
318 if (!
name.startsWith(basePath))
continue;
319 QString relativeName =
name.mid(baseLength);
320 if (relativeName.isEmpty())
continue;
323 if (relativeName.contains(
'/')) {
324 int indexOfSlash = relativeName.indexOf(
'/');
326 isReal = indexOfSlash == relativeName.length() - 1;
327 relativeName = relativeName.left(indexOfSlash + 1);
328 if (dirsFound.contains(relativeName))
continue;
331 dirsFound.insert(relativeName);
332 if ((fltr & QDir::Dirs) == 0 && isDir)
continue;
333 if ((fltr & QDir::Files) == 0 && !isDir)
continue;
334 if (!nmfltr.isEmpty() && !QDir::match(nmfltr, relativeName))
continue;
342 }
while (zip->goToNextFile());
343 QDir::SortFlags srt = sort;
344 if (srt == QDir::NoSort) srt = sorting;
345 #ifdef QUAZIP_QUAZIPDIR_DEBUG
346 qDebug(
"QuaZipDirPrivate::entryInfoList(): before sort:");
348 qDebug(
"%s\t%s", info.
name.toUtf8().constData(),
349 info.
dateTime.toString(Qt::ISODate).toUtf8().constData());
352 if (srt != QDir::NoSort && (srt & QDir::Unsorted) != QDir::Unsorted) {
355 srt |= QDir::IgnoreCase;
356 QuaZipDirComparator lessThan(srt);
358 std::sort(list.begin(), list.end(), lessThan);
367 QDir::Filters filters,
368 QDir::SortFlags sort)
const {
369 QList<QuaZipFileInfo>
result;
373 return QList<QuaZipFileInfo>();
377 QDir::SortFlags sort)
const {
382 const QStringList &nameFilters,
383 QDir::Filters filters,
384 QDir::SortFlags sort)
const {
385 QList<QuaZipFileInfo64>
result;
389 return QList<QuaZipFileInfo64>();
393 QDir::SortFlags sort)
const {
398 QDir::Filters filters,
399 QDir::SortFlags sort)
const {
404 return QStringList();
408 QDir::SortFlags sort)
const {
409 return entryList(QStringList(), filters, sort);
415 if (fileName.endsWith(
'/')) fileName.chop(1);
416 if (fileName.contains(
'/')) {
417 QFileInfo fileInfo(fileName);
418 #ifdef QUAZIP_QUAZIPDIR_DEBUG
419 qDebug(
"QuaZipDir::exists(): fileName=%s, fileInfo.fileName()=%s, "
420 "fileInfo.path()=%s",
421 fileName.toUtf8().constData(),
422 fileInfo.fileName().toUtf8().constData(),
423 fileInfo.path().toUtf8().constData());
426 return dir.
cd(fileInfo.path()) && dir.
exists(fileInfo.fileName());
428 if (fileName ==
"..") {
430 }
else if (fileName ==
".") {
433 QStringList entries =
entryList(QDir::AllEntries, QDir::NoSort);
434 #ifdef QUAZIP_QUAZIPDIR_DEBUG
435 qDebug(
"QuaZipDir::exists(): looking for %s",
436 fileName.toUtf8().constData());
437 for (QStringList::const_iterator i = entries.constBegin();
438 i != entries.constEnd(); ++i) {
439 qDebug(
"QuaZipDir::exists(): entry: %s",
440 i->toUtf8().constData());
443 Qt::CaseSensitivity cs =
446 return entries.contains(
filePath, cs);
448 return entries.contains(fileName, cs) ||
449 entries.contains(fileName +
"/", cs);
458 return QDir(d->dir).filePath(fileName);
470 return QDir(
"/" + d->dir).relativeFilePath(fileName);
484 QString newDir =
path;
488 if (newDir.endsWith(
'/')) newDir.chop(1);
489 if (newDir.startsWith(
'/')) newDir = newDir.mid(1);
Provides ZIP archive navigation.
QuaZip::CaseSensitivity caseSensitivity() const
Returns the current case sensitivity mode.
QString dirName() const
Returns the current directory name.
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.
bool operator==(const QuaZipDir &that)
The assignment operator.
QuaZipDir(const QuaZipDir &that)
The copy constructor.
void setFilter(QDir::Filters filters)
Sets the default filter.
uint count() const
Returns the number of entries in the directory.
QString relativeFilePath(const QString &fileName) const
Returns the path to the specified file relative to the current dir.
QuaZipDir & operator=(const QuaZipDir &that)
operator==
QString operator[](int pos) const
Returns the name of the entry at the specified position.
bool cd(const QString &dirName)
Changes the 'current' directory.
void setNameFilters(const QStringList &nameFilters)
Sets the default name filter.
QDir::Filters filter()
Returns the default filter.
bool isRoot() const
Returns if the QuaZipDir points to the root of the archive.
void setCaseSensitivity(QuaZip::CaseSensitivity caseSensitivity)
Sets the default case sensitivity mode.
QStringList nameFilters() const
Return the default name filter.
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.
QDir::SortFlags sorting() const
Returns the default sorting mode.
void setSorting(QDir::SortFlags sort)
Sets the default sorting mode.
QString path() const
Returns the path to the current dir.
bool exists(const QString &fileName) const
Returns true if the entry with the specified name exists.
void setPath(const QString &path)
Goes to the specified path.
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.
QString filePath(const QString &fileName) const
Returns the full path to the specified file.
bool exists() const
Return true if the directory pointed by this QuaZipDir exists.
static Qt::CaseSensitivity convertCaseSensitivity(CaseSensitivity cs)
Returns the actual case sensitivity for the specified QuaZIP one.
CaseSensitivity
Case sensitivity for the file names.
bool setCurrentFile(const QString &fileName, CaseSensitivity cs=csDefault)
Sets current file by its name.
bool getCurrentFileInfo(QuaZipFileInfo *info) const
Retrieves information about the current file.
constexpr QRegularExpression::PatternOption CaseInsensitive
constexpr Qt::SplitBehavior SkipEmptyParts
static const std::string path
static void QuaZipDir_convertInfoList(const QList< QuaZipFileInfo64 > &from, QList< QuaZipFileInfo64 > &to)
QuaZipFileInfo64 QuaZipDir_getFileInfo(QuaZip *zip, bool *ok, const QString &relativeName, bool isReal)
Information about a file inside archive (with zip64 support).
quint16 versionNeeded
Version needed to extract.
quint32 externalAttr
External file attributes.
quint16 method
Compression method.
QDateTime dateTime
Last modification date and time.
quint64 uncompressedSize
Uncompressed file size.
quint16 flags
General purpose flags.
quint16 versionCreated
Version created by.
quint16 diskNumberStart
Disk number start.
quint64 compressedSize
Compressed file size.
quint16 internalAttr
Internal file attributes.
Information about a file inside archive.