mirror of
https://github.com/transmission/transmission.git
synced 2025-12-19 18:08:31 +00:00
refactor: misc-use-anonymous-namespace pt. 2 (#4538)
This commit is contained in:
@@ -696,7 +696,7 @@ endif()
|
||||
|
||||
if(RUN_CLANG_TIDY)
|
||||
message(STATUS "Looking for clang-tidy")
|
||||
find_program(CLANG_TIDY clang-tidy-15 clang-tidy)
|
||||
find_program(CLANG_TIDY clang-tidy)
|
||||
if(CLANG_TIDY STREQUAL "CLANG_TIDY-NOTFOUND")
|
||||
message(STATUS "Looking for clang-tidy - not found")
|
||||
else()
|
||||
|
||||
@@ -42,15 +42,17 @@
|
||||
#define logdbg(interned, msg) tr_logAddDebug(msg, (interned).sv())
|
||||
#define logtrace(interned, msg) tr_logAddTrace(msg, (interned).sv())
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace std::literals;
|
||||
|
||||
// size defined by bep15
|
||||
using tau_connection_t = uint64_t;
|
||||
using tau_transaction_t = uint32_t;
|
||||
|
||||
static constexpr auto TauConnectionTtlSecs = time_t{ 45 };
|
||||
constexpr auto TauConnectionTtlSecs = time_t{ 45 };
|
||||
|
||||
static auto tau_transaction_new()
|
||||
auto tau_transaction_new()
|
||||
{
|
||||
return tr_rand_obj<tau_transaction_t>();
|
||||
}
|
||||
@@ -64,9 +66,7 @@ enum tau_action_t
|
||||
TAU_ACTION_ERROR = 3
|
||||
};
|
||||
|
||||
/****
|
||||
***** SCRAPE
|
||||
****/
|
||||
/// SCRAPE
|
||||
|
||||
struct tau_scrape_request
|
||||
{
|
||||
@@ -162,9 +162,7 @@ private:
|
||||
tr_scrape_response_func on_response_;
|
||||
};
|
||||
|
||||
/****
|
||||
***** ANNOUNCE
|
||||
****/
|
||||
/// ANNOUNCE
|
||||
|
||||
struct tau_announce_request
|
||||
{
|
||||
@@ -287,9 +285,7 @@ private:
|
||||
tr_announce_response_func on_response_;
|
||||
};
|
||||
|
||||
/****
|
||||
***** TRACKER
|
||||
****/
|
||||
/// TRACKER
|
||||
|
||||
struct tau_tracker
|
||||
{
|
||||
@@ -573,9 +569,7 @@ private:
|
||||
static inline constexpr auto ConnectionRequestTtl = int{ 30 };
|
||||
};
|
||||
|
||||
/****
|
||||
***** SESSION
|
||||
****/
|
||||
/// SESSION
|
||||
|
||||
class tr_announcer_udp_impl final : public tr_announcer_udp
|
||||
{
|
||||
@@ -751,6 +745,8 @@ private:
|
||||
Mediator& mediator_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<tr_announcer_udp> tr_announcer_udp::create(Mediator& mediator)
|
||||
{
|
||||
return std::make_unique<tr_announcer_udp_impl>(mediator);
|
||||
|
||||
@@ -97,7 +97,9 @@
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
static void set_system_error(tr_error** error, int code)
|
||||
namespace
|
||||
{
|
||||
void set_system_error(tr_error** error, int code)
|
||||
{
|
||||
if (error == nullptr)
|
||||
{
|
||||
@@ -107,7 +109,7 @@ static void set_system_error(tr_error** error, int code)
|
||||
tr_error_set(error, code, tr_strerror(code));
|
||||
}
|
||||
|
||||
static void set_system_error_if_file_found(tr_error** error, int code)
|
||||
void set_system_error_if_file_found(tr_error** error, int code)
|
||||
{
|
||||
if (code != ENOENT)
|
||||
{
|
||||
@@ -115,7 +117,7 @@ static void set_system_error_if_file_found(tr_error** error, int code)
|
||||
}
|
||||
}
|
||||
|
||||
static void set_file_for_single_pass(tr_sys_file_t handle)
|
||||
void set_file_for_single_pass(tr_sys_file_t handle)
|
||||
{
|
||||
/* Set hints about the lookahead buffer and caching. It's okay
|
||||
for these to fail silently, so don't let them affect errno */
|
||||
@@ -142,6 +144,7 @@ static void set_file_for_single_pass(tr_sys_file_t handle)
|
||||
|
||||
errno = err;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool tr_sys_path_exists(char const* path, tr_error** error)
|
||||
{
|
||||
|
||||
@@ -28,18 +28,15 @@
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace tr_resume
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr int MaxRememberedPeers = 200;
|
||||
|
||||
} // unnamed namespace
|
||||
///
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
static void savePeers(tr_variant* dict, tr_torrent const* tor)
|
||||
void savePeers(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
if (auto const pex = tr_peerMgrGetPeers(tor, TR_AF_INET, TR_PEERS_INTERESTING, MaxRememberedPeers); !std::empty(pex))
|
||||
{
|
||||
@@ -52,7 +49,7 @@ static void savePeers(tr_variant* dict, tr_torrent const* tor)
|
||||
}
|
||||
}
|
||||
|
||||
static size_t addPeers(tr_torrent* tor, uint8_t const* buf, size_t buflen)
|
||||
size_t addPeers(tr_torrent* tor, uint8_t const* buf, size_t buflen)
|
||||
{
|
||||
size_t const n_in = buflen / sizeof(tr_pex);
|
||||
size_t const n_pex = std::min(n_in, size_t{ MaxRememberedPeers });
|
||||
@@ -62,7 +59,7 @@ static size_t addPeers(tr_torrent* tor, uint8_t const* buf, size_t buflen)
|
||||
return tr_peerMgrAddPex(tor, TR_PEER_FROM_RESUME, std::data(pex), n_pex);
|
||||
}
|
||||
|
||||
static auto loadPeers(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadPeers(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
@@ -85,11 +82,9 @@ static auto loadPeers(tr_variant* dict, tr_torrent* tor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static void saveLabels(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveLabels(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
auto const& labels = tor->labels;
|
||||
tr_variant* list = tr_variantDictAddList(dict, TR_KEY_labels, std::size(labels));
|
||||
@@ -99,7 +94,7 @@ static void saveLabels(tr_variant* dict, tr_torrent const* tor)
|
||||
}
|
||||
}
|
||||
|
||||
static auto loadLabels(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadLabels(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
tr_variant* list = nullptr;
|
||||
if (!tr_variantDictFindList(dict, TR_KEY_labels, &list))
|
||||
@@ -123,16 +118,14 @@ static auto loadLabels(tr_variant* dict, tr_torrent* tor)
|
||||
return tr_resume::Labels;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static void saveGroup(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveGroup(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
tr_variantDictAddStrView(dict, TR_KEY_group, tor->bandwidthGroup());
|
||||
}
|
||||
|
||||
static auto loadGroup(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadGroup(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
if (std::string_view group_name; tr_variantDictFindStrView(dict, TR_KEY_group, &group_name) && !std::empty(group_name))
|
||||
{
|
||||
@@ -143,11 +136,9 @@ static auto loadGroup(tr_variant* dict, tr_torrent* tor)
|
||||
return tr_resume::fields_t{};
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static void saveDND(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveDND(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
auto const n = tor->fileCount();
|
||||
tr_variant* const list = tr_variantDictAddList(dict, TR_KEY_dnd, n);
|
||||
@@ -158,7 +149,7 @@ static void saveDND(tr_variant* dict, tr_torrent const* tor)
|
||||
}
|
||||
}
|
||||
|
||||
static auto loadDND(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadDND(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
tr_variant* list = nullptr;
|
||||
@@ -202,11 +193,9 @@ static auto loadDND(tr_variant* dict, tr_torrent* tor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static void saveFilePriorities(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveFilePriorities(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
auto const n = tor->fileCount();
|
||||
|
||||
@@ -217,7 +206,7 @@ static void saveFilePriorities(tr_variant* dict, tr_torrent const* tor)
|
||||
}
|
||||
}
|
||||
|
||||
static auto loadFilePriorities(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadFilePriorities(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
@@ -240,11 +229,9 @@ static auto loadFilePriorities(tr_variant* dict, tr_torrent* tor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static void saveSingleSpeedLimit(tr_variant* d, tr_torrent const* tor, tr_direction dir)
|
||||
void saveSingleSpeedLimit(tr_variant* d, tr_torrent const* tor, tr_direction dir)
|
||||
{
|
||||
tr_variantDictReserve(d, 3);
|
||||
tr_variantDictAddInt(d, TR_KEY_speed_Bps, tor->speedLimitBps(dir));
|
||||
@@ -252,27 +239,27 @@ static void saveSingleSpeedLimit(tr_variant* d, tr_torrent const* tor, tr_direct
|
||||
tr_variantDictAddBool(d, TR_KEY_use_speed_limit, tor->usesSpeedLimit(dir));
|
||||
}
|
||||
|
||||
static void saveSpeedLimits(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveSpeedLimits(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
saveSingleSpeedLimit(tr_variantDictAddDict(dict, TR_KEY_speed_limit_down, 0), tor, TR_DOWN);
|
||||
saveSingleSpeedLimit(tr_variantDictAddDict(dict, TR_KEY_speed_limit_up, 0), tor, TR_UP);
|
||||
}
|
||||
|
||||
static void saveRatioLimits(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveRatioLimits(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
tr_variant* d = tr_variantDictAddDict(dict, TR_KEY_ratio_limit, 2);
|
||||
tr_variantDictAddReal(d, TR_KEY_ratio_limit, tr_torrentGetRatioLimit(tor));
|
||||
tr_variantDictAddInt(d, TR_KEY_ratio_mode, tr_torrentGetRatioMode(tor));
|
||||
}
|
||||
|
||||
static void saveIdleLimits(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveIdleLimits(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
tr_variant* d = tr_variantDictAddDict(dict, TR_KEY_idle_limit, 2);
|
||||
tr_variantDictAddInt(d, TR_KEY_idle_limit, tor->idleLimitMinutes());
|
||||
tr_variantDictAddInt(d, TR_KEY_idle_mode, tor->idleLimitMode());
|
||||
}
|
||||
|
||||
static void loadSingleSpeedLimit(tr_variant* d, tr_direction dir, tr_torrent* tor)
|
||||
void loadSingleSpeedLimit(tr_variant* d, tr_direction dir, tr_torrent* tor)
|
||||
{
|
||||
if (auto val = int64_t{}; tr_variantDictFindInt(d, TR_KEY_speed_Bps, &val))
|
||||
{
|
||||
@@ -294,7 +281,7 @@ static void loadSingleSpeedLimit(tr_variant* d, tr_direction dir, tr_torrent* to
|
||||
}
|
||||
}
|
||||
|
||||
static auto loadSpeedLimits(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadSpeedLimits(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
@@ -313,7 +300,7 @@ static auto loadSpeedLimits(tr_variant* dict, tr_torrent* tor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static auto loadRatioLimits(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadRatioLimits(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
@@ -335,7 +322,7 @@ static auto loadRatioLimits(tr_variant* dict, tr_torrent* tor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static auto loadIdleLimits(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadIdleLimits(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
@@ -357,16 +344,14 @@ static auto loadIdleLimits(tr_variant* dict, tr_torrent* tor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static void saveName(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveName(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
tr_variantDictAddStrView(dict, TR_KEY_name, tr_torrentName(tor));
|
||||
}
|
||||
|
||||
static auto loadName(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadName(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
@@ -388,11 +373,9 @@ static auto loadName(tr_variant* dict, tr_torrent* tor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static void saveFilenames(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveFilenames(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
auto const n = tor->fileCount();
|
||||
tr_variant* const list = tr_variantDictAddList(dict, TR_KEY_files, n);
|
||||
@@ -402,7 +385,7 @@ static void saveFilenames(tr_variant* dict, tr_torrent const* tor)
|
||||
}
|
||||
}
|
||||
|
||||
static auto loadFilenames(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadFilenames(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
@@ -427,11 +410,9 @@ static auto loadFilenames(tr_variant* dict, tr_torrent* tor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static void bitfieldToRaw(tr_bitfield const& b, tr_variant* benc)
|
||||
void bitfieldToRaw(tr_bitfield const& b, tr_variant* benc)
|
||||
{
|
||||
if (b.hasNone() || (std::empty(b) != 0U))
|
||||
{
|
||||
@@ -448,7 +429,7 @@ static void bitfieldToRaw(tr_bitfield const& b, tr_variant* benc)
|
||||
}
|
||||
}
|
||||
|
||||
static void rawToBitfield(tr_bitfield& bitfield, uint8_t const* raw, size_t rawlen)
|
||||
void rawToBitfield(tr_bitfield& bitfield, uint8_t const* raw, size_t rawlen)
|
||||
{
|
||||
if (raw == nullptr || rawlen == 0 || (rawlen == 4 && memcmp(raw, "none", 4) == 0))
|
||||
{
|
||||
@@ -464,7 +445,7 @@ static void rawToBitfield(tr_bitfield& bitfield, uint8_t const* raw, size_t rawl
|
||||
}
|
||||
}
|
||||
|
||||
static void saveProgress(tr_variant* dict, tr_torrent const* tor)
|
||||
void saveProgress(tr_variant* dict, tr_torrent const* tor)
|
||||
{
|
||||
tr_variant* const prog = tr_variantDictAddDict(dict, TR_KEY_progress, 4);
|
||||
|
||||
@@ -510,7 +491,7 @@ static void saveProgress(tr_variant* dict, tr_torrent const* tor)
|
||||
* First approach (pre-2.20) had an "mtimes" list identical to
|
||||
* 3.10, but not the 'pieces' bitfield.
|
||||
*/
|
||||
static auto loadProgress(tr_variant* dict, tr_torrent* tor)
|
||||
auto loadProgress(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
if (tr_variant* prog = nullptr; tr_variantDictFindDict(dict, TR_KEY_progress, &prog))
|
||||
{
|
||||
@@ -638,11 +619,9 @@ static auto loadProgress(tr_variant* dict, tr_torrent* tor)
|
||||
return tr_resume::fields_t{};
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static auto loadFromFile(tr_torrent* tor, tr_resume::fields_t fields_to_load, bool* did_migrate_filename)
|
||||
auto loadFromFile(tr_torrent* tor, tr_resume::fields_t fields_to_load, bool* did_migrate_filename)
|
||||
{
|
||||
auto fields_loaded = tr_resume::fields_t{};
|
||||
|
||||
@@ -839,7 +818,7 @@ static auto loadFromFile(tr_torrent* tor, tr_resume::fields_t fields_to_load, bo
|
||||
return fields_loaded;
|
||||
}
|
||||
|
||||
static auto setFromCtor(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor const* ctor, tr_ctorMode mode)
|
||||
auto setFromCtor(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor const* ctor, tr_ctorMode mode)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
@@ -870,18 +849,16 @@ static auto setFromCtor(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor con
|
||||
return ret;
|
||||
}
|
||||
|
||||
static auto useMandatoryFields(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor const* ctor)
|
||||
auto useMandatoryFields(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor const* ctor)
|
||||
{
|
||||
return setFromCtor(tor, fields, ctor, TR_FORCE);
|
||||
}
|
||||
|
||||
static auto useFallbackFields(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor const* ctor)
|
||||
auto useFallbackFields(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor const* ctor)
|
||||
{
|
||||
return setFromCtor(tor, fields, ctor, TR_FALLBACK);
|
||||
}
|
||||
|
||||
namespace tr_resume
|
||||
{
|
||||
} // namespace
|
||||
|
||||
fields_t load(tr_torrent* tor, fields_t fields_to_load, tr_ctor const* ctor, bool* did_rename_to_hash_only_name)
|
||||
{
|
||||
|
||||
@@ -401,10 +401,95 @@ static bool tr_torrentIsSeedIdleLimitDone(tr_torrent const* tor)
|
||||
difftime(tr_time(), std::max(tor->startDate, tor->activityDate)) >= idle_minutes * 60U;
|
||||
}
|
||||
|
||||
static void torrentCallScript(tr_torrent const* tor, std::string const& script);
|
||||
|
||||
static void callScriptIfEnabled(tr_torrent const* tor, TrScript type)
|
||||
namespace
|
||||
{
|
||||
namespace script_helpers
|
||||
{
|
||||
[[nodiscard]] std::string buildLabelsString(tr_torrent const* tor)
|
||||
{
|
||||
auto buf = std::stringstream{};
|
||||
|
||||
for (auto it = std::begin(tor->labels), end = std::end(tor->labels); it != end;)
|
||||
{
|
||||
buf << tr_quark_get_string_view(*it);
|
||||
|
||||
if (++it != end)
|
||||
{
|
||||
buf << ',';
|
||||
}
|
||||
}
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string buildTrackersString(tr_torrent const* tor)
|
||||
{
|
||||
auto buf = std::stringstream{};
|
||||
|
||||
for (size_t i = 0, n = tr_torrentTrackerCount(tor); i < n; ++i)
|
||||
{
|
||||
buf << tr_torrentTracker(tor, i).host;
|
||||
|
||||
if (++i < n)
|
||||
{
|
||||
buf << ',';
|
||||
}
|
||||
}
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
void torrentCallScript(tr_torrent const* tor, std::string const& script)
|
||||
{
|
||||
if (std::empty(script))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto torrent_dir = tr_pathbuf{ tor->currentDir() };
|
||||
tr_sys_path_native_separators(std::data(torrent_dir));
|
||||
|
||||
auto const cmd = std::array<char const*, 2>{ script.c_str(), nullptr };
|
||||
|
||||
auto const id_str = std::to_string(tr_torrentId(tor));
|
||||
auto const labels_str = buildLabelsString(tor);
|
||||
auto const trackers_str = buildTrackersString(tor);
|
||||
auto const bytes_downloaded_str = std::to_string(tor->downloadedCur + tor->downloadedPrev);
|
||||
|
||||
auto const env = std::map<std::string_view, std::string_view>{
|
||||
{ "TR_APP_VERSION"sv, SHORT_VERSION_STRING },
|
||||
{ "TR_TIME_LOCALTIME"sv, fmt::format("{:%a %b %d %T %Y%n}", fmt::localtime(tr_time())) },
|
||||
{ "TR_TORRENT_BYTES_DOWNLOADED"sv, bytes_downloaded_str },
|
||||
{ "TR_TORRENT_DIR"sv, torrent_dir.c_str() },
|
||||
{ "TR_TORRENT_HASH"sv, tor->infoHashString() },
|
||||
{ "TR_TORRENT_ID"sv, id_str },
|
||||
{ "TR_TORRENT_LABELS"sv, labels_str },
|
||||
{ "TR_TORRENT_NAME"sv, tr_torrentName(tor) },
|
||||
{ "TR_TORRENT_TRACKERS"sv, trackers_str },
|
||||
};
|
||||
|
||||
tr_logAddInfoTor(tor, fmt::format(_("Calling script '{path}'"), fmt::arg("path", script)));
|
||||
|
||||
tr_error* error = nullptr;
|
||||
|
||||
if (!tr_spawn_async(std::data(cmd), env, TR_IF_WIN32("\\", "/"), &error))
|
||||
{
|
||||
tr_logAddWarnTor(
|
||||
tor,
|
||||
fmt::format(
|
||||
_("Couldn't call script '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", script),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
}
|
||||
}
|
||||
} // namespace script_helpers
|
||||
|
||||
void callScriptIfEnabled(tr_torrent const* tor, TrScript type)
|
||||
{
|
||||
using namespace script_helpers;
|
||||
|
||||
auto const* session = tor->session;
|
||||
|
||||
if (tr_sessionIsScriptEnabled(session, type))
|
||||
@@ -413,9 +498,9 @@ static void callScriptIfEnabled(tr_torrent const* tor, TrScript type)
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
} // namespace
|
||||
|
||||
///
|
||||
|
||||
void tr_torrentCheckSeedLimit(tr_torrent* tor)
|
||||
{
|
||||
@@ -1568,7 +1653,11 @@ void tr_torrentRemove(tr_torrent* tor, bool delete_flag, tr_fileFunc delete_func
|
||||
*** Completeness
|
||||
**/
|
||||
|
||||
static char const* getCompletionString(int type)
|
||||
namespace
|
||||
{
|
||||
namespace completeness_helpers
|
||||
{
|
||||
[[nodiscard]] constexpr char const* get_completion_string(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@@ -1587,89 +1676,13 @@ static char const* getCompletionString(int type)
|
||||
return "Incomplete";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string buildLabelsString(tr_torrent const* tor)
|
||||
{
|
||||
auto buf = std::stringstream{};
|
||||
|
||||
for (auto it = std::begin(tor->labels), end = std::end(tor->labels); it != end;)
|
||||
{
|
||||
buf << tr_quark_get_string_view(*it);
|
||||
|
||||
if (++it != end)
|
||||
{
|
||||
buf << ',';
|
||||
}
|
||||
}
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
static std::string buildTrackersString(tr_torrent const* tor)
|
||||
{
|
||||
auto buf = std::stringstream{};
|
||||
|
||||
for (size_t i = 0, n = tr_torrentTrackerCount(tor); i < n; ++i)
|
||||
{
|
||||
buf << tr_torrentTracker(tor, i).host;
|
||||
|
||||
if (++i < n)
|
||||
{
|
||||
buf << ',';
|
||||
}
|
||||
}
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
static void torrentCallScript(tr_torrent const* tor, std::string const& script)
|
||||
{
|
||||
if (std::empty(script))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto torrent_dir = tr_pathbuf{ tor->currentDir() };
|
||||
tr_sys_path_native_separators(std::data(torrent_dir));
|
||||
|
||||
auto const cmd = std::array<char const*, 2>{ script.c_str(), nullptr };
|
||||
|
||||
auto const id_str = std::to_string(tr_torrentId(tor));
|
||||
auto const labels_str = buildLabelsString(tor);
|
||||
auto const trackers_str = buildTrackersString(tor);
|
||||
auto const bytes_downloaded_str = std::to_string(tor->downloadedCur + tor->downloadedPrev);
|
||||
|
||||
auto const env = std::map<std::string_view, std::string_view>{
|
||||
{ "TR_APP_VERSION"sv, SHORT_VERSION_STRING },
|
||||
{ "TR_TIME_LOCALTIME"sv, fmt::format("{:%a %b %d %T %Y%n}", fmt::localtime(tr_time())) },
|
||||
{ "TR_TORRENT_BYTES_DOWNLOADED"sv, bytes_downloaded_str },
|
||||
{ "TR_TORRENT_DIR"sv, torrent_dir.c_str() },
|
||||
{ "TR_TORRENT_HASH"sv, tor->infoHashString() },
|
||||
{ "TR_TORRENT_ID"sv, id_str },
|
||||
{ "TR_TORRENT_LABELS"sv, labels_str },
|
||||
{ "TR_TORRENT_NAME"sv, tr_torrentName(tor) },
|
||||
{ "TR_TORRENT_TRACKERS"sv, trackers_str },
|
||||
};
|
||||
|
||||
tr_logAddInfoTor(tor, fmt::format(_("Calling script '{path}'"), fmt::arg("path", script)));
|
||||
|
||||
tr_error* error = nullptr;
|
||||
|
||||
if (!tr_spawn_async(std::data(cmd), env, TR_IF_WIN32("\\", "/"), &error))
|
||||
{
|
||||
tr_logAddWarnTor(
|
||||
tor,
|
||||
fmt::format(
|
||||
_("Couldn't call script '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", script),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
}
|
||||
}
|
||||
} // namespace completeness_helpers
|
||||
} // namespace
|
||||
|
||||
void tr_torrent::recheckCompleteness()
|
||||
{
|
||||
using namespace completeness_helpers;
|
||||
|
||||
auto const lock = unique_lock();
|
||||
|
||||
needs_completeness_check_ = false;
|
||||
@@ -1688,8 +1701,8 @@ void tr_torrent::recheckCompleteness()
|
||||
this,
|
||||
fmt::format(
|
||||
"State changed from {} to {}",
|
||||
getCompletionString(this->completeness),
|
||||
getCompletionString(completeness)));
|
||||
get_completion_string(this->completeness),
|
||||
get_completion_string(completeness)));
|
||||
}
|
||||
|
||||
this->completeness = new_completeness;
|
||||
@@ -2395,19 +2408,19 @@ static void torrentSetQueued(tr_torrent* tor, bool queued)
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
**** RENAME
|
||||
****
|
||||
***/
|
||||
/// RENAME
|
||||
|
||||
static bool renameArgsAreValid(std::string_view oldpath, std::string_view newname)
|
||||
namespace
|
||||
{
|
||||
namespace rename_helpers
|
||||
{
|
||||
bool renameArgsAreValid(std::string_view oldpath, std::string_view newname)
|
||||
{
|
||||
return !std::empty(oldpath) && !std::empty(newname) && newname != "."sv && newname != ".."sv &&
|
||||
!tr_strvContains(newname, TR_PATH_DELIMITER);
|
||||
}
|
||||
|
||||
static auto renameFindAffectedFiles(tr_torrent const* tor, std::string_view oldpath)
|
||||
auto renameFindAffectedFiles(tr_torrent const* tor, std::string_view oldpath)
|
||||
{
|
||||
auto indices = std::vector<tr_file_index_t>{};
|
||||
auto const oldpath_as_dir = tr_pathbuf{ oldpath, '/' };
|
||||
@@ -2425,7 +2438,7 @@ static auto renameFindAffectedFiles(tr_torrent const* tor, std::string_view oldp
|
||||
return indices;
|
||||
}
|
||||
|
||||
static int renamePath(tr_torrent const* tor, std::string_view oldpath, std::string_view newname)
|
||||
int renamePath(tr_torrent const* tor, std::string_view oldpath, std::string_view newname)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
@@ -2468,11 +2481,7 @@ static int renamePath(tr_torrent const* tor, std::string_view oldpath, std::stri
|
||||
return err;
|
||||
}
|
||||
|
||||
static void renameTorrentFileString(
|
||||
tr_torrent* tor,
|
||||
std::string_view oldpath,
|
||||
std::string_view newname,
|
||||
tr_file_index_t file_index)
|
||||
void renameTorrentFileString(tr_torrent* tor, std::string_view oldpath, std::string_view newname, tr_file_index_t file_index)
|
||||
{
|
||||
auto name = std::string{};
|
||||
auto const subpath = std::string_view{ tor->fileSubpath(file_index) };
|
||||
@@ -2514,7 +2523,7 @@ static void renameTorrentFileString(
|
||||
}
|
||||
}
|
||||
|
||||
static void torrentRenamePath(
|
||||
void torrentRenamePath(
|
||||
tr_torrent* const tor,
|
||||
std::string oldpath, // NOLINT performance-unnecessary-value-param
|
||||
std::string newname, // NOLINT performance-unnecessary-value-param
|
||||
@@ -2523,10 +2532,6 @@ static void torrentRenamePath(
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
int error = 0;
|
||||
|
||||
if (!renameArgsAreValid(oldpath, newname))
|
||||
@@ -2560,9 +2565,7 @@ static void torrentRenamePath(
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
tor->markChanged();
|
||||
|
||||
@@ -2573,12 +2576,17 @@ static void torrentRenamePath(
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rename_helpers
|
||||
} // namespace
|
||||
|
||||
void tr_torrent::renamePath(
|
||||
std::string_view oldpath,
|
||||
std::string_view newname,
|
||||
tr_torrent_rename_done_func callback,
|
||||
void* callback_user_data)
|
||||
{
|
||||
using namespace rename_helpers;
|
||||
|
||||
this->session->runInSessionThread(
|
||||
torrentRenamePath,
|
||||
this,
|
||||
@@ -2601,6 +2609,8 @@ void tr_torrentRenamePath(
|
||||
tor->renamePath(oldpath, newname, callback, callback_user_data);
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
void tr_torrentSetFilePriorities(
|
||||
tr_torrent* tor,
|
||||
tr_file_index_t const* files,
|
||||
|
||||
@@ -20,7 +20,9 @@ using namespace std::literals;
|
||||
|
||||
int tr_optind = 1;
|
||||
|
||||
static std::string_view getArgName(tr_option const* opt)
|
||||
namespace
|
||||
{
|
||||
[[nodiscard]] constexpr std::string_view getArgName(tr_option const* opt)
|
||||
{
|
||||
if (!opt->has_arg)
|
||||
{
|
||||
@@ -35,7 +37,7 @@ static std::string_view getArgName(tr_option const* opt)
|
||||
return "<args>"sv;
|
||||
}
|
||||
|
||||
static size_t get_next_line_len(std::string_view description, size_t maxlen)
|
||||
[[nodiscard]] constexpr size_t get_next_line_len(std::string_view description, size_t maxlen)
|
||||
{
|
||||
auto len = std::size(description);
|
||||
if (len > maxlen)
|
||||
@@ -47,7 +49,7 @@ static size_t get_next_line_len(std::string_view description, size_t maxlen)
|
||||
return len;
|
||||
}
|
||||
|
||||
static void getopts_usage_line(tr_option const* const opt, size_t long_width, size_t short_width, size_t arg_width)
|
||||
void getopts_usage_line(tr_option const* const opt, size_t long_width, size_t short_width, size_t arg_width)
|
||||
{
|
||||
auto const long_name = std::string_view{ opt->longName != nullptr ? opt->longName : "" };
|
||||
auto const short_name = std::string_view{ opt->shortName != nullptr ? opt->shortName : "" };
|
||||
@@ -82,7 +84,7 @@ static void getopts_usage_line(tr_option const* const opt, size_t long_width, si
|
||||
}
|
||||
}
|
||||
|
||||
static void maxWidth(struct tr_option const* o, size_t& long_width, size_t& short_width, size_t& arg_width)
|
||||
void maxWidth(struct tr_option const* o, size_t& long_width, size_t& short_width, size_t& arg_width)
|
||||
{
|
||||
if (o->longName != nullptr)
|
||||
{
|
||||
@@ -100,36 +102,7 @@ static void maxWidth(struct tr_option const* o, size_t& long_width, size_t& shor
|
||||
}
|
||||
}
|
||||
|
||||
void tr_getopt_usage(char const* app_name, char const* description, struct tr_option const* opts)
|
||||
{
|
||||
auto long_width = size_t{ 0 };
|
||||
auto short_width = size_t{ 0 };
|
||||
auto arg_width = size_t{ 0 };
|
||||
|
||||
for (tr_option const* o = opts; o->val != 0; ++o)
|
||||
{
|
||||
maxWidth(o, long_width, short_width, arg_width);
|
||||
}
|
||||
|
||||
auto const help = tr_option{ -1, "help", "Display this help page and exit", "h", false, nullptr };
|
||||
maxWidth(&help, long_width, short_width, arg_width);
|
||||
|
||||
if (description == nullptr)
|
||||
{
|
||||
description = "Usage: %s [options]";
|
||||
}
|
||||
|
||||
printf(description, app_name);
|
||||
printf("\n\nOptions:\n");
|
||||
getopts_usage_line(&help, long_width, short_width, arg_width);
|
||||
|
||||
for (tr_option const* o = opts; o->val != 0; ++o)
|
||||
{
|
||||
getopts_usage_line(o, long_width, short_width, arg_width);
|
||||
}
|
||||
}
|
||||
|
||||
static tr_option const* findOption(tr_option const* opts, char const* str, char const** setme_arg)
|
||||
tr_option const* findOption(tr_option const* opts, char const* str, char const** setme_arg)
|
||||
{
|
||||
size_t matchlen = 0;
|
||||
char const* arg = nullptr;
|
||||
@@ -180,6 +153,37 @@ static tr_option const* findOption(tr_option const* opts, char const* str, char
|
||||
return match;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void tr_getopt_usage(char const* app_name, char const* description, struct tr_option const* opts)
|
||||
{
|
||||
auto long_width = size_t{ 0 };
|
||||
auto short_width = size_t{ 0 };
|
||||
auto arg_width = size_t{ 0 };
|
||||
|
||||
for (tr_option const* o = opts; o->val != 0; ++o)
|
||||
{
|
||||
maxWidth(o, long_width, short_width, arg_width);
|
||||
}
|
||||
|
||||
auto const help = tr_option{ -1, "help", "Display this help page and exit", "h", false, nullptr };
|
||||
maxWidth(&help, long_width, short_width, arg_width);
|
||||
|
||||
if (description == nullptr)
|
||||
{
|
||||
description = "Usage: %s [options]";
|
||||
}
|
||||
|
||||
printf(description, app_name);
|
||||
printf("\n\nOptions:\n");
|
||||
getopts_usage_line(&help, long_width, short_width, arg_width);
|
||||
|
||||
for (tr_option const* o = opts; o->val != 0; ++o)
|
||||
{
|
||||
getopts_usage_line(o, long_width, short_width, arg_width);
|
||||
}
|
||||
}
|
||||
|
||||
int tr_getopt(char const* usage, int argc, char const* const* argv, tr_option const* opts, char const** setme_optarg)
|
||||
{
|
||||
char const* arg = nullptr;
|
||||
|
||||
@@ -28,10 +28,7 @@ using namespace std::literals;
|
||||
|
||||
auto constexpr MaxBencStrLength = size_t{ 128 * 1024 * 1024 }; // arbitrary
|
||||
|
||||
/***
|
||||
****
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
namespace transmission::benc::impl
|
||||
{
|
||||
@@ -126,11 +123,12 @@ std::optional<std::string_view> ParseString(std::string_view* benc)
|
||||
|
||||
} // namespace transmission::benc::impl
|
||||
|
||||
/***
|
||||
**** tr_variantParse()
|
||||
**** tr_variantLoad()
|
||||
***/
|
||||
///
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace parse_helpers
|
||||
{
|
||||
struct MyHandler : public transmission::benc::Handler
|
||||
{
|
||||
tr_variant* const top_;
|
||||
@@ -260,34 +258,40 @@ private:
|
||||
return node;
|
||||
}
|
||||
};
|
||||
} // namespace parse_helpers
|
||||
} // namespace
|
||||
|
||||
bool tr_variantParseBenc(tr_variant& top, int parse_opts, std::string_view benc, char const** setme_end, tr_error** error)
|
||||
{
|
||||
using namespace parse_helpers;
|
||||
using Stack = transmission::benc::ParserStack<512>;
|
||||
|
||||
auto stack = Stack{};
|
||||
auto handler = MyHandler{ &top, parse_opts };
|
||||
return transmission::benc::parse(benc, stack, handler, setme_end, error) && std::empty(stack);
|
||||
}
|
||||
|
||||
/****
|
||||
*****
|
||||
****/
|
||||
///
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace to_string_helpers
|
||||
{
|
||||
using Buffer = libtransmission::Buffer;
|
||||
|
||||
static void saveIntFunc(tr_variant const* val, void* vout)
|
||||
void saveIntFunc(tr_variant const* val, void* vout)
|
||||
{
|
||||
auto buf = std::array<char, 64>{};
|
||||
auto const* const out = fmt::format_to(std::data(buf), FMT_COMPILE("i{:d}e"), val->val.i);
|
||||
static_cast<Buffer*>(vout)->add(std::data(buf), static_cast<size_t>(out - std::data(buf)));
|
||||
}
|
||||
|
||||
static void saveBoolFunc(tr_variant const* val, void* vout)
|
||||
void saveBoolFunc(tr_variant const* val, void* vout)
|
||||
{
|
||||
static_cast<Buffer*>(vout)->add(val->val.b ? "i1e"sv : "i0e"sv);
|
||||
}
|
||||
|
||||
static void saveStringImpl(Buffer* tgt, std::string_view sv)
|
||||
void saveStringImpl(Buffer* tgt, std::string_view sv)
|
||||
{
|
||||
// `${sv.size()}:${sv}`
|
||||
auto prefix = std::array<char, 32>{};
|
||||
@@ -296,14 +300,14 @@ static void saveStringImpl(Buffer* tgt, std::string_view sv)
|
||||
tgt->add(sv);
|
||||
}
|
||||
|
||||
static void saveStringFunc(tr_variant const* v, void* vout)
|
||||
void saveStringFunc(tr_variant const* v, void* vout)
|
||||
{
|
||||
auto sv = std::string_view{};
|
||||
(void)!tr_variantGetStrView(v, &sv);
|
||||
saveStringImpl(static_cast<Buffer*>(vout), sv);
|
||||
}
|
||||
|
||||
static void saveRealFunc(tr_variant const* val, void* vout)
|
||||
void saveRealFunc(tr_variant const* val, void* vout)
|
||||
{
|
||||
// the benc spec doesn't handle floats; save it as a string.
|
||||
|
||||
@@ -312,22 +316,22 @@ static void saveRealFunc(tr_variant const* val, void* vout)
|
||||
saveStringImpl(static_cast<Buffer*>(vout), { std::data(buf), static_cast<size_t>(out - std::data(buf)) });
|
||||
}
|
||||
|
||||
static void saveDictBeginFunc(tr_variant const* /*val*/, void* vbuf)
|
||||
void saveDictBeginFunc(tr_variant const* /*val*/, void* vbuf)
|
||||
{
|
||||
static_cast<Buffer*>(vbuf)->push_back('d');
|
||||
}
|
||||
|
||||
static void saveListBeginFunc(tr_variant const* /*val*/, void* vbuf)
|
||||
void saveListBeginFunc(tr_variant const* /*val*/, void* vbuf)
|
||||
{
|
||||
static_cast<Buffer*>(vbuf)->push_back('l');
|
||||
}
|
||||
|
||||
static void saveContainerEndFunc(tr_variant const* /*val*/, void* vbuf)
|
||||
void saveContainerEndFunc(tr_variant const* /*val*/, void* vbuf)
|
||||
{
|
||||
static_cast<Buffer*>(vbuf)->push_back('e');
|
||||
}
|
||||
|
||||
static struct VariantWalkFuncs const walk_funcs = {
|
||||
struct VariantWalkFuncs const walk_funcs = {
|
||||
saveIntFunc, //
|
||||
saveBoolFunc, //
|
||||
saveRealFunc, //
|
||||
@@ -337,8 +341,13 @@ static struct VariantWalkFuncs const walk_funcs = {
|
||||
saveContainerEndFunc, //
|
||||
};
|
||||
|
||||
} // namespace to_string_helpers
|
||||
} // namespace
|
||||
|
||||
std::string tr_variantToStrBenc(tr_variant const* top)
|
||||
{
|
||||
using namespace to_string_helpers;
|
||||
|
||||
auto buf = libtransmission::Buffer{};
|
||||
tr_variantWalk(top, &walk_funcs, &buf, true);
|
||||
return buf.toString();
|
||||
|
||||
@@ -35,11 +35,14 @@
|
||||
#include "variant.h"
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
using Buffer = libtransmission::Buffer;
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace parse_helpers
|
||||
{
|
||||
/* arbitrary value... this is much deeper than our code goes */
|
||||
static auto constexpr MaxDepth = size_t{ 64 };
|
||||
auto constexpr MaxDepth = size_t{ 64 };
|
||||
|
||||
struct json_wrapper_data
|
||||
{
|
||||
@@ -60,7 +63,7 @@ struct json_wrapper_data
|
||||
std::array<size_t, MaxDepth> preallocGuess;
|
||||
};
|
||||
|
||||
static tr_variant* get_node(struct jsonsl_st* jsn)
|
||||
tr_variant* get_node(struct jsonsl_st* jsn)
|
||||
{
|
||||
auto* data = static_cast<struct json_wrapper_data*>(jsn->data);
|
||||
|
||||
@@ -84,7 +87,7 @@ static tr_variant* get_node(struct jsonsl_st* jsn)
|
||||
return node;
|
||||
}
|
||||
|
||||
static void error_handler(jsonsl_t jsn, jsonsl_error_t error, jsonsl_state_st* /*state*/, jsonsl_char_t const* buf)
|
||||
void error_handler(jsonsl_t jsn, jsonsl_error_t error, jsonsl_state_st* /*state*/, jsonsl_char_t const* buf)
|
||||
{
|
||||
auto* data = static_cast<struct json_wrapper_data*>(jsn->data);
|
||||
|
||||
@@ -99,17 +102,13 @@ static void error_handler(jsonsl_t jsn, jsonsl_error_t error, jsonsl_state_st* /
|
||||
fmt::arg("error_code", error)));
|
||||
}
|
||||
|
||||
static int error_callback(jsonsl_t jsn, jsonsl_error_t error, struct jsonsl_state_st* state, jsonsl_char_t* at)
|
||||
int error_callback(jsonsl_t jsn, jsonsl_error_t error, struct jsonsl_state_st* state, jsonsl_char_t* at)
|
||||
{
|
||||
error_handler(jsn, error, state, at);
|
||||
return 0; /* bail */
|
||||
}
|
||||
|
||||
static void action_callback_PUSH(
|
||||
jsonsl_t jsn,
|
||||
jsonsl_action_t /*action*/,
|
||||
struct jsonsl_state_st* state,
|
||||
jsonsl_char_t const* /*buf*/)
|
||||
void action_callback_PUSH(jsonsl_t jsn, jsonsl_action_t /*action*/, struct jsonsl_state_st* state, jsonsl_char_t const* /*buf*/)
|
||||
{
|
||||
auto* const data = static_cast<json_wrapper_data*>(jsn->data);
|
||||
|
||||
@@ -133,7 +132,7 @@ static void action_callback_PUSH(
|
||||
}
|
||||
|
||||
/* like sscanf(in+2, "%4x", &val) but less slow */
|
||||
static bool decode_hex_string(char const* in, unsigned int* setme)
|
||||
[[nodiscard]] constexpr bool decode_hex_string(char const* in, unsigned int* setme)
|
||||
{
|
||||
TR_ASSERT(in != nullptr);
|
||||
|
||||
@@ -170,7 +169,7 @@ static bool decode_hex_string(char const* in, unsigned int* setme)
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string_view extract_escaped_string(char const* in, size_t in_len, std::string& buf)
|
||||
[[nodiscard]] std::string_view extract_escaped_string(char const* in, size_t in_len, std::string& buf)
|
||||
{
|
||||
char const* const in_end = in + in_len;
|
||||
|
||||
@@ -267,7 +266,7 @@ static std::string_view extract_escaped_string(char const* in, size_t in_len, st
|
||||
return buf;
|
||||
}
|
||||
|
||||
static std::pair<std::string_view, bool> extract_string(jsonsl_t jsn, struct jsonsl_state_st* state, std::string& buf)
|
||||
[[nodiscard]] std::pair<std::string_view, bool> extract_string(jsonsl_t jsn, struct jsonsl_state_st* state, std::string& buf)
|
||||
{
|
||||
// figure out where the string is
|
||||
char const* in_begin = jsn->base + state->pos_begin;
|
||||
@@ -287,11 +286,7 @@ static std::pair<std::string_view, bool> extract_string(jsonsl_t jsn, struct jso
|
||||
return std::make_pair(extract_escaped_string(in_begin, in_len, buf), false);
|
||||
}
|
||||
|
||||
static void action_callback_POP(
|
||||
jsonsl_t jsn,
|
||||
jsonsl_action_t /*action*/,
|
||||
struct jsonsl_state_st* state,
|
||||
jsonsl_char_t const* /*buf*/)
|
||||
void action_callback_POP(jsonsl_t jsn, jsonsl_action_t /*action*/, struct jsonsl_state_st* state, jsonsl_char_t const* /*buf*/)
|
||||
{
|
||||
auto* data = static_cast<struct json_wrapper_data*>(jsn->data);
|
||||
|
||||
@@ -351,8 +346,13 @@ static void action_callback_POP(
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace parse_helpers
|
||||
} // namespace
|
||||
|
||||
bool tr_variantParseJson(tr_variant& setme, int parse_opts, std::string_view json, char const** setme_end, tr_error** error)
|
||||
{
|
||||
using namespace parse_helpers;
|
||||
|
||||
TR_ASSERT((parse_opts & TR_VARIANT_PARSE_JSON) != 0);
|
||||
|
||||
auto data = json_wrapper_data{};
|
||||
@@ -398,10 +398,12 @@ bool tr_variantParseJson(tr_variant& setme, int parse_opts, std::string_view jso
|
||||
return success;
|
||||
}
|
||||
|
||||
/****
|
||||
*****
|
||||
****/
|
||||
///
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace to_string_helpers
|
||||
{
|
||||
struct ParentState
|
||||
{
|
||||
int variantType;
|
||||
@@ -421,7 +423,7 @@ struct JsonWalk
|
||||
bool doIndent;
|
||||
};
|
||||
|
||||
static void jsonIndent(struct JsonWalk* data)
|
||||
void jsonIndent(struct JsonWalk* data)
|
||||
{
|
||||
static auto buf = std::array<char, 1024>{};
|
||||
|
||||
@@ -437,7 +439,7 @@ static void jsonIndent(struct JsonWalk* data)
|
||||
}
|
||||
}
|
||||
|
||||
static void jsonChildFunc(struct JsonWalk* data)
|
||||
void jsonChildFunc(struct JsonWalk* data)
|
||||
{
|
||||
if (!std::empty(data->parents))
|
||||
{
|
||||
@@ -483,18 +485,18 @@ static void jsonChildFunc(struct JsonWalk* data)
|
||||
}
|
||||
}
|
||||
|
||||
static void jsonPushParent(struct JsonWalk* data, tr_variant const* v)
|
||||
void jsonPushParent(struct JsonWalk* data, tr_variant const* v)
|
||||
{
|
||||
int const n_children = tr_variantIsDict(v) ? v->val.l.count * 2 : v->val.l.count;
|
||||
data->parents.push_back({ v->type, 0, n_children });
|
||||
}
|
||||
|
||||
static void jsonPopParent(struct JsonWalk* data)
|
||||
void jsonPopParent(struct JsonWalk* data)
|
||||
{
|
||||
data->parents.pop_back();
|
||||
}
|
||||
|
||||
static void jsonIntFunc(tr_variant const* val, void* vdata)
|
||||
void jsonIntFunc(tr_variant const* val, void* vdata)
|
||||
{
|
||||
auto buf = std::array<char, 64>{};
|
||||
auto const* const out = fmt::format_to(std::data(buf), FMT_COMPILE("{:d}"), val->val.i);
|
||||
@@ -503,7 +505,7 @@ static void jsonIntFunc(tr_variant const* val, void* vdata)
|
||||
jsonChildFunc(data);
|
||||
}
|
||||
|
||||
static void jsonBoolFunc(tr_variant const* val, void* vdata)
|
||||
void jsonBoolFunc(tr_variant const* val, void* vdata)
|
||||
{
|
||||
auto* data = static_cast<struct JsonWalk*>(vdata);
|
||||
|
||||
@@ -519,7 +521,7 @@ static void jsonBoolFunc(tr_variant const* val, void* vdata)
|
||||
jsonChildFunc(data);
|
||||
}
|
||||
|
||||
static void jsonRealFunc(tr_variant const* val, void* vdata)
|
||||
void jsonRealFunc(tr_variant const* val, void* vdata)
|
||||
{
|
||||
auto* data = static_cast<struct JsonWalk*>(vdata);
|
||||
|
||||
@@ -539,7 +541,7 @@ static void jsonRealFunc(tr_variant const* val, void* vdata)
|
||||
jsonChildFunc(data);
|
||||
}
|
||||
|
||||
static void jsonStringFunc(tr_variant const* val, void* vdata)
|
||||
void jsonStringFunc(tr_variant const* val, void* vdata)
|
||||
{
|
||||
auto* data = static_cast<struct JsonWalk*>(vdata);
|
||||
|
||||
@@ -614,7 +616,7 @@ static void jsonStringFunc(tr_variant const* val, void* vdata)
|
||||
jsonChildFunc(data);
|
||||
}
|
||||
|
||||
static void jsonDictBeginFunc(tr_variant const* val, void* vdata)
|
||||
void jsonDictBeginFunc(tr_variant const* val, void* vdata)
|
||||
{
|
||||
auto* data = static_cast<struct JsonWalk*>(vdata);
|
||||
|
||||
@@ -627,7 +629,7 @@ static void jsonDictBeginFunc(tr_variant const* val, void* vdata)
|
||||
}
|
||||
}
|
||||
|
||||
static void jsonListBeginFunc(tr_variant const* val, void* vdata)
|
||||
void jsonListBeginFunc(tr_variant const* val, void* vdata)
|
||||
{
|
||||
size_t const n_children = tr_variantListSize(val);
|
||||
auto* data = static_cast<struct JsonWalk*>(vdata);
|
||||
@@ -641,7 +643,7 @@ static void jsonListBeginFunc(tr_variant const* val, void* vdata)
|
||||
}
|
||||
}
|
||||
|
||||
static void jsonContainerEndFunc(tr_variant const* val, void* vdata)
|
||||
void jsonContainerEndFunc(tr_variant const* val, void* vdata)
|
||||
{
|
||||
auto* data = static_cast<struct JsonWalk*>(vdata);
|
||||
|
||||
@@ -661,7 +663,7 @@ static void jsonContainerEndFunc(tr_variant const* val, void* vdata)
|
||||
jsonChildFunc(data);
|
||||
}
|
||||
|
||||
static struct VariantWalkFuncs const walk_funcs = {
|
||||
struct VariantWalkFuncs const walk_funcs = {
|
||||
jsonIntFunc, //
|
||||
jsonBoolFunc, //
|
||||
jsonRealFunc, //
|
||||
@@ -671,8 +673,13 @@ static struct VariantWalkFuncs const walk_funcs = {
|
||||
jsonContainerEndFunc, //
|
||||
};
|
||||
|
||||
} // namespace to_string_helpers
|
||||
} // namespace
|
||||
|
||||
std::string tr_variantToStrJson(tr_variant const* top, bool lean)
|
||||
{
|
||||
using namespace to_string_helpers;
|
||||
|
||||
auto data = JsonWalk{ !lean };
|
||||
|
||||
tr_variantWalk(top, &walk_funcs, &data, true);
|
||||
|
||||
@@ -32,26 +32,22 @@
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
static constexpr bool tr_variantIsContainer(tr_variant const* v)
|
||||
namespace
|
||||
{
|
||||
constexpr bool tr_variantIsContainer(tr_variant const* v)
|
||||
{
|
||||
return tr_variantIsList(v) || tr_variantIsDict(v);
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static auto constexpr StringInit = tr_variant_string{
|
||||
auto constexpr StringInit = tr_variant_string{
|
||||
TR_STRING_TYPE_QUARK,
|
||||
0,
|
||||
{},
|
||||
};
|
||||
|
||||
static void tr_variant_string_clear(struct tr_variant_string* str)
|
||||
void tr_variant_string_clear(struct tr_variant_string* str)
|
||||
{
|
||||
if (str->type == TR_STRING_TYPE_HEAP)
|
||||
{
|
||||
@@ -62,7 +58,7 @@ static void tr_variant_string_clear(struct tr_variant_string* str)
|
||||
}
|
||||
|
||||
/* returns a const pointer to the variant's string */
|
||||
static constexpr char const* tr_variant_string_get_string(struct tr_variant_string const* str)
|
||||
constexpr char const* tr_variant_string_get_string(struct tr_variant_string const* str)
|
||||
{
|
||||
switch (str->type)
|
||||
{
|
||||
@@ -79,7 +75,7 @@ static constexpr char const* tr_variant_string_get_string(struct tr_variant_stri
|
||||
}
|
||||
}
|
||||
|
||||
static void tr_variant_string_set_quark(struct tr_variant_string* str, tr_quark const quark)
|
||||
void tr_variant_string_set_quark(struct tr_variant_string* str, tr_quark const quark)
|
||||
{
|
||||
tr_variant_string_clear(str);
|
||||
|
||||
@@ -89,7 +85,7 @@ static void tr_variant_string_set_quark(struct tr_variant_string* str, tr_quark
|
||||
str->len = std::size(sv);
|
||||
}
|
||||
|
||||
static void tr_variant_string_set_string(struct tr_variant_string* str, std::string_view in)
|
||||
void tr_variant_string_set_string(struct tr_variant_string* str, std::string_view in)
|
||||
{
|
||||
tr_variant_string_clear(str);
|
||||
|
||||
@@ -118,18 +114,16 @@ static void tr_variant_string_set_string(struct tr_variant_string* str, std::str
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static constexpr char const* getStr(tr_variant const* v)
|
||||
constexpr char const* getStr(tr_variant const* v)
|
||||
{
|
||||
TR_ASSERT(tr_variantIsString(v));
|
||||
|
||||
return tr_variant_string_get_string(&v->val.s);
|
||||
}
|
||||
|
||||
static constexpr int dictIndexOf(tr_variant const* dict, tr_quark const key)
|
||||
constexpr int dictIndexOf(tr_variant const* dict, tr_quark const key)
|
||||
{
|
||||
if (tr_variantIsDict(dict))
|
||||
{
|
||||
@@ -145,6 +139,64 @@ static constexpr int dictIndexOf(tr_variant const* dict, tr_quark const key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool dictFindType(tr_variant* dict, tr_quark const key, int type, tr_variant** setme)
|
||||
{
|
||||
*setme = tr_variantDictFind(dict, key);
|
||||
return tr_variantIsType(*setme, type);
|
||||
}
|
||||
|
||||
tr_variant* containerReserve(tr_variant* v, size_t count)
|
||||
{
|
||||
TR_ASSERT(tr_variantIsContainer(v));
|
||||
|
||||
if (size_t const needed = v->val.l.count + count; needed > v->val.l.alloc)
|
||||
{
|
||||
/* scale the alloc size in powers-of-2 */
|
||||
size_t n = v->val.l.alloc != 0 ? v->val.l.alloc : 8;
|
||||
|
||||
while (n < needed)
|
||||
{
|
||||
n *= 2U;
|
||||
}
|
||||
|
||||
auto* vals = new tr_variant[n];
|
||||
std::copy_n(v->val.l.vals, v->val.l.count, vals);
|
||||
delete[] v->val.l.vals;
|
||||
v->val.l.vals = vals;
|
||||
v->val.l.alloc = n;
|
||||
}
|
||||
|
||||
return v->val.l.vals + v->val.l.count;
|
||||
}
|
||||
|
||||
tr_variant* dictFindOrAdd(tr_variant* dict, tr_quark const key, int type)
|
||||
{
|
||||
/* see if it already exists, and if so, try to reuse it */
|
||||
tr_variant* child = tr_variantDictFind(dict, key);
|
||||
if (child != nullptr)
|
||||
{
|
||||
if (!tr_variantIsType(child, type))
|
||||
{
|
||||
tr_variantDictRemove(dict, key);
|
||||
child = nullptr;
|
||||
}
|
||||
else if (child->type == TR_VARIANT_TYPE_STR)
|
||||
{
|
||||
tr_variant_string_clear(&child->val.s);
|
||||
}
|
||||
}
|
||||
|
||||
/* if it doesn't exist, create it */
|
||||
if (child == nullptr)
|
||||
{
|
||||
child = tr_variantDictAdd(dict, key);
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
tr_variant* tr_variantDictFind(tr_variant* dict, tr_quark const key)
|
||||
{
|
||||
auto const i = dictIndexOf(dict, key);
|
||||
@@ -152,12 +204,6 @@ tr_variant* tr_variantDictFind(tr_variant* dict, tr_quark const key)
|
||||
return i < 0 ? nullptr : dict->val.l.vals + i;
|
||||
}
|
||||
|
||||
static bool tr_variantDictFindType(tr_variant* dict, tr_quark const key, int type, tr_variant** setme)
|
||||
{
|
||||
*setme = tr_variantDictFind(dict, key);
|
||||
return tr_variantIsType(*setme, type);
|
||||
}
|
||||
|
||||
tr_variant* tr_variantListChild(tr_variant* list, size_t pos)
|
||||
{
|
||||
if (tr_variantIsList(list) && pos < list->val.l.count)
|
||||
@@ -341,12 +387,12 @@ bool tr_variantDictFindStrView(tr_variant* dict, tr_quark const key, std::string
|
||||
|
||||
bool tr_variantDictFindList(tr_variant* dict, tr_quark const key, tr_variant** setme)
|
||||
{
|
||||
return tr_variantDictFindType(dict, key, TR_VARIANT_TYPE_LIST, setme);
|
||||
return dictFindType(dict, key, TR_VARIANT_TYPE_LIST, setme);
|
||||
}
|
||||
|
||||
bool tr_variantDictFindDict(tr_variant* dict, tr_quark const key, tr_variant** setme)
|
||||
{
|
||||
return tr_variantDictFindType(dict, key, TR_VARIANT_TYPE_DICT, setme);
|
||||
return dictFindType(dict, key, TR_VARIANT_TYPE_DICT, setme);
|
||||
}
|
||||
|
||||
bool tr_variantDictFindRaw(tr_variant* dict, tr_quark const key, uint8_t const** setme_raw, size_t* setme_len)
|
||||
@@ -361,9 +407,7 @@ bool tr_variantDictFindRaw(tr_variant* dict, tr_quark const key, std::byte const
|
||||
return tr_variantGetRaw(child, setme_raw, setme_len);
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
void tr_variantInitRaw(tr_variant* initme, void const* raw, size_t raw_len)
|
||||
{
|
||||
@@ -389,30 +433,6 @@ void tr_variantInitList(tr_variant* initme, size_t reserve_count)
|
||||
tr_variantListReserve(initme, reserve_count);
|
||||
}
|
||||
|
||||
static tr_variant* containerReserve(tr_variant* v, size_t count)
|
||||
{
|
||||
TR_ASSERT(tr_variantIsContainer(v));
|
||||
|
||||
if (size_t const needed = v->val.l.count + count; needed > v->val.l.alloc)
|
||||
{
|
||||
/* scale the alloc size in powers-of-2 */
|
||||
size_t n = v->val.l.alloc != 0 ? v->val.l.alloc : 8;
|
||||
|
||||
while (n < needed)
|
||||
{
|
||||
n *= 2U;
|
||||
}
|
||||
|
||||
auto* vals = new tr_variant[n];
|
||||
std::copy_n(v->val.l.vals, v->val.l.count, vals);
|
||||
delete[] v->val.l.vals;
|
||||
v->val.l.vals = vals;
|
||||
v->val.l.alloc = n;
|
||||
}
|
||||
|
||||
return v->val.l.vals + v->val.l.count;
|
||||
}
|
||||
|
||||
void tr_variantListReserve(tr_variant* list, size_t count)
|
||||
{
|
||||
TR_ASSERT(tr_variantIsList(list));
|
||||
@@ -520,32 +540,6 @@ tr_variant* tr_variantDictAdd(tr_variant* dict, tr_quark const key)
|
||||
return val;
|
||||
}
|
||||
|
||||
static tr_variant* dictFindOrAdd(tr_variant* dict, tr_quark const key, int type)
|
||||
{
|
||||
/* see if it already exists, and if so, try to reuse it */
|
||||
tr_variant* child = tr_variantDictFind(dict, key);
|
||||
if (child != nullptr)
|
||||
{
|
||||
if (!tr_variantIsType(child, type))
|
||||
{
|
||||
tr_variantDictRemove(dict, key);
|
||||
child = nullptr;
|
||||
}
|
||||
else if (child->type == TR_VARIANT_TYPE_STR)
|
||||
{
|
||||
tr_variant_string_clear(&child->val.s);
|
||||
}
|
||||
}
|
||||
|
||||
/* if it doesn't exist, create it */
|
||||
if (child == nullptr)
|
||||
{
|
||||
child = tr_variantDictAdd(dict, key);
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
tr_variant* tr_variantDictAddInt(tr_variant* dict, tr_quark const key, int64_t val)
|
||||
{
|
||||
tr_variant* child = dictFindOrAdd(dict, key, TR_VARIANT_TYPE_INT);
|
||||
@@ -641,9 +635,7 @@ bool tr_variantDictRemove(tr_variant* dict, tr_quark const key)
|
||||
return removed;
|
||||
}
|
||||
|
||||
/***
|
||||
**** BENC WALKING
|
||||
***/
|
||||
/// BENC WALKING
|
||||
|
||||
class WalkNode
|
||||
{
|
||||
@@ -872,25 +864,27 @@ void tr_variantWalk(tr_variant const* top, struct VariantWalkFuncs const* walk_f
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
*****
|
||||
****/
|
||||
///
|
||||
|
||||
static void freeDummyFunc(tr_variant const* /*v*/, void* /*buf*/)
|
||||
namespace
|
||||
{
|
||||
namespace clear_helpers
|
||||
{
|
||||
void freeDummyFunc(tr_variant const* /*v*/, void* /*buf*/)
|
||||
{
|
||||
}
|
||||
|
||||
static void freeStringFunc(tr_variant const* v, void* /*user_data*/)
|
||||
void freeStringFunc(tr_variant const* v, void* /*user_data*/)
|
||||
{
|
||||
tr_variant_string_clear(&((tr_variant*)v)->val.s);
|
||||
}
|
||||
|
||||
static void freeContainerEndFunc(tr_variant const* v, void* /*user_data*/)
|
||||
void freeContainerEndFunc(tr_variant const* v, void* /*user_data*/)
|
||||
{
|
||||
delete[] v->val.l.vals;
|
||||
}
|
||||
|
||||
static VariantWalkFuncs constexpr FreeWalkFuncs = {
|
||||
VariantWalkFuncs constexpr FreeWalkFuncs = {
|
||||
freeDummyFunc, //
|
||||
freeDummyFunc, //
|
||||
freeDummyFunc, //
|
||||
@@ -899,9 +893,13 @@ static VariantWalkFuncs constexpr FreeWalkFuncs = {
|
||||
freeDummyFunc, //
|
||||
freeContainerEndFunc, //
|
||||
};
|
||||
} // namespace clear_helpers
|
||||
} // namespace
|
||||
|
||||
void tr_variantClear(tr_variant* v)
|
||||
{
|
||||
using namespace clear_helpers;
|
||||
|
||||
if (!tr_variantIsEmpty(v))
|
||||
{
|
||||
tr_variantWalk(v, &FreeWalkFuncs, nullptr, false);
|
||||
@@ -910,11 +908,29 @@ void tr_variantClear(tr_variant* v)
|
||||
*v = {};
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
static void tr_variantListCopy(tr_variant* target, tr_variant const* src)
|
||||
bool tr_variantDictChild(tr_variant* dict, size_t pos, tr_quark* key, tr_variant** setme_value)
|
||||
{
|
||||
TR_ASSERT(tr_variantIsDict(dict));
|
||||
|
||||
bool success = false;
|
||||
|
||||
if (tr_variantIsDict(dict) && pos < dict->val.l.count)
|
||||
{
|
||||
*key = dict->val.l.vals[pos].key;
|
||||
*setme_value = dict->val.l.vals + pos;
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace merge_helpers
|
||||
{
|
||||
void tr_variantListCopy(tr_variant* target, tr_variant const* src)
|
||||
{
|
||||
for (size_t i = 0;; ++i)
|
||||
{
|
||||
@@ -963,29 +979,17 @@ static void tr_variantListCopy(tr_variant* target, tr_variant const* src)
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr size_t tr_variantDictSize(tr_variant const* dict)
|
||||
constexpr size_t tr_variantDictSize(tr_variant const* dict)
|
||||
{
|
||||
return tr_variantIsDict(dict) ? dict->val.l.count : 0;
|
||||
}
|
||||
|
||||
bool tr_variantDictChild(tr_variant* dict, size_t pos, tr_quark* key, tr_variant** setme_value)
|
||||
{
|
||||
TR_ASSERT(tr_variantIsDict(dict));
|
||||
|
||||
bool success = false;
|
||||
|
||||
if (tr_variantIsDict(dict) && pos < dict->val.l.count)
|
||||
{
|
||||
*key = dict->val.l.vals[pos].key;
|
||||
*setme_value = dict->val.l.vals + pos;
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
} // namespace merge_helpers
|
||||
} // namespace
|
||||
|
||||
void tr_variantMergeDicts(tr_variant* target, tr_variant const* source)
|
||||
{
|
||||
using namespace merge_helpers;
|
||||
|
||||
TR_ASSERT(tr_variantIsDict(target));
|
||||
TR_ASSERT(tr_variantIsDict(source));
|
||||
|
||||
@@ -1065,9 +1069,7 @@ void tr_variantMergeDicts(tr_variant* target, tr_variant const* source)
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
std::string tr_variantToStr(tr_variant const* v, tr_variant_fmt fmt)
|
||||
{
|
||||
@@ -1105,9 +1107,7 @@ int tr_variantToFile(tr_variant const* v, tr_variant_fmt fmt, std::string_view f
|
||||
return error_code;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
///
|
||||
|
||||
bool tr_variantFromBuf(tr_variant* setme, int opts, std::string_view buf, char const** setme_end, tr_error** error)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user