Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions 3rdparty/cli7zplugin/cli7zplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,23 @@ void Cli7zPlugin::killProcess(bool emitFinished)
m_isProcessKilled = true;
}

// The "yyyy-MM-dd hh:mm:ss" local time of a listing line. Same result as
// QDateTime::fromString(text, "yyyy-MM-dd hh:mm:ss"), whose format parser costs tens of microseconds
// per call (seconds for an archive with thousands of entries); anything else still goes through it.
static QDateTime listTimeFromString(const QString &text)
{
if (text.size() == 19 && text.at(4) == QLatin1Char('-') && text.at(7) == QLatin1Char('-')
&& text.at(10) == QLatin1Char(' ') && text.at(13) == QLatin1Char(':') && text.at(16) == QLatin1Char(':')) {
bool ok[6] = {};
const QDate date(text.mid(0, 4).toInt(&ok[0]), text.mid(5, 2).toInt(&ok[1]), text.mid(8, 2).toInt(&ok[2]));
const QTime time(text.mid(11, 2).toInt(&ok[3]), text.mid(14, 2).toInt(&ok[4]), text.mid(17, 2).toInt(&ok[5]));
if (ok[0] && ok[1] && ok[2] && ok[3] && ok[4] && ok[5] && date.isValid() && time.isValid()) {
return QDateTime(date, time);
}
}
return QDateTime::fromString(text, QStringLiteral("yyyy-MM-dd hh:mm:ss"));
}

bool Cli7zPlugin::readListLine(const QString &line)
{
ArchiveData &stArchiveData = DataManager::get_instance().archiveData();
Expand All @@ -193,7 +210,7 @@ bool Cli7zPlugin::readListLine(const QString &line)
return false;
}

const QRegularExpression rxVersionLine(QStringLiteral("^(?:p7zip Version|7-Zip) ([\\d\\.]+).*$"));
static const QRegularExpression rxVersionLine(QStringLiteral("^(?:p7zip Version|7-Zip) ([\\d\\.]+).*$"));
QRegularExpressionMatch matchVersion;

switch (m_parseState) {
Expand Down Expand Up @@ -271,11 +288,11 @@ bool Cli7zPlugin::readListLine(const QString &line)
if (dotIndex != -1) {
modifiedTime.truncate(dotIndex);
}
m_fileEntry.uLastModifiedTime = QDateTime::fromString(modifiedTime,
m_fileEntry.uLastModifiedTime = listTimeFromString(modifiedTime)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QStringLiteral("yyyy-MM-dd hh:mm:ss")).toTime_t();
.toTime_t();
#else
QStringLiteral("yyyy-MM-dd hh:mm:ss")).toSecsSinceEpoch();
.toSecsSinceEpoch();
#endif
if (ArchiveTypeIso == m_archiveType || ArchiveTypeUdf == m_archiveType) { // 读取的压缩包是iso、udf文件,读到Modified的时候已经结束了
// QString name = m_fileEntry.strFullPath;
Expand Down
28 changes: 23 additions & 5 deletions 3rdparty/clirarplugin/clirarplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "datamanager.h"

#include <QRegularExpression>
#include <QDateTime>
#include <QFileInfo>
#include <QDir>
#include <QDebug>
Expand Down Expand Up @@ -175,17 +176,35 @@ void CliRarPlugin::killProcess(bool emitFinished)
m_isProcessKilled = true;
}

// The "yyyy-MM-dd hh:mm:ss" local time of a listing line. Same result as
// QDateTime::fromString(text, "yyyy-MM-dd hh:mm:ss"), whose format parser costs tens of microseconds
// per call (seconds for an archive with thousands of entries); anything else still goes through it.
static QDateTime listTimeFromString(const QString &text)
{
if (text.size() == 19 && text.at(4) == QLatin1Char('-') && text.at(7) == QLatin1Char('-')
&& text.at(10) == QLatin1Char(' ') && text.at(13) == QLatin1Char(':') && text.at(16) == QLatin1Char(':')) {
bool ok[6] = {};
const QDate date(text.mid(0, 4).toInt(&ok[0]), text.mid(5, 2).toInt(&ok[1]), text.mid(8, 2).toInt(&ok[2]));
const QTime time(text.mid(11, 2).toInt(&ok[3]), text.mid(14, 2).toInt(&ok[4]), text.mid(17, 2).toInt(&ok[5]));
if (ok[0] && ok[1] && ok[2] && ok[3] && ok[4] && ok[5] && date.isValid() && time.isValid()) {
return QDateTime(date, time);
}
}
return QDateTime::fromString(text, QStringLiteral("yyyy-MM-dd hh:mm:ss"));
}

bool CliRarPlugin::readListLine(const QString &line)
{
ArchiveData &stArchiveData = DataManager::get_instance().archiveData();

QRegularExpression rxVersionLine(QStringLiteral("^UNRAR (\\d+\\.\\d+)( beta \\d)? .*$"));
QRegularExpressionMatch matchVersion = rxVersionLine.match(line);
// Compiled once and only matched before the version line: building and JIT-compiling it for every
// line of the listing took about as long as the rest of the parsing
static const QRegularExpression rxVersionLine(QStringLiteral("^UNRAR (\\d+\\.\\d+)( beta \\d)? .*$"));

switch (m_parseState) {
case ParseStateHeader:
case ParseStateTitle:
if (matchVersion.hasMatch()) { // unrar信息读取完,开始读压缩包相关信息
if (rxVersionLine.match(line).hasMatch()) { // unrar信息读取完,开始读压缩包相关信息
m_parseState = ParseStateArchiveInformation;
}
break;
Expand Down Expand Up @@ -246,8 +265,7 @@ bool CliRarPlugin::readListLine(const QString &line)
} else if (parseLineLeft == QLatin1String("mtime")) {
QString time = line.left((line.length() - 10));
// 文件最后修改时间
m_fileEntry.uLastModifiedTime = QDateTime::fromString(time.right(time.length() - 14),
QStringLiteral("yyyy-MM-dd hh:mm:ss"))
m_fileEntry.uLastModifiedTime = listTimeFromString(time.right(time.length() - 14))
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
.toTime_t();
#else
Expand Down
Loading