diff --git a/libtransmission/file.h b/libtransmission/file.h index 4a9f5b3f7..d6fec3f5f 100644 --- a/libtransmission/file.h +++ b/libtransmission/file.h @@ -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()`. diff --git a/libtransmission/platform.cc b/libtransmission/platform.cc index f12ad252c..48f7afd69 100644 --- a/libtransmission/platform.cc +++ b/libtransmission/platform.cc @@ -250,7 +250,7 @@ static std::string getUserDirsFilename() static std::string getXdgEntryFromUserDirs(std::string_view key) { auto content = std::vector{}; - if (!tr_loadFile(content, getUserDirsFilename()) && std::empty(content)) + if (!tr_loadFile(getUserDirsFilename(), content) && std::empty(content)) { return {}; } diff --git a/libtransmission/resume.cc b/libtransmission/resume.cc index 01d9cfa04..d38428989 100644 --- a/libtransmission/resume.cc +++ b/libtransmission/resume.cc @@ -675,7 +675,7 @@ static auto loadFromFile(tr_torrent* tor, tr_resume::fields_t fieldsToLoad, bool auto buf = std::vector{}; 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, diff --git a/libtransmission/rpc-server.cc b/libtransmission/rpc-server.cc index 928f1349f..64b61e52d 100644 --- a/libtransmission/rpc-server.cc +++ b/libtransmission/rpc-server.cc @@ -4,6 +4,7 @@ // License text can be found in the licenses/ folder. #include +#include #include #include /* memcpy */ #include @@ -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, 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); diff --git a/libtransmission/rpcimpl.cc b/libtransmission/rpcimpl.cc index 9a968457e..42e03a484 100644 --- a/libtransmission/rpcimpl.cc +++ b/libtransmission/rpcimpl.cc @@ -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; diff --git a/libtransmission/session.cc b/libtransmission/session.cc index 24c6b67bc..c7b84882e 100644 --- a/libtransmission/session.cc +++ b/libtransmission/session.cc @@ -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{}; tr_loadFile(buf, path)) + if (auto buf = std::vector{}; tr_loadFile(path.sv(), buf)) { tr_ctorSetMetainfoFromMagnetLink( data->ctor, diff --git a/libtransmission/torrent-ctor.cc b/libtransmission/torrent-ctor.cc index e2c5b1436..e173e91e4 100644 --- a/libtransmission/torrent-ctor.cc +++ b/libtransmission/torrent-ctor.cc @@ -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) diff --git a/libtransmission/torrent-metainfo.cc b/libtransmission/torrent-metainfo.cc index de931aa29..9c597af98 100644 --- a/libtransmission/torrent-metainfo.cc +++ b/libtransmission/torrent-metainfo.cc @@ -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 diff --git a/libtransmission/utils.cc b/libtransmission/utils.cc index 37cd9c0c0..eb0918fcd 100644 --- a/libtransmission/utils.cc +++ b/libtransmission/utils.cc @@ -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& setme, std::string const& path, tr_error** error) +bool tr_loadFile(std::string_view path_in, std::vector& 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& 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& 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& 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; } diff --git a/libtransmission/utils.h b/libtransmission/utils.h index 845473797..a02e4ba7a 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -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& setme, std::string const& filename, tr_error** error = nullptr); +bool tr_loadFile(std::string_view filename, std::vector& 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 +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 && ...), bool> = true> std::string& tr_buildBuf(std::string& setme, T... args) diff --git a/libtransmission/variant.cc b/libtransmission/variant.cc index 74d5dd612..d38d3f1a1 100644 --- a/libtransmission/variant.cc +++ b/libtransmission/variant.cc @@ -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{}; - if (!tr_loadFile(buf, filename, error)) + if (!tr_loadFile(filename, buf, error)) { return false; } diff --git a/tests/libtransmission/announce-list-test.cc b/tests/libtransmission/announce-list-test.cc index bbc17ff3d..778b29d2f 100644 --- a/tests/libtransmission/announce-list-test.cc +++ b/tests/libtransmission/announce-list-test.cc @@ -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{}; - 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()); diff --git a/tests/libtransmission/torrent-metainfo-test.cc b/tests/libtransmission/torrent-metainfo-test.cc index e0e0f8b32..faea4a3c1 100644 --- a/tests/libtransmission/torrent-metainfo-test.cc +++ b/tests/libtransmission/torrent-metainfo-test.cc @@ -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{}; - EXPECT_TRUE(tr_loadFile(src_contents, src_filename, &error)); + EXPECT_TRUE(tr_loadFile(src_filename.sv(), src_contents, &error)); auto tgt_contents = std::vector{}; - 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 diff --git a/tests/libtransmission/utils-test.cc b/tests/libtransmission/utils-test.cc index 5ae975773..0d330de09 100644 --- a/tests/libtransmission/utils-test.cc +++ b/tests/libtransmission/utils-test.cc @@ -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{}; - 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); diff --git a/utils/remote.cc b/utils/remote.cc index 41e211879..b14d52f97 100644 --- a/utils/remote.cc +++ b/utils/remote.cc @@ -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{}; - 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)) {