refactor: add a tr_loadFile() variant that takes a reusable buffer (#2181)

This commit is contained in:
Charles Kerr
2021-11-16 00:15:13 -06:00
committed by GitHub
parent 73edd7b642
commit 7344b7e3cb
3 changed files with 71 additions and 30 deletions

View File

@@ -52,6 +52,8 @@ struct tr_ctor
std::vector<tr_file_index_t> normal; std::vector<tr_file_index_t> normal;
std::vector<tr_file_index_t> high; std::vector<tr_file_index_t> high;
std::vector<char> contents;
explicit tr_ctor(tr_session const* session_in) explicit tr_ctor(tr_session const* session_in)
: session{ session_in } : session{ session_in }
{ {
@@ -113,52 +115,46 @@ int tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, char const* magnet_link)
int tr_ctorSetMetainfoFromFile(tr_ctor* ctor, char const* filename) int tr_ctorSetMetainfoFromFile(tr_ctor* ctor, char const* filename)
{ {
auto len = size_t{}; if (!tr_loadFile(ctor->contents, filename, nullptr) || std::empty(ctor->contents))
auto* const metainfo = tr_loadFile(filename, &len, nullptr);
auto err = int{};
if (metainfo != nullptr && len != 0)
{
err = tr_ctorSetMetainfo(ctor, metainfo, len);
}
else
{ {
clearMetainfo(ctor); clearMetainfo(ctor);
err = 1; return EILSEQ;
}
int const err = tr_ctorSetMetainfo(ctor, std::data(ctor->contents), std::size(ctor->contents));
if (err)
{
clearMetainfo(ctor);
return err;
} }
setSourceFile(ctor, filename); setSourceFile(ctor, filename);
/* if no `name' field was set, then set it from the filename */ /* if no `name' field was set, then set it from the filename */
if (ctor->isSet_metainfo) tr_variant* info = nullptr;
if (tr_variantDictFindDict(&ctor->metainfo, TR_KEY_info, &info))
{ {
tr_variant* info = nullptr; auto name = std::string_view{};
if (tr_variantDictFindDict(&ctor->metainfo, TR_KEY_info, &info)) if (!tr_variantDictFindStrView(info, TR_KEY_name_utf_8, &name) && !tr_variantDictFindStrView(info, TR_KEY_name, &name))
{ {
auto name = std::string_view{}; name = ""sv;
}
if (!tr_variantDictFindStrView(info, TR_KEY_name_utf_8, &name) && if (std::empty(name))
!tr_variantDictFindStrView(info, TR_KEY_name, &name)) {
char* base = tr_sys_path_basename(filename, nullptr);
if (base != nullptr)
{ {
name = ""sv; tr_variantDictAddStr(info, TR_KEY_name, base);
} tr_free(base);
if (std::empty(name))
{
char* base = tr_sys_path_basename(filename, nullptr);
if (base != nullptr)
{
tr_variantDictAddStr(info, TR_KEY_name, base);
tr_free(base);
}
} }
} }
} }
tr_free(metainfo); return 0;
return err;
} }
/*** /***

View File

@@ -336,6 +336,49 @@ uint8_t* tr_loadFile(char const* path, size_t* size, tr_error** error)
return buf; return buf;
} }
bool tr_loadFile(std::vector<char>& setme, char const* path, tr_error** error)
{
char const* const err_fmt = _("Couldn't read \"%1$s\": %2$s");
/* try to stat the file */
auto info = tr_sys_path_info{};
tr_error* my_error = nullptr;
if (!tr_sys_path_get_info(path, 0, &info, &my_error))
{
tr_logAddDebug(err_fmt, path, my_error->message);
tr_error_propagate(error, &my_error);
return false;
}
if (info.type != TR_SYS_PATH_IS_FILE)
{
tr_logAddError(err_fmt, path, _("Not a regular file"));
tr_error_set_literal(error, TR_ERROR_EISDIR, _("Not a regular file"));
return false;
}
/* Load the torrent file into our buffer */
tr_sys_file_t const fd = tr_sys_file_open(path, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, &my_error);
if (fd == TR_BAD_SYS_FILE)
{
tr_logAddError(err_fmt, path, my_error->message);
tr_error_propagate(error, &my_error);
return false;
}
setme.resize(info.size);
if (!tr_sys_file_read(fd, std::data(setme), info.size, nullptr, &my_error))
{
tr_logAddError(err_fmt, path, my_error->message);
tr_sys_file_close(fd, nullptr);
tr_error_propagate(error, &my_error);
return false;
}
tr_sys_file_close(fd, nullptr);
return true;
}
char* tr_buildPath(char const* first_element, ...) char* tr_buildPath(char const* first_element, ...)
{ {

View File

@@ -79,6 +79,8 @@ bool tr_wildmat(char const* text, char const* pattern) TR_GNUC_NONNULL(1, 2);
*/ */
uint8_t* tr_loadFile(char const* filename, size_t* size, struct tr_error** error) TR_GNUC_MALLOC TR_GNUC_NONNULL(1); uint8_t* tr_loadFile(char const* filename, size_t* size, struct tr_error** error) TR_GNUC_MALLOC TR_GNUC_NONNULL(1);
bool tr_loadFile(std::vector<char>& setme, char const* filename, tr_error** error = nullptr);
/** @brief build a filename from a series of elements using the /** @brief build a filename from a series of elements using the
platform's correct directory separator. */ platform's correct directory separator. */
char* tr_buildPath(char const* first_element, ...) TR_GNUC_NULL_TERMINATED TR_GNUC_MALLOC; char* tr_buildPath(char const* first_element, ...) TR_GNUC_NULL_TERMINATED TR_GNUC_MALLOC;