refactor: add libtransmission::Values (#6215)

This commit is contained in:
Charles Kerr 2023-11-09 08:39:06 -06:00 committed by GitHub
parent b413beab70
commit 2e32789193
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 439 additions and 407 deletions

View File

@ -26,32 +26,7 @@
using namespace std::chrono_literals;
/***
****
***/
static auto constexpr MemK = size_t{ 1024 };
static char constexpr MemKStr[] = "KiB";
static char constexpr MemMStr[] = "MiB";
static char constexpr MemGStr[] = "GiB";
static char constexpr MemTStr[] = "TiB";
static auto constexpr DiskK = size_t{ 1000 };
static char constexpr DiskKStr[] = "kB";
static char constexpr DiskMStr[] = "MB";
static char constexpr DiskGStr[] = "GB";
static char constexpr DiskTStr[] = "TB";
static auto constexpr SpeedK = size_t{ 1000 };
#define SPEED_K_STR "kB/s"
static char constexpr SpeedKStr[] = SPEED_K_STR;
static char constexpr SpeedMStr[] = "MB/s";
static char constexpr SpeedGStr[] = "GB/s";
static char constexpr SpeedTStr[] = "TB/s";
/***
****
***/
static auto constexpr LineWidth = int{ 80 };
@ -204,10 +179,6 @@ int tr_main(int argc, char* argv[])
tr_locale_set_global("");
tr_formatter_mem_init(MemK, MemKStr, MemMStr, MemGStr, MemTStr);
tr_formatter_size_init(DiskK, DiskKStr, DiskMStr, DiskGStr, DiskTStr);
tr_formatter_speed_init(SpeedK, SpeedKStr, SpeedMStr, SpeedGStr, SpeedTStr);
printf("%s %s\n", MyReadableName, LONG_VERSION_STRING);
/* user needs to pass in at least one argument */

View File

@ -73,24 +73,6 @@ static char constexpr Usage[] = "Transmission " LONG_VERSION_STRING
"\n"
"Usage: transmission-daemon [options]";
static auto constexpr MemK = size_t{ 1024 };
static char constexpr MemKStr[] = "KiB";
static char constexpr MemMStr[] = "MiB";
static char constexpr MemGStr[] = "GiB";
static char constexpr MemTStr[] = "TiB";
static auto constexpr DiskK = size_t{ 1000 };
static char constexpr DiskKStr[] = "kB";
static char constexpr DiskMStr[] = "MB";
static char constexpr DiskGStr[] = "GB";
static char constexpr DiskTStr[] = "TB";
static auto constexpr SpeedK = size_t{ 1000 };
static char constexpr SpeedKStr[] = "kB/s";
static char constexpr SpeedMStr[] = "MB/s";
static char constexpr SpeedGStr[] = "GB/s";
static char constexpr SpeedTStr[] = "TB/s";
/***
**** Config File
***/
@ -723,9 +705,6 @@ int tr_daemon::start([[maybe_unused]] bool foreground)
}
/* start the session */
tr_formatter_mem_init(MemK, MemKStr, MemMStr, MemGStr, MemTStr);
tr_formatter_size_init(DiskK, DiskKStr, DiskMStr, DiskGStr, DiskTStr);
tr_formatter_speed_init(SpeedK, SpeedKStr, SpeedMStr, SpeedGStr, SpeedTStr);
session = tr_sessionInit(cdir, true, settings_);
tr_sessionSetRPCCallback(session, on_rpc_callback, this);
tr_logAddInfo(fmt::format(_("Loading settings from '{path}'"), fmt::arg("path", cdir)));

View File

@ -323,6 +323,7 @@ if(INSTALL_LIB)
tr-strbuf.h
transmission.h
utils.h
values.h
variant.h
watchdir.h
web-utils.h

View File

@ -54,6 +54,7 @@
#include "libtransmission/tr-assert.h"
#include "libtransmission/tr-strbuf.h"
#include "libtransmission/utils.h"
#include "libtransmission/values.h"
#include "libtransmission/variant.h"
using namespace std::literals;
@ -664,242 +665,138 @@ uint64_t tr_ntohll(uint64_t netlonglong)
#endif
}
// ---
// --- VALUES / FORMATTER
namespace
{
namespace formatter_impl
namespace libtransmission::Values
{
struct formatter_unit
{
std::array<char, 16> name;
uint64_t value;
};
// default values; can be overridden by client apps
Config::Units<MemoryUnits> Config::Memory{ Config::Base::Kibi, "B"sv, "KiB"sv, "MiB"sv, "GiB"sv, "TiB"sv };
Config::Units<SpeedUnits> Config::Speed{ Config::Base::Kilo, "B/s"sv, "kB/s"sv, "MB/s"sv, "GB/s"sv, "TB/s"sv };
Config::Units<StorageUnits> Config::Storage{ Config::Base::Kilo, "B"sv, "kB"sv, "MB"sv, "GB"sv, "TB"sv };
using formatter_units = std::array<formatter_unit, 4>;
enum
{
TR_FMT_KB,
TR_FMT_MB,
TR_FMT_GB,
TR_FMT_TB
};
void formatter_init(formatter_units& units, uint64_t kilo, char const* kb, char const* mb, char const* gb, char const* tb)
{
uint64_t value = kilo;
tr_strlcpy(std::data(units[TR_FMT_KB].name), kb, std::size(units[TR_FMT_KB].name));
units[TR_FMT_KB].value = value;
value *= kilo;
tr_strlcpy(std::data(units[TR_FMT_MB].name), mb, std::size(units[TR_FMT_MB].name));
units[TR_FMT_MB].value = value;
value *= kilo;
tr_strlcpy(std::data(units[TR_FMT_GB].name), gb, std::size(units[TR_FMT_GB].name));
units[TR_FMT_GB].value = value;
value *= kilo;
tr_strlcpy(std::data(units[TR_FMT_TB].name), tb, std::size(units[TR_FMT_TB].name));
units[TR_FMT_TB].value = value;
}
char* formatter_get_size_str(formatter_units const& u, char* buf, uint64_t bytes, size_t buflen)
{
formatter_unit const* unit = nullptr;
if (bytes < u[1].value)
{
unit = std::data(u);
}
else if (bytes < u[2].value)
{
unit = &u[1];
}
else if (bytes < u[3].value)
{
unit = &u[2];
}
else
{
unit = &u[3];
}
double const value = static_cast<double>(bytes) / unit->value;
auto const* const units = std::data(unit->name);
auto precision = int{};
if (unit->value == 1)
{
precision = 0;
}
else if (value < 100)
{
precision = 2;
}
else
{
precision = 1;
}
auto const [out, len] = fmt::format_to_n(buf, buflen - 1, "{:.{}Lf} {:s}", value, precision, units);
*out = '\0';
return buf;
}
formatter_units size_units;
formatter_units speed_units;
formatter_units mem_units;
} // namespace formatter_impl
} // namespace
size_t tr_speed_K = 0;
void tr_formatter_size_init(uint64_t kilo, char const* kb, char const* mb, char const* gb, char const* tb)
{
using namespace formatter_impl;
formatter_init(size_units, kilo, kb, mb, gb, tb);
}
std::string tr_formatter_size_B(uint64_t bytes)
{
using namespace formatter_impl;
auto buf = std::array<char, 64>{};
return formatter_get_size_str(size_units, std::data(buf), bytes, std::size(buf));
}
void tr_formatter_speed_init(size_t kilo, char const* kb, char const* mb, char const* gb, char const* tb)
{
using namespace formatter_impl;
tr_speed_K = kilo;
formatter_init(speed_units, kilo, kb, mb, gb, tb);
}
std::string tr_formatter_speed_KBps(double kilo_per_second)
{
using namespace formatter_impl;
auto speed = kilo_per_second;
if (speed < 999.95) // 0.0 KB to 999.9 KB (0.0 KiB to 999.9 KiB)
{
return fmt::format("{:.1Lf} {:s}", speed, std::data(speed_units[TR_FMT_KB].name));
}
double const kilo = speed_units[TR_FMT_KB].value;
speed /= kilo;
if (speed < 99.995) // 0.98 MB to 99.99 MB (1.00 MiB to 99.99 MiB)
{
return fmt::format("{:.2Lf} {:s}", speed, std::data(speed_units[TR_FMT_MB].name));
}
if (speed < 999.95) // 100.0 MB to 999.9 MB (100.0 MiB to 999.9 MiB)
{
return fmt::format("{:.1Lf} {:s}", speed, std::data(speed_units[TR_FMT_MB].name));
}
speed /= kilo;
if (speed < 99.995) // 0.98 GB to 99.99 GB (1.00 GiB to 99.99 GiB)
{
return fmt::format("{:.2Lf} {:s}", speed, std::data(speed_units[TR_FMT_GB].name));
}
// 100.0 GB and above (100.0 GiB and above)
return fmt::format("{:.1Lf} {:s}", speed, std::data(speed_units[TR_FMT_GB].name));
}
std::string tr_formatter_speed_compact_KBps(double kilo_per_second)
{
using namespace formatter_impl;
auto speed = kilo_per_second;
if (speed < 99.95) // 0.0 KB to 99.9 KB (0.0 KiB to 99.9 KiB)
{
return fmt::format("{:.1Lf} {:s}", speed, std::data(speed_units[TR_FMT_KB].name));
}
if (speed < 999.5) // 100 KB to 999 KB (100 KiB to 999 KiB)
{
return fmt::format("{:.0Lf} {:s}", speed, std::data(speed_units[TR_FMT_KB].name));
}
double const kilo = speed_units[TR_FMT_KB].value;
speed /= kilo;
if (speed < 9.995) // 0.98 MB to 9.99 MB (1.00 MiB to 9.99 MiB)
{
return fmt::format("{:.2Lf} {:s}", speed, std::data(speed_units[TR_FMT_MB].name));
}
if (speed < 99.95) // 10.0 MB to 99.9 MB (10.0 MiB to 99.9 MiB)
{
return fmt::format("{:.1Lf} {:s}", speed, std::data(speed_units[TR_FMT_MB].name));
}
if (speed < 999.5) // 100 MB to 999 MB (100 MiB to 999 MiB)
{
return fmt::format("{:.0Lf} {:s}", speed, std::data(speed_units[TR_FMT_MB].name));
}
speed /= kilo;
if (speed < 9.995) // 0.98 GB to 9.99 GB (1.00 GiB to 9.99 GiB)
{
return fmt::format("{:.2Lf} {:s}", speed, std::data(speed_units[TR_FMT_GB].name));
}
if (speed < 99.95) // 10.0 GB to 99.9 GB (10.0 GiB to 99.9 GiB)
{
return fmt::format("{:.1Lf} {:s}", speed, std::data(speed_units[TR_FMT_GB].name));
}
// 100 GB and above (100 GiB and above)
return fmt::format("{:.0Lf} {:s}", speed, std::data(speed_units[TR_FMT_GB].name));
}
size_t tr_mem_K = 0;
void tr_formatter_mem_init(size_t kilo, char const* kb, char const* mb, char const* gb, char const* tb)
{
using namespace formatter_impl;
tr_mem_K = kilo;
formatter_init(mem_units, kilo, kb, mb, gb, tb);
}
std::string tr_formatter_mem_B(size_t bytes_per_second)
{
using namespace formatter_impl;
auto buf = std::array<char, 64>{};
return formatter_get_size_str(mem_units, std::data(buf), bytes_per_second, std::size(buf));
}
} // namespace libtransmission::Values
tr_variant tr_formatter_get_units()
{
using namespace formatter_impl;
using namespace libtransmission::Values;
auto const make_units_vec = [](formatter_units const& units)
auto const make_units_vec = [](auto const& units)
{
auto units_vec = tr_variant::Vector{};
units_vec.reserve(std::size(units));
std::transform(
std::begin(units),
std::end(units),
std::back_inserter(units_vec),
[](auto const& unit) { return std::data(unit.name); });
for (size_t i = 0;; ++i)
{
auto const display_name = units.display_name(i);
if (std::empty(display_name))
{
break;
}
units_vec.emplace_back(display_name);
}
return units_vec;
};
auto units_map = tr_variant::Map{ 6U };
units_map.try_emplace(TR_KEY_memory_bytes, mem_units[TR_FMT_KB].value);
units_map.try_emplace(TR_KEY_memory_units, make_units_vec(mem_units));
units_map.try_emplace(TR_KEY_size_bytes, size_units[TR_FMT_KB].value);
units_map.try_emplace(TR_KEY_size_units, make_units_vec(size_units));
units_map.try_emplace(TR_KEY_speed_bytes, speed_units[TR_FMT_KB].value);
units_map.try_emplace(TR_KEY_speed_units, make_units_vec(speed_units));
units_map.try_emplace(TR_KEY_memory_bytes, Memory::units().base());
units_map.try_emplace(TR_KEY_memory_units, make_units_vec(Memory::units()));
units_map.try_emplace(TR_KEY_size_bytes, Storage::units().base());
units_map.try_emplace(TR_KEY_size_units, make_units_vec(Storage::units()));
units_map.try_emplace(TR_KEY_speed_bytes, Speed::units().base());
units_map.try_emplace(TR_KEY_speed_units, make_units_vec(Speed::units()));
return tr_variant{ std::move(units_map) };
}
// --- formatters: storage
void tr_formatter_size_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb)
{
namespace Values = libtransmission::Values;
auto const kval = base == 1000U ? Values::Config::Base::Kilo : Values::Config::Base::Kibi;
Values::Config::Storage = { kval, "B", kb, mb, gb, tb };
}
std::string tr_formatter_size_B(uint64_t bytes)
{
using Storage = libtransmission::Values::Storage;
return Storage{ bytes, Storage::Units::Bytes }.to_string();
}
// --- formatters: speed
size_t tr_speed_K = 0;
void tr_formatter_speed_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb)
{
namespace Values = libtransmission::Values;
auto const kval = base == 1000U ? Values::Config::Base::Kilo : Values::Config::Base::Kibi;
Values::Config::Speed = { kval, "B/s", kb, mb, gb, tb };
tr_speed_K = base;
}
std::string tr_formatter_speed_KBps(double kbyps)
{
using Speed = libtransmission::Values::Speed;
return Speed{ kbyps, Speed::Units::KByps }.to_string();
}
uint64_t tr_toSpeedBytes(size_t kbyps)
{
using Speed = libtransmission::Values::Speed;
return Speed{ kbyps, Speed::Units::KByps }.base_quantity();
}
double tr_toSpeedKBps(size_t byps)
{
using Speed = libtransmission::Values::Speed;
return Speed{ byps, Speed::Units::Byps }.count(Speed::Units::KByps);
}
// --- formatters: memory
size_t tr_mem_K = 0;
void tr_formatter_mem_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb)
{
namespace Values = libtransmission::Values;
auto const kval = base == 1000U ? Values::Config::Base::Kilo : Values::Config::Base::Kibi;
Values::Config::Memory = { kval, "B", kb, mb, gb, tb };
tr_mem_K = base;
}
std::string tr_formatter_mem_B(uint64_t bytes)
{
using Memory = libtransmission::Values::Memory;
return Memory{ bytes, Memory::Units::Bytes }.to_string();
}
std::string tr_formatter_mem_MB(double mbytes)
{
using Memory = libtransmission::Values::Memory;
return Memory{ mbytes, Memory::Units::MBytes }.to_string();
}
uint64_t tr_toMemBytes(size_t mbytes)
{
using Memory = libtransmission::Values::Memory;
return Memory{ mbytes, Memory::Units::MBytes }.base_quantity();
}
double tr_toMemMB(uint64_t bytes)
{
using Memory = libtransmission::Values::Memory;
return Memory{ bytes, Memory::Units::Bytes }.count(Memory::Units::MBytes);
}
// --- ENVIRONMENT
bool tr_env_key_exists(char const* key)

View File

@ -19,6 +19,7 @@
#include "libtransmission/tr-macros.h"
#include "libtransmission/variant.h"
#include "libtransmission/values.h"
struct tr_error;
@ -300,55 +301,24 @@ constexpr void tr_timeUpdate(time_t now) noexcept
// ---
/* example: tr_formatter_size_init(1024, _("KiB"), _("MiB"), _("GiB"), _("TiB")); */
void tr_formatter_size_init(uint64_t kilo, char const* kb, char const* mb, char const* gb, char const* tb);
void tr_formatter_speed_init(size_t kilo, char const* kb, char const* mb, char const* gb, char const* tb);
void tr_formatter_mem_init(size_t kilo, char const* kb, char const* mb, char const* gb, char const* tb);
void tr_formatter_size_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb);
void tr_formatter_speed_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb);
void tr_formatter_mem_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb);
extern size_t tr_speed_K;
extern size_t tr_mem_K;
extern uint64_t tr_size_K; /* unused? */
/** @brief Format a speed from KBps into a user-readable string of at most 4 significant digits. */
[[nodiscard]] std::string tr_formatter_speed_KBps(double kilo_per_second);
/** @brief Format a speed from KBps into a user-readable string of at most 3 significant digits. */
[[nodiscard]] std::string tr_formatter_speed_compact_KBps(double kilo_per_second);
[[nodiscard]] double tr_toMemMB(uint64_t bytes);
[[nodiscard]] double tr_toSpeedKBps(size_t byps);
[[nodiscard]] uint64_t tr_toMemBytes(size_t mbytes);
[[nodiscard]] uint64_t tr_toSpeedBytes(size_t kbyps);
/** @brief Format a memory size from bytes into a user-readable string. */
[[nodiscard]] std::string tr_formatter_mem_B(size_t bytes);
/** @brief Format a memory size from MB into a user-readable string. */
[[nodiscard]] static inline std::string tr_formatter_mem_MB(double MBps)
{
return tr_formatter_mem_B((size_t)(MBps * tr_mem_K * tr_mem_K));
}
/** @brief Format a file size from bytes into a user-readable string. */
[[nodiscard]] std::string tr_formatter_mem_B(uint64_t bytes);
[[nodiscard]] std::string tr_formatter_mem_MB(double mbytes);
[[nodiscard]] std::string tr_formatter_size_B(uint64_t bytes);
[[nodiscard]] std::string tr_formatter_speed_KBps(double kbyps);
struct tr_variant tr_formatter_get_units();
[[nodiscard]] static inline size_t tr_toSpeedBytes(size_t KBps)
{
return KBps * tr_speed_K;
}
[[nodiscard]] static inline auto tr_toSpeedKBps(size_t Bps)
{
return Bps / double(tr_speed_K);
}
[[nodiscard]] static inline auto tr_toMemBytes(size_t MB)
{
return uint64_t(tr_mem_K) * tr_mem_K * MB;
}
[[nodiscard]] static inline auto tr_toMemMB(uint64_t B)
{
return size_t(B / (tr_mem_K * tr_mem_K));
}
[[nodiscard]] struct tr_variant tr_formatter_get_units();
// ---

259
libtransmission/values.h Normal file
View File

@ -0,0 +1,259 @@
// This file Copyright © Mnemosyne LLC.
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
#pragma once
#include <array>
#include <cstdint> // for uint64_t
#include <string>
#include <string_view>
#include <fmt/core.h>
namespace libtransmission::Values
{
enum class MemoryUnits
{
Bytes,
KBytes,
MBytes,
GBytes,
TBytes
};
using StorageUnits = MemoryUnits;
enum class SpeedUnits
{
Byps,
KByps,
MByps,
GByps,
TByps
};
struct Config
{
enum class Base
{
Kilo = 1000U,
Kibi = 1024U
};
template<typename UnitsEnum>
struct Units
{
template<typename... Names>
Units(Base base, Names... names)
{
set_base(base);
auto idx = size_t{ 0U };
(set_name(idx++, names), ...);
}
[[nodiscard]] constexpr auto base() const noexcept
{
return static_cast<size_t>(base_);
}
[[nodiscard]] constexpr auto display_name(size_t units) const noexcept
{
return std::string_view{ units < std::size(display_names_) ? std::data(display_names_[units]) : "" };
}
[[nodiscard]] constexpr auto multiplier(UnitsEnum multiplier) const noexcept
{
return multipliers_[static_cast<int>(multiplier)];
}
private:
constexpr void set_base(Base base)
{
base_ = base;
auto val = uint64_t{ 1U };
for (auto& multiplier : multipliers_)
{
multiplier = val;
val *= static_cast<size_t>(base);
}
}
void set_name(size_t idx, std::string_view name)
{
*fmt::format_to_n(std::data(display_names_[idx]), std::size(display_names_[idx]) - 1, "{:s}", name).out = '\0';
}
std::array<std::array<char, 32>, 5> display_names_ = {};
std::array<uint64_t, 5> multipliers_;
Base base_;
};
static Units<MemoryUnits> Memory;
static Units<SpeedUnits> Speed;
static Units<StorageUnits> Storage;
};
template<typename UnitsEnum, Config::Units<UnitsEnum> const& units_>
class Value
{
public:
using Units = UnitsEnum;
constexpr Value() = default;
constexpr Value(uint64_t value, Units multiple)
: base_quantity_{ value * units_.multiplier(multiple) }
{
}
template<typename Number>
Value(Number value, Units multiple)
: base_quantity_{ static_cast<uint64_t>(value * units_.multiplier(multiple)) }
{
}
constexpr auto& operator+=(Value const& that) noexcept
{
base_quantity_ += that.base_quantity_;
return *this;
}
[[nodiscard]] constexpr auto base_quantity() const noexcept
{
return base_quantity_;
}
[[nodiscard]] constexpr auto count(Units tgt) const noexcept
{
return base_quantity_ / (1.0 * units_.multiplier(tgt));
}
[[nodiscard]] constexpr auto operator+(Value const& that) noexcept
{
auto ret = *this;
return ret += that;
}
constexpr auto& operator*=(uint64_t mult) noexcept
{
base_quantity_ *= mult;
return *this;
}
[[nodiscard]] constexpr auto operator*(uint64_t mult) noexcept
{
auto ret = *this;
return ret *= mult;
}
constexpr auto& operator/=(uint64_t mult) noexcept
{
base_quantity_ /= mult;
return *this;
}
[[nodiscard]] constexpr auto operator/(uint64_t mult) noexcept
{
auto ret = *this;
return ret /= mult;
}
[[nodiscard]] constexpr auto operator<(Value const& that) const noexcept
{
return compare(that) < 0;
}
[[nodiscard]] constexpr auto operator<=(Value const& that) const noexcept
{
return compare(that) <= 0;
}
[[nodiscard]] constexpr auto operator==(Value const& that) const noexcept
{
return compare(that) == 0;
}
[[nodiscard]] constexpr auto operator!=(Value const& that) const noexcept
{
return compare(that) != 0;
}
[[nodiscard]] constexpr auto operator>(Value const& that) const noexcept
{
return compare(that) > 0;
}
[[nodiscard]] constexpr auto operator>=(Value const& that) const noexcept
{
return compare(that) >= 0;
}
std::string_view to_string(char* buf, size_t buflen) const noexcept
{
auto idx = size_t{ 0 };
if (base_quantity_ < 1000) // 0 to 999
{
*fmt::format_to_n(buf, buflen - 1, "{:d} {:s}", base_quantity_, units_.display_name(idx)).out = '\0';
return buf;
}
auto val = 1.0 * base_quantity_;
for (;;)
{
++idx;
val /= units_.base();
if (val < 99.995) // 0.98 to 99.99
{
*fmt::format_to_n(buf, buflen - 1, "{:.2Lf} {:s}", val, units_.display_name(idx)).out = '\0';
return buf;
}
if (val < 999.95 || std::empty(units_.display_name(idx + 1))) // 100.0 to 999.9
{
*fmt::format_to_n(buf, buflen - 1, "{:.1Lf} {:s}", val, units_.display_name(idx)).out = '\0';
return buf;
}
}
}
[[nodiscard]] std::string to_string() const
{
auto buf = std::array<char, 64>{};
return std::string{ to_string(std::data(buf), std::size(buf)) };
}
[[nodiscard]] static constexpr auto const& units() noexcept
{
return units_;
}
private:
uint64_t base_quantity_ = {};
[[nodiscard]] constexpr int compare(Value const& that) const noexcept // <=>
{
if (base_quantity_ < that.base_quantity_)
{
return -1;
}
if (base_quantity_ > that.base_quantity_)
{
return 1;
}
return 0;
}
};
using Memory = Value<MemoryUnits, Config::Memory>;
using Storage = Value<StorageUnits, Config::Storage>;
using Speed = Value<SpeedUnits, Config::Speed>;
} // namespace libtransmission::Values

View File

@ -54,6 +54,7 @@ target_sources(libtransmission-test
torrents-test.cc
tr-peer-info-test.cc
utils-test.cc
values-test.cc
variant-test.cc
watchdir-test.cc
web-utils-test.cc)

View File

@ -305,38 +305,6 @@ private:
Sandbox sandbox_;
};
inline void ensureFormattersInited()
{
static constexpr int MEM_K = 1024;
static char constexpr const* const MEM_K_STR = "KiB";
static char constexpr const* const MEM_M_STR = "MiB";
static char constexpr const* const MEM_G_STR = "GiB";
static char constexpr const* const MEM_T_STR = "TiB";
static constexpr int DISK_K = 1000;
static char constexpr const* const DISK_K_STR = "kB";
static char constexpr const* const DISK_M_STR = "MB";
static char constexpr const* const DISK_G_STR = "GB";
static char constexpr const* const DISK_T_STR = "TB";
static constexpr int SPEED_K = 1000;
static char constexpr const* const SPEED_K_STR = "kB/s";
static char constexpr const* const SPEED_M_STR = "MB/s";
static char constexpr const* const SPEED_G_STR = "GB/s";
static char constexpr const* const SPEED_T_STR = "TB/s";
static std::once_flag flag;
std::call_once(
flag,
[]()
{
tr_formatter_mem_init(MEM_K, MEM_K_STR, MEM_M_STR, MEM_G_STR, MEM_T_STR);
tr_formatter_size_init(DISK_K, DISK_K_STR, DISK_M_STR, DISK_G_STR, DISK_T_STR);
tr_formatter_speed_init(SPEED_K, SPEED_K_STR, SPEED_M_STR, SPEED_G_STR, SPEED_T_STR);
});
}
class SessionTest : public SandboxedTest
{
private:
@ -344,8 +312,6 @@ private:
tr_session* sessionInit(tr_variant& settings)
{
ensureFormattersInited();
auto* const settings_map = settings.get_if<tr_variant::Map>();
EXPECT_NE(settings_map, nullptr);

View File

@ -0,0 +1,46 @@
// This file Copyright © Mnemosyne LLC.
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
#include <libtransmission/transmission.h>
#include <libtransmission/utils.h>
#include <libtransmission/values.h>
#include "gtest/gtest.h"
using ValuesTest = ::testing::Test;
TEST_F(ValuesTest, value)
{
using Speed = libtransmission::Values::Speed;
auto val = Speed{ 1, Speed::Units::MByps };
EXPECT_EQ("1.00 MB/s", val.to_string());
EXPECT_EQ(1000000UL, val.base_quantity());
EXPECT_NEAR(1000U, val.count(Speed::Units::KByps), 0.0001);
EXPECT_NEAR(1U, val.count(Speed::Units::MByps), 0.0001);
EXPECT_NEAR(0.001, val.count(Speed::Units::GByps), 0.0001);
val = Speed{ 1, Speed::Units::Byps };
EXPECT_EQ(1U, val.base_quantity());
EXPECT_EQ("1 B/s", val.to_string());
val = Speed{ 10, Speed::Units::KByps };
EXPECT_EQ("10.00 kB/s", val.to_string());
val = Speed{ 999, Speed::Units::KByps };
EXPECT_EQ("999.0 kB/s", val.to_string());
}
TEST_F(ValuesTest, valueHonorsFormatterInit)
{
using Speed = libtransmission::Values::Speed;
tr_formatter_speed_init(1024, "KayBeePerEss", "EmmBeePerEss", "GeeBeePerEss", "TeeBeePerEss");
auto const val = Speed{ 1, Speed::Units::MByps };
EXPECT_EQ("1.00 EmmBeePerEss", val.to_string());
EXPECT_EQ(1048576U, val.base_quantity());
}

View File

@ -11,7 +11,7 @@ GENERAL
Source: 私たちの世界
Piece Count: 1
Piece Size: 1.00 MiB
Total Size: 0.01 kB
Total Size: 13 B
Privacy: Public torrent
TRACKERS
@ -21,6 +21,6 @@ TRACKERS
FILES
modified test-utf8/別の世界f1.txt (0.01 kB)
modified test-utf8/別の世界f2.txt (0.01 kB)
modified test-utf8/別の世界f1.txt (6 B)
modified test-utf8/別の世界f2.txt (7 B)

View File

@ -32,7 +32,7 @@ FILES
bittorrent-v1-v2-hybrid-test/eld-dust.mkv (61.64 MB)
bittorrent-v1-v2-hybrid-test/fairlight_cncd-agenda_circling_forth-1080p30lq.mp4 (277.9 MB)
bittorrent-v1-v2-hybrid-test/meet the deadline - Still _ Evoke 2014.mp4 (44.58 MB)
bittorrent-v1-v2-hybrid-test/readme.txt (0.06 kB)
bittorrent-v1-v2-hybrid-test/readme.txt (61 B)
bittorrent-v1-v2-hybrid-test/tbl-goa.avi (26.30 MB)
bittorrent-v1-v2-hybrid-test/tbl-tint.mpg (115.9 MB)

View File

@ -29,8 +29,6 @@
#include <libtransmission/utils.h>
#include <libtransmission/version.h>
#include "units.h"
using namespace std::literals;
namespace
@ -139,9 +137,6 @@ int tr_main(int argc, char* argv[])
tr_locale_set_global("");
tr_logSetLevel(TR_LOG_ERROR);
tr_formatter_mem_init(MemK, MemKStr, MemMStr, MemGStr, MemTStr);
tr_formatter_size_init(DiskK, DiskKStr, DiskMStr, DiskGStr, DiskTStr);
tr_formatter_speed_init(SpeedK, SpeedKStr, SpeedMStr, SpeedGStr, SpeedTStr);
auto options = app_options{};
if (parseCommandLine(options, argc, (char const* const*)argv) != 0)

View File

@ -61,24 +61,6 @@ static char constexpr Usage[] = "transmission-remote " LONG_VERSION_STRING
static auto constexpr Arguments = TR_KEY_arguments;
static auto constexpr MemK = size_t{ 1024 };
static char constexpr MemKStr[] = "KiB";
static char constexpr MemMStr[] = MEM_M_STR;
static char constexpr MemGStr[] = "GiB";
static char constexpr MemTStr[] = "TiB";
static auto constexpr DiskK = size_t{ 1000 };
static char constexpr DiskKStr[] = "kB";
static char constexpr DiskMStr[] = "MB";
static char constexpr DiskGStr[] = "GB";
static char constexpr DiskTStr[] = "TB";
static auto constexpr SpeedK = size_t{ 1000 };
static auto constexpr SpeedKStr = SPEED_K_STR;
static char constexpr SpeedMStr[] = "MB/s";
static char constexpr SpeedGStr[] = "GB/s";
static char constexpr SpeedTStr[] = "TB/s";
struct Config
{
std::string auth;
@ -3329,10 +3311,6 @@ int tr_main(int argc, char* argv[])
return EXIT_FAILURE;
}
tr_formatter_mem_init(MemK, MemKStr, MemMStr, MemGStr, MemTStr);
tr_formatter_size_init(DiskK, DiskKStr, DiskMStr, DiskGStr, DiskTStr);
tr_formatter_speed_init(SpeedK, SpeedKStr, SpeedMStr, SpeedGStr, SpeedTStr);
getHostAndPortAndRpcUrl(&argc, argv, &host, &port, &rpcurl, config);
if (std::empty(host))

View File

@ -35,8 +35,6 @@
#include <libtransmission/web.h>
#include <libtransmission/web-utils.h>
#include "units.h"
using namespace std::literals;
namespace
@ -409,9 +407,6 @@ int tr_main(int argc, char* argv[])
tr_logSetQueueEnabled(false);
tr_logSetLevel(TR_LOG_ERROR);
tr_formatter_mem_init(MemK, MemKStr, MemMStr, MemGStr, MemTStr);
tr_formatter_size_init(DiskK, DiskKStr, DiskMStr, DiskGStr, DiskTStr);
tr_formatter_speed_init(SpeedK, SpeedKStr, SpeedMStr, SpeedGStr, SpeedTStr);
auto opts = app_opts{};
if (parseCommandLine(opts, argc, (char const* const*)argv) != 0)

View File

@ -1,26 +0,0 @@
// This file Copyright © Mnemosyne LLC.
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
#pragma once
#include <cstddef>
static auto constexpr MemK = size_t{ 1024 };
static char constexpr MemKStr[] = "KiB";
static char constexpr MemMStr[] = "MiB";
static char constexpr MemGStr[] = "GiB";
static char constexpr MemTStr[] = "TiB";
static auto constexpr DiskK = size_t{ 1000 };
static char constexpr DiskKStr[] = "kB";
static char constexpr DiskMStr[] = "MB";
static char constexpr DiskGStr[] = "GB";
static char constexpr DiskTStr[] = "TB";
static auto constexpr SpeedK = size_t{ 1000 };
static char constexpr SpeedKStr[] = "kB/s";
static char constexpr SpeedMStr[] = "MB/s";
static char constexpr SpeedGStr[] = "GB/s";
static char constexpr SpeedTStr[] = "TB/s";