refactor: tr_address_from_string is now std::string_view-friendly (#2176)

This commit is contained in:
Charles Kerr 2021-11-15 17:03:55 -06:00 committed by GitHub
parent 505d2ae428
commit da142f400e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 43 deletions

View File

@ -132,8 +132,8 @@ static tr_pex* listToPex(tr_variant* peerList, size_t* setme_len)
continue;
}
char const* ip = nullptr;
if (!tr_variantDictFindStr(peer, TR_KEY_ip, &ip, nullptr))
auto ip = std::string_view{};
if (!tr_variantDictFindStrView(peer, TR_KEY_ip, &ip))
{
continue;
}

View File

@ -20,6 +20,7 @@
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include <array>
#include <cerrno>
#include <climits>
#include <cstring>
@ -108,20 +109,35 @@ char const* tr_address_to_string(tr_address const* addr)
bool tr_address_from_string(tr_address* dst, char const* src)
{
bool success = false;
if (evutil_inet_pton(AF_INET, src, &dst->addr) == 1)
{
dst->type = TR_AF_INET;
success = true;
}
else if (evutil_inet_pton(AF_INET6, src, &dst->addr) == 1)
{
dst->type = TR_AF_INET6;
success = true;
return true;
}
return success;
if (evutil_inet_pton(AF_INET6, src, &dst->addr) == 1)
{
dst->type = TR_AF_INET6;
return true;
}
return false;
}
bool tr_address_from_string(tr_address* dst, std::string_view src)
{
// inet_pton() requires zero-terminated strings,
// so make a zero-terminated copy here on the stack.
auto buf = std::array<char, 64>{};
if (std::size(src) >= std::size(buf))
{
// shouldn't ever be that large; malformed address
return false;
}
*std::copy(std::begin(src), std::end(src), std::begin(buf)) = '\0';
return tr_address_from_string(dst, std::data(buf));
}
/*

View File

@ -26,6 +26,8 @@
#error only libtransmission should #include this header.
#endif
#include <string_view>
#ifdef _WIN32
#include <inttypes.h>
#include <ws2tcpip.h>
@ -104,6 +106,8 @@ char const* tr_address_and_port_to_string(char* buf, size_t buflen, tr_address c
bool tr_address_from_string(tr_address* setme, char const* string);
bool tr_address_from_string(tr_address* dst, std::string_view src);
bool tr_address_from_sockaddr_storage(tr_address* setme, tr_port* port, struct sockaddr_storage const* src);
int tr_address_compare(tr_address const* a, tr_address const* b);

View File

@ -1694,14 +1694,11 @@ static void gotMetadataFromURL(
tr_free(data);
}
static bool isCurlURL(char const* filename)
static bool isCurlURL(std::string_view url)
{
if (filename == nullptr)
{
return false;
}
return strncmp(filename, "ftp://", 6) == 0 || strncmp(filename, "http://", 7) == 0 || strncmp(filename, "https://", 8) == 0;
auto constexpr Schemes = std::array<std::string_view, 4>{ "http"sv, "https"sv, "ftp"sv, "sftp"sv };
auto const parsed = tr_urlParse(url);
return parsed && std::find(std::begin(Schemes), std::end(Schemes), parsed->scheme) != std::end(Schemes);
}
static auto fileListFromList(tr_variant* list)
@ -1727,13 +1724,13 @@ static char const* torrentAdd(tr_session* session, tr_variant* args_in, tr_varia
{
TR_ASSERT(idle_data != nullptr);
char const* filename = nullptr;
(void)tr_variantDictFindStr(args_in, TR_KEY_filename, &filename, nullptr);
auto filename = std::string_view{};
(void)tr_variantDictFindStrView(args_in, TR_KEY_filename, &filename);
char const* metainfo_base64 = nullptr;
(void)tr_variantDictFindStr(args_in, TR_KEY_metainfo, &metainfo_base64, nullptr);
auto metainfo_base64 = std::string_view{};
(void)tr_variantDictFindStrView(args_in, TR_KEY_metainfo, &metainfo_base64);
if (filename == nullptr && metainfo_base64 == nullptr)
if (std::empty(filename) && std::empty(metainfo_base64))
{
return "no filename or metainfo specified";
}
@ -1805,38 +1802,38 @@ static char const* torrentAdd(tr_session* session, tr_variant* args_in, tr_varia
tr_ctorSetFilePriorities(ctor, std::data(files), std::size(files), TR_PRI_HIGH);
}
dbgmsg("torrentAdd: filename is \"%s\"", filename ? filename : " (null)");
dbgmsg("torrentAdd: filename is \"%" TR_PRIsv "\"", TR_PRIsv_ARG(filename));
if (isCurlURL(filename))
{
struct add_torrent_idle_data* d = tr_new0(struct add_torrent_idle_data, 1);
auto* const d = tr_new0(struct add_torrent_idle_data, 1);
d->data = idle_data;
d->ctor = ctor;
tr_webRunWithCookies(session, filename, cookies, gotMetadataFromURL, d);
}
else
{
char* fname = tr_strdup(filename);
if (fname == nullptr)
if (std::empty(filename))
{
auto len = size_t{};
auto* const metainfo = static_cast<char*>(tr_base64_decode_str(metainfo_base64, &len));
tr_ctorSetMetainfo(ctor, (uint8_t*)metainfo, len);
tr_free(metainfo);
}
else if (strncmp(fname, "magnet:?", 8) == 0)
{
tr_ctorSetMetainfoFromMagnetLink(ctor, fname);
std::string const metainfo = tr_base64_decode_str(metainfo_base64);
tr_ctorSetMetainfo(ctor, std::data(metainfo), std::size(metainfo));
}
else
{
tr_ctorSetMetainfoFromFile(ctor, fname);
// these two tr_ctorSet*() functions require zero-terminated strings
auto const filename_str = std::string{ filename };
if (tr_strvStartsWith(filename, "magnet:?"sv))
{
tr_ctorSetMetainfoFromMagnetLink(ctor, filename_str.c_str());
}
else
{
tr_ctorSetMetainfoFromFile(ctor, filename_str.c_str());
}
}
addTorrentImpl(idle_data, ctor);
tr_free(fname);
}
return nullptr;

View File

@ -941,8 +941,8 @@ static void sessionSetImpl(void* vdata)
free_incoming_peer_port(session);
if (!tr_variantDictFindStr(settings, TR_KEY_bind_address_ipv4, &strVal, nullptr) ||
!tr_address_from_string(&b.addr, strVal) || b.addr.type != TR_AF_INET)
if (!tr_variantDictFindStrView(settings, TR_KEY_bind_address_ipv4, &sv) || !tr_address_from_string(&b.addr, sv) ||
b.addr.type != TR_AF_INET)
{
b.addr = tr_inaddr_any;
}
@ -950,8 +950,8 @@ static void sessionSetImpl(void* vdata)
b.socket = TR_BAD_SOCKET;
session->bind_ipv4 = static_cast<struct tr_bindinfo*>(tr_memdup(&b, sizeof(struct tr_bindinfo)));
if (!tr_variantDictFindStr(settings, TR_KEY_bind_address_ipv6, &strVal, nullptr) ||
!tr_address_from_string(&b.addr, strVal) || b.addr.type != TR_AF_INET6)
if (!tr_variantDictFindStrView(settings, TR_KEY_bind_address_ipv6, &sv) || !tr_address_from_string(&b.addr, sv) ||
b.addr.type != TR_AF_INET6)
{
b.addr = tr_in6addr_any;
}