mirror of
https://github.com/transmission/transmission
synced 2025-03-04 02:28:03 +00:00
refactor: tr_loadFile() tr_saveFile() take a std::string_view filename arg (#2822)
* refactor: tr_saveFile takes a string_view * refactor: tr_saveFile, tr_loadFile take string_view filename
This commit is contained in:
parent
1051160b99
commit
977b2a1bab
15 changed files with 102 additions and 86 deletions
|
@ -210,7 +210,7 @@ bool tr_sys_path_is_same(char const* path1, char const* path2, struct tr_error**
|
|||
* when no longer needed), `nullptr` otherwise (with `error` set
|
||||
* accordingly).
|
||||
*/
|
||||
char* tr_sys_path_resolve(char const* path, struct tr_error** error);
|
||||
char* tr_sys_path_resolve(char const* path, struct tr_error** error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `basename()`.
|
||||
|
|
|
@ -250,7 +250,7 @@ static std::string getUserDirsFilename()
|
|||
static std::string getXdgEntryFromUserDirs(std::string_view key)
|
||||
{
|
||||
auto content = std::vector<char>{};
|
||||
if (!tr_loadFile(content, getUserDirsFilename()) && std::empty(content))
|
||||
if (!tr_loadFile(getUserDirsFilename(), content) && std::empty(content))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -675,7 +675,7 @@ static auto loadFromFile(tr_torrent* tor, tr_resume::fields_t fieldsToLoad, bool
|
|||
auto buf = std::vector<char>{};
|
||||
tr_error* error = nullptr;
|
||||
auto top = tr_variant{};
|
||||
if (!tr_loadFile(buf, filename, &error) ||
|
||||
if (!tr_loadFile(filename, buf, &error) ||
|
||||
!tr_variantFromBuf(
|
||||
&top,
|
||||
TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cerrno>
|
||||
#include <cstring> /* memcpy */
|
||||
#include <ctime>
|
||||
|
@ -43,6 +44,7 @@
|
|||
#include "session-id.h"
|
||||
#include "session.h"
|
||||
#include "tr-assert.h"
|
||||
#include "tr-strbuf.h"
|
||||
#include "trevent.h"
|
||||
#include "utils.h"
|
||||
#include "variant.h"
|
||||
|
@ -137,29 +139,24 @@ static void send_simple_response(struct evhttp_request* req, int code, char cons
|
|||
****
|
||||
***/
|
||||
|
||||
static char const* mimetype_guess(char const* path)
|
||||
static char const* mimetype_guess(std::string_view path)
|
||||
{
|
||||
struct
|
||||
{
|
||||
char const* suffix;
|
||||
char const* mime_type;
|
||||
} const types[] = {
|
||||
/* these are the ones we need for serving the web client's files... */
|
||||
{ "css", "text/css" },
|
||||
{ "gif", "image/gif" },
|
||||
{ "html", "text/html" },
|
||||
{ "ico", "image/vnd.microsoft.icon" },
|
||||
{ "js", "application/javascript" },
|
||||
{ "png", "image/png" },
|
||||
{ "svg", "image/svg+xml" },
|
||||
};
|
||||
char const* dot = strrchr(path, '.');
|
||||
// these are the ones we need for serving the web client's files...
|
||||
static auto constexpr Types = std::array<std::pair<std::string_view, char const*>, 7>{ {
|
||||
{ ".css"sv, "text/css" },
|
||||
{ ".gif"sv, "image/gif" },
|
||||
{ ".html"sv, "text/html" },
|
||||
{ ".ico"sv, "image/vnd.microsoft.icon" },
|
||||
{ ".js"sv, "application/javascript" },
|
||||
{ ".png"sv, "image/png" },
|
||||
{ ".svg"sv, "image/svg+xml" },
|
||||
} };
|
||||
|
||||
for (unsigned int i = 0; dot != nullptr && i < TR_N_ELEMENTS(types); ++i)
|
||||
for (auto const& [suffix, mime_type] : Types)
|
||||
{
|
||||
if (strcmp(dot + 1, types[i].suffix) == 0)
|
||||
if (tr_strvEndsWith(path, suffix))
|
||||
{
|
||||
return types[i].mime_type;
|
||||
return mime_type;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +219,7 @@ static void evbuffer_ref_cleanup_tr_free(void const* /*data*/, size_t /*datalen*
|
|||
tr_free(extra);
|
||||
}
|
||||
|
||||
static void serve_file(struct evhttp_request* req, tr_rpc_server* server, char const* filename)
|
||||
static void serve_file(struct evhttp_request* req, tr_rpc_server* server, std::string_view filename)
|
||||
{
|
||||
if (req->type != EVHTTP_REQ_GET)
|
||||
{
|
||||
|
@ -294,11 +291,8 @@ static void handle_web_client(struct evhttp_request* req, tr_rpc_server* server)
|
|||
}
|
||||
else
|
||||
{
|
||||
auto const filename = tr_strvJoin(
|
||||
webClientDir,
|
||||
TR_PATH_DELIMITER_STR,
|
||||
tr_str_is_empty(subpath) ? "index.html" : subpath);
|
||||
serve_file(req, server, filename.c_str());
|
||||
auto const filename = tr_pathbuf{ webClientDir, "/"sv, tr_str_is_empty(subpath) ? "index.html" : subpath };
|
||||
serve_file(req, server, filename.sv());
|
||||
}
|
||||
|
||||
tr_free(subpath);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "torrent.h"
|
||||
#include "tr-assert.h"
|
||||
#include "tr-macros.h"
|
||||
#include "tr-strbuf.h"
|
||||
#include "utils.h"
|
||||
#include "variant.h"
|
||||
#include "version.h"
|
||||
|
@ -1439,11 +1440,17 @@ static void onBlocklistFetched(tr_web::FetchResponse const& web_response)
|
|||
|
||||
// tr_blocklistSetContent needs a source file,
|
||||
// so save content into a tmpfile
|
||||
auto const filename = tr_strvJoin(tr_sessionGetConfigDir(session), "blocklist.tmp");
|
||||
auto const filename = tr_pathbuf{ session->config_dir, "/blocklist.tmp"sv };
|
||||
tr_error* error = nullptr;
|
||||
if (!tr_saveFile(filename, std::string_view{ std::data(content), std::size(content) }, &error))
|
||||
if (!tr_saveFile(filename.sv(), content, &error))
|
||||
{
|
||||
tr_snprintf(result, sizeof(result), _("Couldn't save file \"%1$s\": %2$s"), filename.c_str(), error->message);
|
||||
fmt::format_to_n(
|
||||
result,
|
||||
sizeof(result),
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename.sv()),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code));
|
||||
tr_error_clear(&error);
|
||||
tr_idle_function_done(data, result);
|
||||
return;
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "tr-assert.h"
|
||||
#include "tr-dht.h" /* tr_dhtUpkeep() */
|
||||
#include "tr-lpd.h"
|
||||
#include "tr-strbuf.h"
|
||||
#include "tr-udp.h"
|
||||
#include "tr-utp.h"
|
||||
#include "trevent.h"
|
||||
|
@ -2020,7 +2021,6 @@ static void sessionLoadTorrents(struct sessionLoadTorrentsData* const data)
|
|||
if (odir != TR_BAD_SYS_DIR)
|
||||
{
|
||||
auto const dirname_sv = std::string_view{ dirname };
|
||||
auto path = std::string{};
|
||||
|
||||
char const* name = nullptr;
|
||||
while ((name = tr_sys_dir_read_name(odir, nullptr)) != nullptr)
|
||||
|
@ -2030,12 +2030,12 @@ static void sessionLoadTorrents(struct sessionLoadTorrentsData* const data)
|
|||
continue;
|
||||
}
|
||||
|
||||
tr_buildBuf(path, dirname_sv, "/", name);
|
||||
auto const path = tr_pathbuf{ dirname_sv, "/"sv, name };
|
||||
|
||||
// is a magnet link?
|
||||
if (!tr_ctorSetMetainfoFromFile(data->ctor, path, nullptr))
|
||||
if (!tr_ctorSetMetainfoFromFile(data->ctor, std::string{ path.sv() }, nullptr))
|
||||
{
|
||||
if (auto buf = std::vector<char>{}; tr_loadFile(buf, path))
|
||||
if (auto buf = std::vector<char>{}; tr_loadFile(path.sv(), buf))
|
||||
{
|
||||
tr_ctorSetMetainfoFromMagnetLink(
|
||||
data->ctor,
|
||||
|
|
|
@ -74,7 +74,7 @@ bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, std::string const& filename, tr_e
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!tr_loadFile(ctor->contents, filename, error))
|
||||
if (!tr_loadFile(filename, ctor->contents, error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ bool tr_ctorSaveContents(tr_ctor const* ctor, std::string const& filename, tr_er
|
|||
return false;
|
||||
}
|
||||
|
||||
return tr_saveFile(filename, { std::data(ctor->contents), std::size(ctor->contents) }, error);
|
||||
return tr_saveFile(filename, ctor->contents, error);
|
||||
}
|
||||
|
||||
bool tr_ctorSaveMagnetContents(tr_torrent* tor, std::string const& filename, tr_error** error)
|
||||
|
|
|
@ -493,8 +493,7 @@ bool tr_torrent_metainfo::parseTorrentFile(std::string_view filename, std::vecto
|
|||
contents = &local_contents;
|
||||
}
|
||||
|
||||
auto const sz_filename = std::string{ filename };
|
||||
return tr_loadFile(*contents, sz_filename, error) && parseBenc({ std::data(*contents), std::size(*contents) }, error);
|
||||
return tr_loadFile(filename, *contents, error) && parseBenc({ std::data(*contents), std::size(*contents) }, error);
|
||||
}
|
||||
|
||||
tr_sha1_digest_t const& tr_torrent_metainfo::pieceHash(tr_piece_index_t piece) const
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "net.h" // ntohl()
|
||||
#include "platform-quota.h" /* tr_device_info_create(), tr_device_info_get_disk_space(), tr_device_info_free() */
|
||||
#include "tr-assert.h"
|
||||
#include "tr-strbuf.h"
|
||||
#include "utils.h"
|
||||
#include "variant.h"
|
||||
|
||||
|
@ -226,16 +227,18 @@ void tr_timerAddMsec(struct event* timer, int msec)
|
|||
***
|
||||
**/
|
||||
|
||||
uint8_t* tr_loadFile(char const* path, size_t* size, tr_error** error)
|
||||
uint8_t* tr_loadFile(std::string_view path_in, size_t* size, tr_error** error)
|
||||
{
|
||||
auto const path = tr_pathbuf{ path_in };
|
||||
|
||||
/* 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))
|
||||
if (!tr_sys_path_get_info(path.c_str(), 0, &info, &my_error))
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("path", path.sv()),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_error_propagate(error, &my_error);
|
||||
|
@ -244,7 +247,7 @@ uint8_t* tr_loadFile(char const* path, size_t* size, tr_error** error)
|
|||
|
||||
if (info.type != TR_SYS_PATH_IS_FILE)
|
||||
{
|
||||
tr_logAddError(fmt::format(_("Couldn't read '{path}': Not a regular file"), fmt::arg("path", path)));
|
||||
tr_logAddError(fmt::format(_("Couldn't read '{path}': Not a regular file"), fmt::arg("path", path.sv())));
|
||||
tr_error_set(error, TR_ERROR_EISDIR, "Not a regular file"sv);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -256,12 +259,12 @@ uint8_t* tr_loadFile(char const* path, size_t* size, tr_error** error)
|
|||
}
|
||||
|
||||
/* Load the torrent file into our buffer */
|
||||
auto const fd = tr_sys_file_open(path, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, &my_error);
|
||||
auto const fd = tr_sys_file_open(path.c_str(), TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, &my_error);
|
||||
if (fd == TR_BAD_SYS_FILE)
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("path", path.sv()),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_error_propagate(error, &my_error);
|
||||
|
@ -273,7 +276,7 @@ uint8_t* tr_loadFile(char const* path, size_t* size, tr_error** error)
|
|||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("path", path.sv()),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_sys_file_close(fd, nullptr);
|
||||
|
@ -288,18 +291,18 @@ uint8_t* tr_loadFile(char const* path, size_t* size, tr_error** error)
|
|||
return buf;
|
||||
}
|
||||
|
||||
bool tr_loadFile(std::vector<char>& setme, std::string const& path, tr_error** error)
|
||||
bool tr_loadFile(std::string_view path_in, std::vector<char>& setme, tr_error** error)
|
||||
{
|
||||
auto const* const path_sz = path.c_str();
|
||||
auto const path = tr_pathbuf{ path_in };
|
||||
|
||||
/* try to stat the file */
|
||||
auto info = tr_sys_path_info{};
|
||||
tr_error* my_error = nullptr;
|
||||
if (!tr_sys_path_get_info(path_sz, 0, &info, &my_error))
|
||||
if (!tr_sys_path_get_info(path.c_str(), 0, &info, &my_error))
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("path", path.sv()),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_error_propagate(error, &my_error);
|
||||
|
@ -308,18 +311,18 @@ bool tr_loadFile(std::vector<char>& setme, std::string const& path, tr_error** e
|
|||
|
||||
if (info.type != TR_SYS_PATH_IS_FILE)
|
||||
{
|
||||
tr_logAddError(fmt::format(_("Couldn't read '{path}': Not a regular file"), fmt::arg("path", path)));
|
||||
tr_logAddError(fmt::format(_("Couldn't read '{path}': Not a regular file"), fmt::arg("path", path.sv())));
|
||||
tr_error_set(error, TR_ERROR_EISDIR, "Not a regular file"sv);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Load the torrent file into our buffer */
|
||||
auto const fd = tr_sys_file_open(path_sz, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, &my_error);
|
||||
auto const fd = tr_sys_file_open(path.c_str(), TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, &my_error);
|
||||
if (fd == TR_BAD_SYS_FILE)
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("path", path.sv()),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_error_propagate(error, &my_error);
|
||||
|
@ -331,7 +334,7 @@ bool tr_loadFile(std::vector<char>& setme, std::string const& path, tr_error** e
|
|||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("path", path.sv()),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_sys_file_close(fd, nullptr);
|
||||
|
@ -343,24 +346,26 @@ bool tr_loadFile(std::vector<char>& setme, std::string const& path, tr_error** e
|
|||
return true;
|
||||
}
|
||||
|
||||
bool tr_saveFile(std::string const& filename, std::string_view contents, tr_error** error)
|
||||
bool tr_saveFile(std::string_view filename_in, std::string_view contents, tr_error** error)
|
||||
{
|
||||
auto const filename = tr_pathbuf{ filename_in };
|
||||
// follow symlinks to find the "real" file, to make sure the temporary
|
||||
// we build with tr_sys_file_open_temp() is created on the right partition
|
||||
if (char* const real_filename_c_str = tr_sys_path_resolve(filename.c_str(), nullptr); real_filename_c_str != nullptr)
|
||||
if (char* const real_filename = tr_sys_path_resolve(filename.c_str()); real_filename != nullptr)
|
||||
{
|
||||
auto const real_filename = std::string{ real_filename_c_str };
|
||||
tr_free(real_filename_c_str);
|
||||
|
||||
if (real_filename != filename)
|
||||
if (filename_in != real_filename)
|
||||
{
|
||||
return tr_saveFile(real_filename, contents, error);
|
||||
auto const saved = tr_saveFile(real_filename, contents, error);
|
||||
tr_free(real_filename);
|
||||
return saved;
|
||||
}
|
||||
|
||||
tr_free(real_filename);
|
||||
}
|
||||
|
||||
// Write it to a temp file first.
|
||||
// This is a safeguard against edge cases, e.g. disk full, crash while writing, etc.
|
||||
auto tmp = tr_strvJoin(filename, ".tmp.XXXXXX"sv);
|
||||
auto tmp = tr_pathbuf{ filename.sv(), ".tmp.XXXXXX"sv };
|
||||
auto const fd = tr_sys_file_open_temp(std::data(tmp), error);
|
||||
if (fd == TR_BAD_SYS_FILE)
|
||||
{
|
||||
|
@ -386,7 +391,7 @@ bool tr_saveFile(std::string const& filename, std::string_view contents, tr_erro
|
|||
return false;
|
||||
}
|
||||
|
||||
tr_logAddTrace(fmt::format("Saved '{}'", filename));
|
||||
tr_logAddTrace(fmt::format("Saved '{}'", filename.sv()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,11 +79,17 @@ bool tr_wildmat(char const* text, char const* pattern) TR_GNUC_NONNULL(1, 2);
|
|||
* @brief Loads a file and returns its contents.
|
||||
* On failure, NULL is returned and errno is set.
|
||||
*/
|
||||
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(std::string_view filename, size_t* size, struct tr_error** error) TR_GNUC_MALLOC;
|
||||
|
||||
bool tr_loadFile(std::vector<char>& setme, std::string const& filename, tr_error** error = nullptr);
|
||||
bool tr_loadFile(std::string_view filename, std::vector<char>& contents, tr_error** error = nullptr);
|
||||
|
||||
bool tr_saveFile(std::string const& filename, std::string_view contents, tr_error** error = nullptr);
|
||||
bool tr_saveFile(std::string_view filename, std::string_view contents, tr_error** error = nullptr);
|
||||
|
||||
template<typename ContiguousRange>
|
||||
constexpr auto tr_saveFile(std::string_view filename, ContiguousRange const& x, tr_error** error = nullptr)
|
||||
{
|
||||
return tr_saveFile(filename, std::string_view{ std::data(x), std::size(x) }, error);
|
||||
}
|
||||
|
||||
template<typename... T, typename std::enable_if_t<(std::is_convertible_v<T, std::string_view> && ...), bool> = true>
|
||||
std::string& tr_buildBuf(std::string& setme, T... args)
|
||||
|
|
|
@ -1212,7 +1212,7 @@ int tr_variantToFile(tr_variant const* v, tr_variant_fmt fmt, std::string const&
|
|||
auto const contents = tr_variantToStr(v, fmt);
|
||||
|
||||
tr_error* error = nullptr;
|
||||
tr_saveFile(filename, { std::data(contents), std::size(contents) }, &error);
|
||||
tr_saveFile(filename, contents, &error);
|
||||
if (error != nullptr)
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
|
@ -1268,7 +1268,7 @@ bool tr_variantFromFile(tr_variant* setme, tr_variant_parse_opts opts, std::stri
|
|||
TR_ASSERT((opts & TR_VARIANT_PARSE_INPLACE) == 0);
|
||||
|
||||
auto buf = std::vector<char>{};
|
||||
if (!tr_loadFile(buf, filename, error))
|
||||
if (!tr_loadFile(filename, buf, error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "announce-list.h"
|
||||
#include "error.h"
|
||||
#include "torrent-metainfo.h"
|
||||
#include "tr-strbuf.h"
|
||||
#include "utils.h"
|
||||
#include "variant.h"
|
||||
|
||||
|
@ -343,11 +344,11 @@ TEST_F(AnnounceListTest, save)
|
|||
// first, set up a scratch torrent
|
||||
auto constexpr* const OriginalFile = LIBTRANSMISSION_TEST_ASSETS_DIR "/Android-x86 8.1 r6 iso.torrent";
|
||||
auto original_content = std::vector<char>{};
|
||||
auto const test_file = tr_strvJoin(::testing::TempDir(), "transmission-announce-list-test.torrent"sv);
|
||||
auto const test_file = tr_pathbuf{ ::testing::TempDir(), "transmission-announce-list-test.torrent"sv };
|
||||
tr_error* error = nullptr;
|
||||
EXPECT_TRUE(tr_loadFile(original_content, OriginalFile, &error));
|
||||
EXPECT_TRUE(tr_loadFile(OriginalFile, original_content, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_TRUE(tr_saveFile(test_file, { std::data(original_content), std::size(original_content) }, &error));
|
||||
EXPECT_TRUE(tr_saveFile(test_file.sv(), original_content, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
|
||||
// make an announce_list for it
|
||||
|
@ -363,7 +364,7 @@ TEST_F(AnnounceListTest, save)
|
|||
tr_error_clear(&error);
|
||||
|
||||
// now save to a real torrent file
|
||||
EXPECT_TRUE(announce_list.save(test_file, &error));
|
||||
EXPECT_TRUE(announce_list.save(std::string{ test_file.sv() }, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
|
||||
// load the original
|
||||
|
@ -372,7 +373,7 @@ TEST_F(AnnounceListTest, save)
|
|||
|
||||
// load the scratch that we saved to
|
||||
auto modified_tm = tr_torrent_metainfo{};
|
||||
EXPECT_TRUE(modified_tm.parseTorrentFile(test_file));
|
||||
EXPECT_TRUE(modified_tm.parseTorrentFile(test_file.sv()));
|
||||
|
||||
// test that non-announce parts of the metainfo are the same
|
||||
EXPECT_EQ(original_tm.name(), modified_tm.name());
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "error.h"
|
||||
#include "torrent-metainfo.h"
|
||||
#include "torrent.h"
|
||||
#include "tr-strbuf.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "test-fixtures.h"
|
||||
|
@ -159,13 +160,13 @@ TEST_F(TorrentMetainfoTest, AndroidTorrent)
|
|||
|
||||
TEST_F(TorrentMetainfoTest, ctorSaveContents)
|
||||
{
|
||||
auto const src_filename = tr_strvJoin(LIBTRANSMISSION_TEST_ASSETS_DIR, "/Android-x86 8.1 r6 iso.torrent"sv);
|
||||
auto const tgt_filename = tr_strvJoin(::testing::TempDir(), "save-contents-test.torrent");
|
||||
auto const src_filename = tr_pathbuf{ LIBTRANSMISSION_TEST_ASSETS_DIR, "/Android-x86 8.1 r6 iso.torrent"sv };
|
||||
auto const tgt_filename = tr_pathbuf{ ::testing::TempDir(), "save-contents-test.torrent" };
|
||||
|
||||
// try saving without passing any metainfo.
|
||||
auto* ctor = tr_ctorNew(session_);
|
||||
tr_error* error = nullptr;
|
||||
EXPECT_FALSE(tr_ctorSaveContents(ctor, tgt_filename, &error));
|
||||
EXPECT_FALSE(tr_ctorSaveContents(ctor, tgt_filename.c_str(), &error));
|
||||
EXPECT_NE(nullptr, error);
|
||||
if (error != nullptr)
|
||||
{
|
||||
|
@ -176,14 +177,14 @@ TEST_F(TorrentMetainfoTest, ctorSaveContents)
|
|||
// now try saving _with_ metainfo
|
||||
EXPECT_TRUE(tr_ctorSetMetainfoFromFile(ctor, src_filename.c_str(), &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_TRUE(tr_ctorSaveContents(ctor, tgt_filename, &error));
|
||||
EXPECT_TRUE(tr_ctorSaveContents(ctor, tgt_filename.c_str(), &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
|
||||
// the saved contents should match the source file's contents
|
||||
auto src_contents = std::vector<char>{};
|
||||
EXPECT_TRUE(tr_loadFile(src_contents, src_filename, &error));
|
||||
EXPECT_TRUE(tr_loadFile(src_filename.sv(), src_contents, &error));
|
||||
auto tgt_contents = std::vector<char>{};
|
||||
EXPECT_TRUE(tr_loadFile(tgt_contents, tgt_filename, &error));
|
||||
EXPECT_TRUE(tr_loadFile(tgt_filename.sv(), tgt_contents, &error));
|
||||
EXPECT_EQ(src_contents, tgt_contents);
|
||||
|
||||
// cleanup
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "crypto-utils.h" // tr_rand_int_weak()
|
||||
#include "platform.h"
|
||||
#include "ptrarray.h"
|
||||
#include "tr-strbuf.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "test-fixtures.h"
|
||||
|
@ -461,16 +462,18 @@ TEST_F(UtilsTest, mimeTypes)
|
|||
|
||||
TEST_F(UtilsTest, saveFile)
|
||||
{
|
||||
auto filename = tr_pathbuf{};
|
||||
|
||||
// save a file to GoogleTest's temp dir
|
||||
auto filename = tr_strvJoin(::testing::TempDir(), "filename.txt");
|
||||
filename.assign(::testing::TempDir(), "filename.txt"sv);
|
||||
auto contents = "these are the contents"sv;
|
||||
tr_error* error = nullptr;
|
||||
EXPECT_TRUE(tr_saveFile(filename, contents, &error));
|
||||
EXPECT_TRUE(tr_saveFile(filename.sv(), contents, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
|
||||
// now read the file back in and confirm the contents are the same
|
||||
auto buf = std::vector<char>{};
|
||||
EXPECT_TRUE(tr_loadFile(buf, filename, &error));
|
||||
EXPECT_TRUE(tr_loadFile(filename.sv(), buf, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
auto sv = std::string_view{ std::data(buf), std::size(buf) };
|
||||
EXPECT_EQ(contents, sv);
|
||||
|
@ -481,7 +484,7 @@ TEST_F(UtilsTest, saveFile)
|
|||
|
||||
// try saving a file to a path that doesn't exist
|
||||
filename = "/this/path/does/not/exist/foo.txt";
|
||||
EXPECT_FALSE(tr_saveFile(filename, contents, &error));
|
||||
EXPECT_FALSE(tr_saveFile(filename.sv(), contents, &error));
|
||||
ASSERT_NE(nullptr, error);
|
||||
EXPECT_NE(0, error->code);
|
||||
tr_error_clear(&error);
|
||||
|
|
|
@ -552,10 +552,10 @@ static char* netrc = nullptr;
|
|||
static char* session_id = nullptr;
|
||||
static bool UseSSL = false;
|
||||
|
||||
static std::string getEncodedMetainfo(char const* filename)
|
||||
static std::string getEncodedMetainfo(std::string_view filename)
|
||||
{
|
||||
auto contents = std::vector<char>{};
|
||||
if (tr_loadFile(contents, filename))
|
||||
if (tr_loadFile(filename, contents))
|
||||
{
|
||||
return tr_base64_encode({ std::data(contents), std::size(contents) });
|
||||
}
|
||||
|
@ -2386,7 +2386,7 @@ static int processArgs(char const* rpcurl, int argc, char const* const* argv)
|
|||
if (tadd != nullptr)
|
||||
{
|
||||
tr_variant* args = tr_variantDictFind(tadd, Arguments);
|
||||
std::string const tmp = getEncodedMetainfo(optarg);
|
||||
auto const tmp = getEncodedMetainfo(optarg);
|
||||
|
||||
if (!std::empty(tmp))
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue