added SI unit option

pull/2318/head
ignorant05 2025-09-26 10:20:29 +01:00
parent d372b788ec
commit 9efe23dcb8
11 changed files with 77 additions and 30 deletions

View File

@ -80,10 +80,15 @@ std::string SizeFormatter::operator()(int64_t size) const
namespace { namespace {
class AbbrevSizeFormatter : public SizeFormatter { class AbbrevSizeFormatter : public SizeFormatter {
private:
bool useSI_;
public:
explicit AbbrevSizeFormatter(bool useSI) : useSI_{useSI} {}
protected: protected:
virtual std::string format(int64_t size) const CXX11_OVERRIDE virtual std::string format(int64_t size) const CXX11_OVERRIDE
{ {
return util::abbrevSize(size); return util::abbrevSize(size, useSI_);
} }
}; };
} // namespace } // namespace
@ -267,7 +272,7 @@ void printProgressSummary(const RequestGroupList& groups, size_t cols,
} }
} // namespace } // namespace
ConsoleStatCalc::ConsoleStatCalc(std::chrono::seconds summaryInterval, ConsoleStatCalc::ConsoleStatCalc(std::chrono::seconds summaryInterval, bool useSI,
bool colorOutput, bool humanReadable) bool colorOutput, bool humanReadable)
: summaryInterval_(std::move(summaryInterval)), : summaryInterval_(std::move(summaryInterval)),
readoutVisibility_(true), readoutVisibility_(true),
@ -278,9 +283,10 @@ ConsoleStatCalc::ConsoleStatCalc(std::chrono::seconds summaryInterval,
isTTY_(isatty(STDOUT_FILENO) == 1), isTTY_(isatty(STDOUT_FILENO) == 1),
#endif // !__MINGW32__ #endif // !__MINGW32__
colorOutput_(colorOutput) colorOutput_(colorOutput)
{ {
if (humanReadable) { if (humanReadable) {
sizeFormatter_ = make_unique<AbbrevSizeFormatter>(); sizeFormatter_ = make_unique<AbbrevSizeFormatter>(useSI);
} }
else { else {
sizeFormatter_ = make_unique<PlainSizeFormatter>(); sizeFormatter_ = make_unique<PlainSizeFormatter>();

View File

@ -35,6 +35,7 @@
#ifndef D_CONSOLE_STAT_CALC_H #ifndef D_CONSOLE_STAT_CALC_H
#define D_CONSOLE_STAT_CALC_H #define D_CONSOLE_STAT_CALC_H
#include "Option.h"
#include "StatCalc.h" #include "StatCalc.h"
#include <string> #include <string>
@ -70,8 +71,8 @@ private:
bool colorOutput_; bool colorOutput_;
public: public:
ConsoleStatCalc(std::chrono::seconds summaryInterval, bool colorOutput = true, ConsoleStatCalc(std::chrono::seconds summaryInterval, bool useSI = false,
bool humanReadable = true); bool colorOutput = true, bool humanReadable = true);
virtual ~ConsoleStatCalc() = default; virtual ~ConsoleStatCalc() = default;

View File

@ -137,6 +137,7 @@ std::unique_ptr<StatCalc> getStatCalc(const std::shared_ptr<Option>& op)
} }
auto impl = make_unique<ConsoleStatCalc>( auto impl = make_unique<ConsoleStatCalc>(
std::chrono::seconds(op->getAsInt(PREF_SUMMARY_INTERVAL)), std::chrono::seconds(op->getAsInt(PREF_SUMMARY_INTERVAL)),
op->getAsBool(PREF_USE_SI_UNITS),
op->getAsBool(PREF_ENABLE_COLOR), op->getAsBool(PREF_HUMAN_READABLE)); op->getAsBool(PREF_ENABLE_COLOR), op->getAsBool(PREF_HUMAN_READABLE));
impl->setReadoutVisibility(op->getAsBool(PREF_SHOW_CONSOLE_READOUT)); impl->setReadoutVisibility(op->getAsBool(PREF_SHOW_CONSOLE_READOUT));
impl->setTruncate(op->getAsBool(PREF_TRUNCATE_CONSOLE_READOUT)); impl->setTruncate(op->getAsBool(PREF_TRUNCATE_CONSOLE_READOUT));

View File

@ -1993,6 +1993,16 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
// SI units option
{
OptionHandler* op(
new BooleanOptionHandler(PREF_USE_SI_UNITS, TEXT_USE_SI_UNITS,
A2_V_FALSE, OptionHandler::NO_ARG));
op->addTag(TAG_BASIC);
op->setInitialOption(true);
op->setChangeGlobalOption(true);
handlers.push_back(op);
}
return handlers; return handlers;
} }

View File

@ -85,6 +85,7 @@
#include "OpenedFileCounter.h" #include "OpenedFileCounter.h"
#include "wallclock.h" #include "wallclock.h"
#include "RpcMethodImpl.h" #include "RpcMethodImpl.h"
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
# include "bittorrent_helper.h" # include "bittorrent_helper.h"
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
@ -714,6 +715,7 @@ void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const
std::string line(pathRowSize, '='); std::string line(pathRowSize, '=');
o.printf("%s\n", line.c_str()); o.printf("%s\n", line.c_str());
bool useColor = o.supportsColor() && option_->getAsBool(PREF_ENABLE_COLOR); bool useColor = o.supportsColor() && option_->getAsBool(PREF_ENABLE_COLOR);
bool useSI = option_->getAsBool(PREF_USE_SI_UNITS);
int ok = 0; int ok = 0;
int err = 0; int err = 0;
int inpr = 0; int inpr = 0;
@ -742,10 +744,10 @@ void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const
++err; ++err;
} }
if (full) { if (full) {
formatDownloadResultFull(o, status, dr); formatDownloadResultFull(o, status, dr, useSI);
} }
else { else {
o.write(formatDownloadResult(status, dr).c_str()); o.write(formatDownloadResult(status, dr, useSI).c_str());
o.write("\n"); o.write("\n");
} }
} }
@ -770,14 +772,15 @@ void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const
namespace { namespace {
void formatDownloadResultCommon( void formatDownloadResultCommon(
std::ostream& o, const char* status, std::ostream& o, const char* status,
const std::shared_ptr<DownloadResult>& downloadResult) const std::shared_ptr<DownloadResult>& downloadResult,
bool useSI)
{ {
o << std::setw(3) << downloadResult->gid->toAbbrevHex() << "|" << std::setw(4) o << std::setw(3) << downloadResult->gid->toAbbrevHex() << "|" << std::setw(4)
<< status << "|"; << status << "|";
if (downloadResult->sessionTime.count() > 0) { if (downloadResult->sessionTime.count() > 0) {
o << std::setw(8) o << std::setw(8)
<< util::abbrevSize(downloadResult->sessionDownloadLength * 1000 / << util::abbrevSize(downloadResult->sessionDownloadLength * 1000 /
downloadResult->sessionTime.count()) downloadResult->sessionTime.count(), useSI)
<< "B/s"; << "B/s";
} }
else { else {
@ -790,7 +793,8 @@ void formatDownloadResultCommon(
void RequestGroupMan::formatDownloadResultFull( void RequestGroupMan::formatDownloadResultFull(
OutputFile& out, const char* status, OutputFile& out, const char* status,
const std::shared_ptr<DownloadResult>& downloadResult) const const std::shared_ptr<DownloadResult>& downloadResult,
bool useSI) const
{ {
BitfieldMan bt(downloadResult->pieceLength, downloadResult->totalLength); BitfieldMan bt(downloadResult->pieceLength, downloadResult->totalLength);
bt.setBitfield( bt.setBitfield(
@ -805,7 +809,7 @@ void RequestGroupMan::formatDownloadResultFull(
} }
std::stringstream o; std::stringstream o;
if (head) { if (head) {
formatDownloadResultCommon(o, status, downloadResult); formatDownloadResultCommon(o, status, downloadResult, useSI);
head = false; head = false;
} }
else { else {
@ -825,7 +829,7 @@ void RequestGroupMan::formatDownloadResultFull(
} }
if (head) { if (head) {
std::stringstream o; std::stringstream o;
formatDownloadResultCommon(o, status, downloadResult); formatDownloadResultCommon(o, status, downloadResult, useSI);
o << " -|n/a\n"; o << " -|n/a\n";
out.write(o.str().c_str()); out.write(o.str().c_str());
} }
@ -833,10 +837,11 @@ void RequestGroupMan::formatDownloadResultFull(
std::string RequestGroupMan::formatDownloadResult( std::string RequestGroupMan::formatDownloadResult(
const char* status, const char* status,
const std::shared_ptr<DownloadResult>& downloadResult) const const std::shared_ptr<DownloadResult>& downloadResult,
bool useSI) const
{ {
std::stringstream o; std::stringstream o;
formatDownloadResultCommon(o, status, downloadResult); formatDownloadResultCommon(o, status, downloadResult, useSI);
const std::vector<std::shared_ptr<FileEntry>>& fileEntries = const std::vector<std::shared_ptr<FileEntry>>& fileEntries =
downloadResult->fileEntries; downloadResult->fileEntries;
writeFilePath(fileEntries.begin(), fileEntries.end(), o, writeFilePath(fileEntries.begin(), fileEntries.end(), o,
@ -1103,12 +1108,14 @@ int RequestGroupMan::optimizeConcurrentDownloads()
maxConcurrentDownloads = maxConcurrentDownloads =
std::min(std::max(1, maxConcurrentDownloads), maxConcurrentDownloads_); std::min(std::max(1, maxConcurrentDownloads), maxConcurrentDownloads_);
bool useSI = option_->getAsBool(PREF_USE_SI_UNITS);
A2_LOG_DEBUG( A2_LOG_DEBUG(
fmt("Max concurrent downloads optimized at %d (%lu currently active) " fmt("Max concurrent downloads optimized at %d (%lu currently active) "
"[optimization speed %sB/s, current speed %sB/s]", "[optimization speed %sB/s, current speed %sB/s]",
maxConcurrentDownloads, static_cast<unsigned long>(numActive_), maxConcurrentDownloads, static_cast<unsigned long>(numActive_),
util::abbrevSize(optimizationSpeed_).c_str(), util::abbrevSize(optimizationSpeed_, useSI).c_str(),
util::abbrevSize(currentSpeed).c_str())); util::abbrevSize(currentSpeed, useSI).c_str()));
return maxConcurrentDownloads; return maxConcurrentDownloads;
} }

View File

@ -132,11 +132,13 @@ private:
void formatDownloadResultFull( void formatDownloadResultFull(
OutputFile& out, const char* status, OutputFile& out, const char* status,
const std::shared_ptr<DownloadResult>& downloadResult) const; const std::shared_ptr<DownloadResult>& downloadResult,
bool useSI = false) const;
std::string formatDownloadResult( std::string
const char* status, formatDownloadResult(const char* status,
const std::shared_ptr<DownloadResult>& downloadResult) const; const std::shared_ptr<DownloadResult>& downloadResult,
bool useSI = false) const;
void configureRequestGroup( void configureRequestGroup(
const std::shared_ptr<RequestGroup>& requestGroup) const; const std::shared_ptr<RequestGroup>& requestGroup) const;

View File

@ -592,4 +592,10 @@ PrefPtr PREF_METALINK_ENABLE_UNIQUE_PROTOCOL =
makePref("metalink-enable-unique-protocol"); makePref("metalink-enable-unique-protocol");
PrefPtr PREF_METALINK_BASE_URI = makePref("metalink-base-uri"); PrefPtr PREF_METALINK_BASE_URI = makePref("metalink-base-uri");
/**
* Units related (IEC/SI)
*/
// values: true | false
PrefPtr PREF_USE_SI_UNITS = makePref("si-units");
} // namespace aria2 } // namespace aria2

View File

@ -542,6 +542,12 @@ extern PrefPtr PREF_METALINK_ENABLE_UNIQUE_PROTOCOL;
// values: a string // values: a string
extern PrefPtr PREF_METALINK_BASE_URI; extern PrefPtr PREF_METALINK_BASE_URI;
/**
* Units related (IEC/SI)
*/
// values: true | false
extern PrefPtr PREF_USE_SI_UNITS;
} // namespace aria2 } // namespace aria2
#endif // D_PREFS_H #endif // D_PREFS_H

View File

@ -1129,5 +1129,8 @@
" file saved by --bt-save-metadata option. If it is\n" \ " file saved by --bt-save-metadata option. If it is\n" \
" successful, then skip downloading metadata from\n" \ " successful, then skip downloading metadata from\n" \
" DHT.") " DHT.")
#define TEXT_USE_SI_UNITS \
_(" --si-units[=true|false]\n"\
"Use SI units (kB, MB, GB) instead of IEC units (KiB, MiB, GiB).")
// clang-format on // clang-format on

View File

@ -1857,20 +1857,25 @@ int64_t getRealSize(const std::string& sizeWithUnit)
return v * mult; return v * mult;
} }
std::string abbrevSize(int64_t size) std::string abbrevSize(int64_t size, bool useSI)
{ {
static const char* UNITS[] = {"", "Ki", "Mi", "Gi"}; static const char* IEC_UNITS[] = {"", "Ki", "Mi", "Gi"};
static const char* SI_UNITS[] = {"", "K", "M", "G"};
const char** units = useSI ? SI_UNITS : IEC_UNITS;
int64_t divisor = useSI ? 1000 : 1024;
int64_t t = size; int64_t t = size;
size_t uidx = 0; size_t uidx = 0;
int r = 0; int r = 0;
while (t >= static_cast<int64_t>(1_k) && while (t >= divisor &&
uidx + 1 < sizeof(UNITS) / sizeof(UNITS[0])) { uidx + 1 < sizeof(units)) {
lldiv_t d = lldiv(t, 1_k); lldiv_t d = lldiv(t, divisor);
t = d.quot; t = d.quot;
r = d.rem; r = d.rem;
++uidx; ++uidx;
} }
if (uidx + 1 < sizeof(UNITS) / sizeof(UNITS[0]) && t >= 922) { if (uidx + 1 < sizeof(units) && t >= 922) {
++uidx; ++uidx;
r = t; r = t;
t = 0; t = 0;
@ -1879,9 +1884,9 @@ std::string abbrevSize(int64_t size)
res += itos(t, true); res += itos(t, true);
if (t < 10 && uidx > 0) { if (t < 10 && uidx > 0) {
res += "."; res += ".";
res += itos(r * 10 / 1_k); res += itos(r * 10 / divisor);
} }
res += UNITS[uidx]; res += units[uidx];
return res; return res;
} }

View File

@ -361,7 +361,7 @@ std::string getDHTFile(bool ipv6);
int64_t getRealSize(const std::string& sizeWithUnit); int64_t getRealSize(const std::string& sizeWithUnit);
std::string abbrevSize(int64_t size); std::string abbrevSize(int64_t size, bool useSI = false);
template <typename InputIterator, typename Output> template <typename InputIterator, typename Output>
void toStream(InputIterator first, InputIterator last, Output& os) void toStream(InputIterator first, InputIterator last, Output& os)