diff --git a/src/ui/model/traflistmodel.cpp b/src/ui/model/traflistmodel.cpp index 40171647..bc51580f 100644 --- a/src/ui/model/traflistmodel.cpp +++ b/src/ui/model/traflistmodel.cpp @@ -191,15 +191,6 @@ bool TrafListModel::updateTableRow(const QVariantHash & /*vars*/, int row) const QString TrafListModel::formatTrafUnit(qint64 bytes) const { - static const QVector unitMults = { - 1, // Adaptive - 1, // Bytes - 1024, // KB - 1024 * 1024, // MB - qint64(1024) * 1024 * 1024, // GB - qint64(1024) * 1024 * 1024 * 1024 // TB - }; - if (bytes == 0) { return QLatin1String("0"); } @@ -210,9 +201,9 @@ QString TrafListModel::formatTrafUnit(qint64 bytes) const return FormatUtil::formatDataSize(bytes, trafPrec); } - const qint64 unitMult = unitMults.at(unit()); + const int power = unit() - 1; - return QLocale().toString(qreal(bytes) / unitMult, 'f', trafPrec); + return FormatUtil::formatSize(bytes, power, trafPrec); } QString TrafListModel::formatTrafTime(qint32 trafTime) const diff --git a/src/ui/model/traflistmodel.h b/src/ui/model/traflistmodel.h index 1ed64de1..870d635c 100644 --- a/src/ui/model/traflistmodel.h +++ b/src/ui/model/traflistmodel.h @@ -17,7 +17,7 @@ class TrafListModel : public TableItemModel Q_OBJECT public: - enum TrafUnit { UnitAdaptive = 0, UnitBytes, UnitKB, UnitMB, UnitGB, UnitTB }; + enum TrafUnit { UnitAdaptive = 0, UnitBytes, UnitKB, UnitMB, UnitGB, UnitTB, UnitPB, UnitEB }; Q_ENUM(TrafUnit) enum TrafType { TrafHourly = 0, TrafDaily, TrafMonthly, TrafTotal }; diff --git a/src/ui/util/formatutil.cpp b/src/ui/util/formatutil.cpp index ca4deb3e..049e5818 100644 --- a/src/ui/util/formatutil.cpp +++ b/src/ui/util/formatutil.cpp @@ -1,5 +1,48 @@ #include "formatutil.h" +namespace { + +static const qint64 g_baseSiPowerValues[] = { + 1, + 1024LL, // kilo + 1024LL * 1024LL, // mega + 1024LL * 1024LL * 1024LL, // giga + 1024LL * 1024LL * 1024LL * 1024LL, // tera + 1024LL * 1024LL * 1024LL * 1024LL * 1024LL, // peta + 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL, // exa +}; + +static const qint64 g_baseIecPowerValues[] = { + 1, + 1000LL, // kibi + 1000LL * 1000LL, // mebi + 1000LL * 1000LL * 1000LL, // gibi + 1000LL * 1000LL * 1000LL * 1000LL, // tebi + 1000LL * 1000LL * 1000LL * 1000LL * 1000LL, // pebi + 1000LL * 1000LL * 1000LL * 1000LL * 1000LL * 1000LL, // exbi +}; + +constexpr int FORMAT_POWER_VALUES_SIZE = 7; + +static_assert( + std::size(g_baseSiPowerValues) == FORMAT_POWER_VALUES_SIZE, "powerValues size mismatch"); + +} + +QString FormatUtil::formatSize( + qint64 value, int power, int precision, QLocale::DataSizeFormats format) +{ + // We don't support sizes in units larger than exbibytes because + // the number of bytes would not fit into qint64. + Q_ASSERT(power < FORMAT_POWER_VALUES_SIZE && power >= 0); + + const qint64 *powerValues = + (format & QLocale::DataSizeBase1000) ? g_baseIecPowerValues : g_baseSiPowerValues; + const qint64 powerValue = powerValues[power]; + + return QLocale().toString(qreal(value) / powerValue, 'f', precision); +} + QString FormatUtil::formatDataSize(qint64 bytes, int precision, QLocale::DataSizeFormats format) { return QLocale().formattedDataSize(bytes, precision, format); diff --git a/src/ui/util/formatutil.h b/src/ui/util/formatutil.h index 727af1e1..c96da0ae 100644 --- a/src/ui/util/formatutil.h +++ b/src/ui/util/formatutil.h @@ -9,6 +9,9 @@ class FormatUtil : public QObject Q_OBJECT public: + static QString formatSize(qint64 value, int power, int precision = 2, + QLocale::DataSizeFormats format = QLocale::DataSizeTraditionalFormat); + static QString formatDataSize(qint64 bytes, int precision = 2, QLocale::DataSizeFormats format = QLocale::DataSizeTraditionalFormat);