1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-26 09:37:56 +00:00

refactor: add tr_buildTorrentFilename() (#2196)

a simpler API for building .torrent and .resume filenames
This commit is contained in:
Charles Kerr 2021-11-19 18:36:25 -06:00 committed by GitHub
parent 073c6af1d6
commit f7b729a350
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 101 deletions

View file

@ -34,69 +34,20 @@ using namespace std::literals;
****
***/
#ifdef _WIN32
auto constexpr PATH_DELIMITER_CHARS = std::array<char, 2>{ '/', '\\' };
#else
auto constexpr PATH_DELIMITER_CHARS = std::array<char, 1>{ '/' };
#endif
static constexpr bool char_is_path_separator(char c)
std::string tr_buildTorrentFilename(
std::string_view dirname,
tr_info const* inf,
enum tr_metainfo_basename_format format,
std::string_view suffix)
{
for (auto ch : PATH_DELIMITER_CHARS)
{
if (c == ch)
{
return true;
}
}
return false;
return format == TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH ?
tr_strvJoin(dirname, "/"sv, inf->name, "."sv, std::string_view{ inf->hashString, 16 }, suffix) :
tr_strvJoin(dirname, "/"sv, inf->hashString, suffix);
}
static char* metainfoGetBasenameNameAndPartialHash(tr_info const* inf)
static std::string getTorrentFilename(tr_session const* session, tr_info const* inf, enum tr_metainfo_basename_format format)
{
char const* name = inf->originalName;
size_t const name_len = strlen(name);
char* ret = tr_strdup_printf("%s.%16.16s", name, inf->hashString);
for (size_t i = 0; i < name_len; ++i)
{
if (char_is_path_separator(ret[i]))
{
ret[i] = '_';
}
}
return ret;
}
static char* metainfoGetBasenameHashOnly(tr_info const* inf)
{
return tr_strdup(inf->hashString);
}
char* tr_metainfoGetBasename(tr_info const* inf, enum tr_metainfo_basename_format format)
{
switch (format)
{
case TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH:
return metainfoGetBasenameNameAndPartialHash(inf);
case TR_METAINFO_BASENAME_HASH:
return metainfoGetBasenameHashOnly(inf);
default:
TR_ASSERT_MSG(false, "unknown metainfo basename format %d", (int)format);
return nullptr;
}
}
static char* getTorrentFilename(tr_session const* session, tr_info const* inf, enum tr_metainfo_basename_format format)
{
char* base = tr_metainfoGetBasename(inf, format);
char* filename = tr_strdup_printf("%s" TR_PATH_DELIMITER_STR "%s.torrent", tr_getTorrentDir(session), base);
tr_free(base);
return filename;
return tr_buildTorrentFilename(tr_getTorrentDir(session), inf, format, ".torrent"sv);
}
/***
@ -665,7 +616,7 @@ static char const* tr_metainfoParseImpl(
/* filename of Transmission's copy */
tr_free(inf->torrent);
inf->torrent = session != nullptr ? getTorrentFilename(session, inf, TR_METAINFO_BASENAME_HASH) : nullptr;
inf->torrent = session != nullptr ? tr_strvDup(getTorrentFilename(session, inf, TR_METAINFO_BASENAME_HASH)) : nullptr;
return nullptr;
}
@ -719,13 +670,11 @@ void tr_metainfoFree(tr_info* inf)
void tr_metainfoRemoveSaved(tr_session const* session, tr_info const* inf)
{
char* filename = getTorrentFilename(session, inf, TR_METAINFO_BASENAME_HASH);
tr_sys_path_remove(filename, nullptr);
tr_free(filename);
auto filename = getTorrentFilename(session, inf, TR_METAINFO_BASENAME_HASH);
tr_sys_path_remove(filename.c_str(), nullptr);
filename = getTorrentFilename(session, inf, TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH);
tr_sys_path_remove(filename, nullptr);
tr_free(filename);
tr_sys_path_remove(filename.c_str(), nullptr);
}
void tr_metainfoMigrateFile(
@ -734,14 +683,15 @@ void tr_metainfoMigrateFile(
enum tr_metainfo_basename_format old_format,
enum tr_metainfo_basename_format new_format)
{
char* old_filename = getTorrentFilename(session, info, old_format);
char* new_filename = getTorrentFilename(session, info, new_format);
auto const old_filename = getTorrentFilename(session, info, old_format);
auto const new_filename = getTorrentFilename(session, info, new_format);
if (tr_sys_path_rename(old_filename, new_filename, nullptr))
if (tr_sys_path_rename(old_filename.c_str(), new_filename.c_str(), nullptr))
{
tr_logAddNamedError(info->name, "Migrated torrent file from \"%s\" to \"%s\"", old_filename, new_filename);
tr_logAddNamedError(
info->name,
"Migrated torrent file from \"%s\" to \"%s\"",
old_filename.c_str(),
new_filename.c_str());
}
tr_free(new_filename);
tr_free(old_filename);
}

View file

@ -58,7 +58,11 @@ std::optional<tr_metainfo_parsed> tr_metainfoParse(tr_session const* session, tr
void tr_metainfoRemoveSaved(tr_session const* session, tr_info const* info);
char* tr_metainfoGetBasename(tr_info const*, enum tr_metainfo_basename_format format);
std::string tr_buildTorrentFilename(
std::string_view dirname,
tr_info const* inf,
enum tr_metainfo_basename_format format,
std::string_view suffix);
void tr_metainfoMigrateFile(
tr_session const* session,

View file

@ -35,12 +35,9 @@ constexpr int MAX_REMEMBERED_PEERS = 200;
} // unnamed namespace
static char* getResumeFilename(tr_torrent const* tor, enum tr_metainfo_basename_format format)
static std::string getResumeFilename(tr_torrent const* tor, enum tr_metainfo_basename_format format)
{
char* base = tr_metainfoGetBasename(tr_torrentInfo(tor), format);
char* filename = tr_strdup_printf("%s" TR_PATH_DELIMITER_STR "%s.resume", tr_getResumeDir(tor->session), base);
tr_free(base);
return filename;
return tr_buildTorrentFilename(tr_getResumeDir(tor->session), tr_torrentInfo(tor), format, ".resume"sv);
}
/***
@ -719,13 +716,12 @@ void tr_torrentSaveResume(tr_torrent* tor)
saveName(&top, tor);
saveLabels(&top, tor);
char* const filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH);
int const err = tr_variantToFile(&top, TR_VARIANT_FMT_BENC, filename);
std::string const filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH);
int const err = tr_variantToFile(&top, TR_VARIANT_FMT_BENC, filename.c_str());
if (err != 0)
{
tr_torrentSetLocalError(tor, "Unable to save resume file: %s", tr_strerror(err));
}
tr_free(filename);
tr_variantFree(&top);
}
@ -747,9 +743,9 @@ static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad, bool* didRe
*didRenameToHashOnlyName = false;
}
char* const filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH);
std::string const filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH);
auto buf = std::vector<char>{};
if (!tr_loadFile(buf, filename, &error) ||
if (!tr_loadFile(buf, filename.c_str(), &error) ||
!tr_variantFromBuf(
&top,
TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE,
@ -757,35 +753,30 @@ static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad, bool* didRe
nullptr,
&error))
{
tr_logAddTorDbg(tor, "Couldn't read \"%s\": %s", filename, error->message);
tr_logAddTorDbg(tor, "Couldn't read \"%s\": %s", filename.c_str(), error->message);
tr_error_clear(&error);
char* old_filename = getResumeFilename(tor, TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH);
std::string const old_filename = getResumeFilename(tor, TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH);
if (!tr_variantFromFile(&top, TR_VARIANT_PARSE_BENC, old_filename, &error))
if (!tr_variantFromFile(&top, TR_VARIANT_PARSE_BENC, old_filename.c_str(), &error))
{
tr_logAddTorDbg(tor, "Couldn't read \"%s\" either: %s", old_filename, error->message);
tr_logAddTorDbg(tor, "Couldn't read \"%s\" either: %s", old_filename.c_str(), error->message);
tr_error_free(error);
tr_free(old_filename);
tr_free(filename);
return fieldsLoaded;
}
if (tr_sys_path_rename(old_filename, filename, nullptr))
if (tr_sys_path_rename(old_filename.c_str(), filename.c_str(), nullptr))
{
tr_logAddTorDbg(tor, "Migrated resume file from \"%s\" to \"%s\"", old_filename, filename);
tr_logAddTorDbg(tor, "Migrated resume file from \"%s\" to \"%s\"", old_filename.c_str(), filename.c_str());
if (didRenameToHashOnlyName != nullptr)
{
*didRenameToHashOnlyName = true;
}
}
tr_free(old_filename);
}
tr_logAddTorDbg(tor, "Read resume file \"%s\"", filename);
tr_logAddTorDbg(tor, "Read resume file \"%s\"", filename.c_str());
if ((fieldsToLoad & TR_FR_CORRUPT) != 0 && tr_variantDictFindInt(&top, TR_KEY_corrupt, &i))
{
@ -943,7 +934,6 @@ static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad, bool* didRe
tor->isDirty = wasDirty;
tr_variantFree(&top);
tr_free(filename);
return fieldsLoaded;
}
@ -1007,11 +997,9 @@ uint64_t tr_torrentLoadResume(tr_torrent* tor, uint64_t fieldsToLoad, tr_ctor co
void tr_torrentRemoveResume(tr_torrent const* tor)
{
char* filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH);
tr_sys_path_remove(filename, nullptr);
tr_free(filename);
std::string filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH);
tr_sys_path_remove(filename.c_str(), nullptr);
filename = getResumeFilename(tor, TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH);
tr_sys_path_remove(filename, nullptr);
tr_free(filename);
tr_sys_path_remove(filename.c_str(), nullptr);
}