refactor: add a tr_loadFile() variant that takes a reusable buffer (#2181)
This commit is contained in:
parent
73edd7b642
commit
7344b7e3cb
|
@ -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;
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue