mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
refactor: add a tr_loadFile() variant that takes a reusable buffer (#2181)
This commit is contained in:
@@ -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,33 +115,29 @@ 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))
|
||||
{
|
||||
auto name = std::string_view{};
|
||||
|
||||
if (!tr_variantDictFindStrView(info, TR_KEY_name_utf_8, &name) &&
|
||||
!tr_variantDictFindStrView(info, TR_KEY_name, &name))
|
||||
if (!tr_variantDictFindStrView(info, TR_KEY_name_utf_8, &name) && !tr_variantDictFindStrView(info, TR_KEY_name, &name))
|
||||
{
|
||||
name = ""sv;
|
||||
}
|
||||
@@ -155,10 +153,8 @@ int tr_ctorSetMetainfoFromFile(tr_ctor* ctor, char const* filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr_free(metainfo);
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
|
||||
@@ -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, ...)
|
||||
{
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user