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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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> high;
std::vector<char> contents;
explicit tr_ctor(tr_session const* 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)
{
auto len = size_t{};
auto* const metainfo = tr_loadFile(filename, &len, nullptr);
auto err = int{};
if (metainfo != nullptr && len != 0)
{
err = tr_ctorSetMetainfo(ctor, metainfo, len);
}
else
if (!tr_loadFile(ctor->contents, filename, nullptr) || std::empty(ctor->contents))
{
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);
/* 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) &&
!tr_variantDictFindStrView(info, TR_KEY_name, &name))
if (std::empty(name))
{
char* base = tr_sys_path_basename(filename, nullptr);
if (base != nullptr)
{
name = ""sv;
}
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_variantDictAddStr(info, TR_KEY_name, base);
tr_free(base);
}
}
}
tr_free(metainfo);
return err;
return 0;
}
/***

View File

@ -336,6 +336,49 @@ uint8_t* tr_loadFile(char const* path, size_t* size, tr_error** error)
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, ...)
{

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);
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
platform's correct directory separator. */
char* tr_buildPath(char const* first_element, ...) TR_GNUC_NULL_TERMINATED TR_GNUC_MALLOC;