diff --git a/libtransmission/rpcimpl.cc b/libtransmission/rpcimpl.cc index 5a3eef665..50e9debd1 100644 --- a/libtransmission/rpcimpl.cc +++ b/libtransmission/rpcimpl.cc @@ -119,7 +119,7 @@ static auto getTorrents(tr_session* session, tr_variant* args) auto torrents = std::vector{}; auto id = int64_t{}; - char const* str = nullptr; + auto sv = std::string_view{}; tr_variant* ids = nullptr; if (tr_variantDictFindList(args, TR_KEY_ids, &ids)) @@ -136,9 +136,9 @@ static auto getTorrents(tr_session* session, tr_variant* args) { tor = tr_torrentFindFromId(session, id); } - else if (tr_variantGetStr(node, &str, nullptr)) + else if (tr_variantGetStrView(node, &sv)) { - tor = tr_torrentFindFromHashString(session, str); + tor = tr_torrentFindFromHashString(session, sv); } if (tor != nullptr) @@ -150,15 +150,14 @@ static auto getTorrents(tr_session* session, tr_variant* args) else if (tr_variantDictFindInt(args, TR_KEY_ids, &id) || tr_variantDictFindInt(args, TR_KEY_id, &id)) { tr_torrent* const tor = tr_torrentFindFromId(session, id); - if (tor != nullptr) { torrents.push_back(tor); } } - else if (tr_variantDictFindStr(args, TR_KEY_ids, &str, nullptr)) + else if (tr_variantDictFindStrView(args, TR_KEY_ids, &sv)) { - if (strcmp(str, "recently-active") == 0) + if (sv == "recently-active"sv) { time_t const cutoff = tr_time() - RECENTLY_ACTIVE_SECONDS; @@ -171,8 +170,7 @@ static auto getTorrents(tr_session* session, tr_variant* args) } else { - tr_torrent* const tor = tr_torrentFindFromHashString(session, str); - + tr_torrent* const tor = tr_torrentFindFromHashString(session, sv); if (tor != nullptr) { torrents.push_back(tor); diff --git a/libtransmission/session.h b/libtransmission/session.h index e2f41e881..8ca7d1596 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -101,11 +102,30 @@ struct CompareHash } }; -struct CompareHashString +struct CaseInsensitiveStringCompare // case-insensitive string compare { - bool operator()(char const* const a, char const* const b) const + int compare(std::string_view a, std::string_view b) const // <=> { - return evutil_ascii_strcasecmp(a, b) < 0; + auto const alen = std::size(a); + auto const blen = std::size(b); + + auto i = evutil_ascii_strncasecmp(std::data(a), std::data(b), std::min(alen, blen)); + if (i != 0) + { + return i; + } + + if (alen != blen) + { + return alen < blen ? -1 : 1; + } + + return 0; + } + + bool operator()(std::string_view a, std::string_view b) const // less than + { + return compare(a, b) < 0; } }; @@ -194,7 +214,7 @@ struct tr_session std::unordered_set torrents; std::map torrentsById; std::map torrentsByHash; - std::map torrentsByHashString; + std::map torrentsByHashString; std::array scripts; diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index c64725ad0..88b6d07e6 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -86,10 +86,10 @@ tr_torrent* tr_torrentFindFromId(tr_session* session, int id) return it == std::end(src) ? nullptr : it->second; } -tr_torrent* tr_torrentFindFromHashString(tr_session* session, char const* hashstr) +tr_torrent* tr_torrentFindFromHashString(tr_session* session, std::string_view hash_string) { auto& src = session->torrentsByHashString; - auto it = src.find(hashstr); + auto it = src.find(hash_string); return it == std::end(src) ? nullptr : it->second; } diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index bf82e0226..5b1e507b2 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -64,7 +64,7 @@ void tr_torrentSetHasPiece(tr_torrent* tor, tr_piece_index_t pieceIndex, bool ha void tr_torrentChangeMyPort(tr_torrent* session); -tr_torrent* tr_torrentFindFromHashString(tr_session* session, char const* hashString); +tr_torrent* tr_torrentFindFromHashString(tr_session* session, std::string_view hash_string); tr_torrent* tr_torrentFindFromObfuscatedHash(tr_session* session, uint8_t const* hash);