mirror of https://github.com/aria2/aria2
added SI unit option
parent
d372b788ec
commit
9efe23dcb8
|
@ -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),
|
||||||
|
@ -279,8 +284,9 @@ ConsoleStatCalc::ConsoleStatCalc(std::chrono::seconds summaryInterval,
|
||||||
#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>();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
21
src/util.cc
21
src/util.cc
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue