refactor: remove unused pieces of str to variant (#2166)

* feat: add tr_variantInitStrView()

* refactor: remove unused function tr_variantFromJsonFull

* refactor: tr_variantFromJson() now takes a string_view

* refactor: tr_variantFromBenc() now takes a string_view

* refactor: remove unused source arg from tr_variantFromBencFull()

* refactor: make tr_variantFromBuf() private
This commit is contained in:
Charles Kerr 2021-11-15 01:21:57 -06:00 committed by GitHub
parent b1aeaa3dcc
commit 250a2e3cc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 184 additions and 160 deletions

View File

@ -219,7 +219,7 @@ static void on_announce_done(
else
{
tr_variant benc;
bool const variant_loaded = tr_variantFromBenc(&benc, msg, msglen) == 0;
bool const variant_loaded = tr_variantFromBenc(&benc, { static_cast<char const*>(msg), msglen }) == 0;
if (tr_env_key_exists("TR_CURL_VERBOSE"))
{
@ -392,7 +392,7 @@ static void on_scrape_done(
else
{
auto top = tr_variant{};
auto const variant_loaded = tr_variantFromBenc(&top, msg, msglen) == 0;
auto const variant_loaded = tr_variantFromBenc(&top, { static_cast<char const*>(msg), msglen }) == 0;
if (tr_env_key_exists("TR_CURL_VERBOSE"))
{

View File

@ -1119,12 +1119,12 @@ static void sendLtepHandshake(tr_peerMsgsImpl* msgs)
static void parseLtepHandshake(tr_peerMsgsImpl* msgs, uint32_t len, struct evbuffer* inbuf)
{
uint8_t* const tmp = tr_new(uint8_t, len);
auto* const tmp = tr_new(char, len);
tr_peerIoReadBytes(msgs->io, inbuf, tmp, len);
msgs->peerSentLtepHandshake = true;
auto val = tr_variant{};
if (tr_variantFromBenc(&val, tmp, len) != 0 || !tr_variantIsDict(&val))
if (tr_variantFromBenc(&val, { tmp, len }) != 0 || !tr_variantIsDict(&val))
{
dbgmsg(msgs, "GET extended-handshake, couldn't get dictionary");
tr_free(tmp);
@ -1234,14 +1234,14 @@ static void parseUtMetadata(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuf
int64_t msg_type = -1;
int64_t piece = -1;
int64_t total_size = 0;
uint8_t* const tmp = tr_new(uint8_t, msglen);
char* const tmp = tr_new(char, msglen);
tr_peerIoReadBytes(msgs->io, inbuf, tmp, msglen);
char const* const msg_end = (char const*)tmp + msglen;
auto dict = tr_variant{};
char const* benc_end = nullptr;
if (tr_variantFromBencFull(&dict, tmp, msglen, nullptr, &benc_end) == 0)
if (tr_variantFromBencFull(&dict, std::string_view{ tmp, msglen }, &benc_end) == 0)
{
(void)tr_variantDictFindInt(&dict, TR_KEY_msg_type, &msg_type);
(void)tr_variantDictFindInt(&dict, TR_KEY_piece, &piece);
@ -1306,11 +1306,11 @@ static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuffer*
return;
}
uint8_t* tmp = tr_new(uint8_t, msglen);
auto* tmp = tr_new(char, msglen);
tr_peerIoReadBytes(msgs->io, inbuf, tmp, msglen);
tr_variant val;
bool const loaded = tr_variantFromBenc(&val, tmp, msglen) == 0;
bool const loaded = tr_variantFromBenc(&val, std::string_view{ tmp, msglen }) == 0;
tr_free(tmp);

View File

@ -190,12 +190,12 @@ static void handle_upload(struct evhttp_request* req, tr_rpc_server* server)
auto test = tr_variant{};
auto have_source = bool{ false };
if (tr_urlIsValid({ body.c_str(), body_len }))
if (tr_urlIsValid(body))
{
tr_variantDictAddRaw(args, TR_KEY_filename, body.c_str(), body_len);
tr_variantDictAddStrView(args, TR_KEY_filename, body);
have_source = true;
}
else if (tr_variantFromBenc(&test, body.c_str(), body_len) == 0)
else if (tr_variantFromBenc(&test, body) == 0)
{
auto* b64 = static_cast<char*>(tr_base64_encode(body.c_str(), body_len, nullptr));
tr_variantDictAddStr(args, TR_KEY_metainfo, b64);
@ -449,10 +449,10 @@ static void rpc_response_func(tr_session* /*session*/, tr_variant* response, voi
tr_free(data);
}
static void handle_rpc_from_json(struct evhttp_request* req, tr_rpc_server* server, char const* json, size_t json_len)
static void handle_rpc_from_json(struct evhttp_request* req, tr_rpc_server* server, std::string_view json)
{
auto top = tr_variant{};
auto const have_content = tr_variantFromJson(&top, json, json_len) == 0;
auto const have_content = tr_variantFromJson(&top, json) == 0;
auto* const data = tr_new0(struct rpc_response_data, 1);
data->req = req;
@ -470,11 +470,9 @@ static void handle_rpc(struct evhttp_request* req, tr_rpc_server* server)
{
if (req->type == EVHTTP_REQ_POST)
{
handle_rpc_from_json(
req,
server,
(char const*)evbuffer_pullup(req->input_buffer, -1),
evbuffer_get_length(req->input_buffer));
auto json = std::string_view{ reinterpret_cast<char const*>(evbuffer_pullup(req->input_buffer, -1)),
evbuffer_get_length(req->input_buffer) };
handle_rpc_from_json(req, server, json);
return;
}

View File

@ -81,7 +81,8 @@ static void clearMetainfo(tr_ctor* ctor)
int tr_ctorSetMetainfo(tr_ctor* ctor, void const* metainfo, size_t len)
{
clearMetainfo(ctor);
auto const err = tr_variantFromBenc(&ctor->metainfo, metainfo, len);
auto sv = std::string_view{ static_cast<char const*>(metainfo), len };
auto const err = tr_variantFromBenc(&ctor->metainfo, sv);
ctor->isSet_metainfo = err == 0;
return err;
}

View File

@ -43,8 +43,8 @@ struct metadata_node
struct tr_incomplete_metadata
{
uint8_t* metadata;
int metadata_size;
char* metadata;
size_t metadata_size;
int pieceCount;
/** sorted from least to most recently requested */
@ -88,7 +88,7 @@ bool tr_torrentSetMetadataSizeHint(tr_torrent* tor, int64_t size)
}
m->pieceCount = n;
m->metadata = tr_new(uint8_t, size);
m->metadata = tr_new(char, size);
m->metadata_size = size;
m->piecesNeededCount = n;
m->piecesNeeded = tr_new(struct metadata_node, n);
@ -119,7 +119,7 @@ static size_t findInfoDictOffset(tr_torrent const* tor)
if (fileContents != nullptr)
{
auto top = tr_variant{};
if (tr_variantFromBenc(&top, fileContents, fileLen) == 0)
if (tr_variantFromBenc(&top, std::string_view{ reinterpret_cast<char const*>(fileContents), fileLen }) == 0)
{
tr_variant* infoDict = nullptr;
if (tr_variantDictFindDict(&top, TR_KEY_info, &infoDict))
@ -277,7 +277,8 @@ void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, in
{
/* checksum passed; now try to parse it as benc */
tr_variant infoDict;
int const err = tr_variantFromBenc(&infoDict, m->metadata, m->metadata_size);
auto metadata_sv = std::string_view{ m->metadata, m->metadata_size };
int const err = tr_variantFromBenc(&infoDict, metadata_sv);
dbgmsg(tor, "err is %d", err);
metainfoParsed = err == 0;

View File

@ -160,6 +160,7 @@ static constexpr char const* tr_variant_string_get_string(struct tr_variant_stri
case TR_STRING_TYPE_HEAP:
case TR_STRING_TYPE_QUARK:
case TR_STRING_TYPE_VIEW:
return str->str.str;
default:
@ -175,6 +176,15 @@ static void tr_variant_string_set_quark(struct tr_variant_string* str, tr_quark
str->str.str = tr_quark_get_string(quark, &str->len);
}
static void tr_variant_string_set_string_view(struct tr_variant_string* str, std::string_view in)
{
tr_variant_string_clear(str);
str->type = TR_STRING_TYPE_VIEW;
str->len = std::size(in);
str->str.str = std::data(in);
}
static void tr_variant_string_set_string(struct tr_variant_string* str, std::string_view in)
{
tr_variant_string_clear(str);
@ -486,6 +496,12 @@ void tr_variantInitStr(tr_variant* v, std::string_view str)
tr_variant_string_set_string(&v->val.s, str);
}
void tr_variantInitStrView(tr_variant* v, std::string_view str)
{
tr_variantInit(v, TR_VARIANT_TYPE_STR);
tr_variant_string_set_string_view(&v->val.s, str);
}
void tr_variantInitBool(tr_variant* v, bool value)
{
tr_variantInit(v, TR_VARIANT_TYPE_BOOL);
@ -593,6 +609,13 @@ tr_variant* tr_variantListAddStr(tr_variant* list, std::string_view str)
return child;
}
tr_variant* tr_variantListAddStrView(tr_variant* list, std::string_view str)
{
tr_variant* child = tr_variantListAdd(list);
tr_variantInitStrView(child, str);
return child;
}
tr_variant* tr_variantListAddQuark(tr_variant* list, tr_quark const val)
{
tr_variant* child = tr_variantListAdd(list);
@ -694,6 +717,13 @@ tr_variant* tr_variantDictAddStr(tr_variant* dict, tr_quark const key, std::stri
return child;
}
tr_variant* tr_variantDictAddStrView(tr_variant* dict, tr_quark const key, std::string_view str)
{
tr_variant* child = dictFindOrAdd(dict, key, TR_VARIANT_TYPE_STR);
tr_variantInitStrView(child, str);
return child;
}
tr_variant* tr_variantDictAddRaw(tr_variant* dict, tr_quark const key, void const* src, size_t len)
{
tr_variant* child = dictFindOrAdd(dict, key, TR_VARIANT_TYPE_STR);
@ -1289,30 +1319,7 @@ int tr_variantToFile(tr_variant const* v, tr_variant_fmt fmt, char const* filena
****
***/
bool tr_variantFromFile(tr_variant* setme, tr_variant_fmt fmt, char const* filename, tr_error** error)
{
bool ret = false;
auto buflen = size_t{};
uint8_t* const buf = tr_loadFile(filename, &buflen, error);
if (buf != nullptr)
{
if (tr_variantFromBuf(setme, fmt, buf, buflen, filename, nullptr) == 0)
{
ret = true;
}
else
{
tr_error_set_literal(error, 0, _("Unable to parse file content"));
}
tr_free(buf);
}
return ret;
}
int tr_variantFromBuf(
static int tr_variantFromBuf(
tr_variant* setme,
tr_variant_fmt fmt,
void const* buf,
@ -1341,3 +1348,41 @@ int tr_variantFromBuf(
restore_locale(&locale_ctx);
return err;
}
int tr_variantFromBenc(tr_variant* setme, std::string_view benc)
{
return tr_variantFromBuf(setme, TR_VARIANT_FMT_BENC, std::data(benc), std::size(benc), nullptr, nullptr);
}
int tr_variantFromBencFull(tr_variant* setme, std::string_view benc, char const** setme_end)
{
return tr_variantFromBuf(setme, TR_VARIANT_FMT_BENC, std::data(benc), std::size(benc), nullptr, setme_end);
}
int tr_variantFromJson(tr_variant* setme, std::string_view json)
{
return tr_variantFromBuf(setme, TR_VARIANT_FMT_JSON, std::data(json), std::size(json), nullptr, nullptr);
}
bool tr_variantFromFile(tr_variant* setme, tr_variant_fmt fmt, char const* filename, tr_error** error)
{
bool ret = false;
auto buflen = size_t{};
uint8_t* const buf = tr_loadFile(filename, &buflen, error);
if (buf != nullptr)
{
if (tr_variantFromBuf(setme, fmt, buf, buflen, filename, nullptr) == 0)
{
ret = true;
}
else
{
tr_error_set_literal(error, 0, _("Unable to parse file content"));
}
tr_free(buf);
}
return ret;
}

View File

@ -34,7 +34,8 @@ enum tr_string_type
{
TR_STRING_TYPE_QUARK,
TR_STRING_TYPE_HEAP,
TR_STRING_TYPE_BUF
TR_STRING_TYPE_BUF,
TR_STRING_TYPE_VIEW
};
/* these are PRIVATE IMPLEMENTATION details that should not be touched.
@ -114,44 +115,11 @@ struct evbuffer* tr_variantToBuf(tr_variant const* variant, tr_variant_fmt fmt);
/* TR_VARIANT_FMT_JSON_LEAN and TR_VARIANT_FMT_JSON are equivalent here. */
bool tr_variantFromFile(tr_variant* setme, tr_variant_fmt fmt, char const* filename, struct tr_error** error);
/* TR_VARIANT_FMT_JSON_LEAN and TR_VARIANT_FMT_JSON are equivalent here. */
int tr_variantFromBuf(
tr_variant* setme,
tr_variant_fmt fmt,
void const* buf,
size_t buflen,
char const* optional_source,
char const** setme_end);
int tr_variantFromBenc(tr_variant* setme, std::string_view benc);
static inline int tr_variantFromBenc(tr_variant* setme, void const* buf, size_t buflen)
{
return tr_variantFromBuf(setme, TR_VARIANT_FMT_BENC, buf, buflen, nullptr, nullptr);
}
int tr_variantFromBencFull(tr_variant* setme, std::string_view benc, char const** setme_end);
static inline int tr_variantFromBencFull(
tr_variant* setme,
void const* buf,
size_t buflen,
char const* source,
char const** setme_end)
{
return tr_variantFromBuf(setme, TR_VARIANT_FMT_BENC, buf, buflen, source, setme_end);
}
static inline int tr_variantFromJsonFull(
tr_variant* setme,
void const* buf,
size_t buflen,
char const* source,
char const** setme_end)
{
return tr_variantFromBuf(setme, TR_VARIANT_FMT_JSON, buf, buflen, source, setme_end);
}
static inline int tr_variantFromJson(tr_variant* setme, void const* buf, size_t buflen)
{
return tr_variantFromBuf(setme, TR_VARIANT_FMT_JSON, buf, buflen, nullptr, nullptr);
}
int tr_variantFromJson(tr_variant* setme, std::string_view json);
constexpr bool tr_variantIsType(tr_variant const* b, int type)
{
@ -170,6 +138,7 @@ constexpr bool tr_variantIsString(tr_variant const* b)
bool tr_variantGetStrView(tr_variant const* variant, std::string_view* setme);
void tr_variantInitStr(tr_variant* initme, std::string_view);
void tr_variantInitStrView(tr_variant* initme, std::string_view);
void tr_variantInitQuark(tr_variant* initme, tr_quark const quark);
void tr_variantInitRaw(tr_variant* initme, void const* raw, size_t raw_len);
@ -228,6 +197,7 @@ tr_variant* tr_variantListAddBool(tr_variant* list, bool addme);
tr_variant* tr_variantListAddInt(tr_variant* list, int64_t addme);
tr_variant* tr_variantListAddReal(tr_variant* list, double addme);
tr_variant* tr_variantListAddStr(tr_variant* list, std::string_view);
tr_variant* tr_variantListAddStrView(tr_variant* list, std::string_view);
tr_variant* tr_variantListAddQuark(tr_variant* list, tr_quark const addme);
tr_variant* tr_variantListAddRaw(tr_variant* list, void const* addme_value, size_t addme_len);
tr_variant* tr_variantListAddList(tr_variant* list, size_t reserve_count);
@ -255,6 +225,7 @@ tr_variant* tr_variantDictAddReal(tr_variant* dict, tr_quark const key, double v
tr_variant* tr_variantDictAddInt(tr_variant* dict, tr_quark const key, int64_t value);
tr_variant* tr_variantDictAddBool(tr_variant* dict, tr_quark const key, bool value);
tr_variant* tr_variantDictAddStr(tr_variant* dict, tr_quark const key, std::string_view);
tr_variant* tr_variantDictAddStrView(tr_variant* dict, tr_quark const key, std::string_view);
tr_variant* tr_variantDictAddQuark(tr_variant* dict, tr_quark const key, tr_quark const val);
tr_variant* tr_variantDictAddList(tr_variant* dict, tr_quark const key, size_t reserve_count);
tr_variant* tr_variantDictAddDict(tr_variant* dict, tr_quark const key, size_t reserve_count);

View File

@ -272,12 +272,12 @@ void RpcClient::networkRequestFinished(QNetworkReply* reply)
}
else
{
RpcResponse result;
QByteArray const json_data = reply->readAll().trimmed();
TrVariantPtr json = createVariant();
auto const json_sv = std::string_view{ std::data(json_data), size_t(std::size(json_data)) };
if (tr_variantFromJson(json.get(), json_data.constData(), json_data.size()) == 0)
TrVariantPtr json = createVariant();
RpcResponse result;
if (tr_variantFromJson(json.get(), json_sv) == 0)
{
result = parseResponseData(*json);
}

View File

@ -48,7 +48,7 @@ TEST_P(JSONTest, testElements)
};
tr_variant top;
int err = tr_variantFromJson(&top, in.data(), in.size());
int err = tr_variantFromJson(&top, in);
EXPECT_EQ(0, err);
EXPECT_TRUE(tr_variantIsDict(&top));
@ -93,7 +93,7 @@ TEST_P(JSONTest, testUtf8)
int err;
tr_quark const key = tr_quark_new("key"sv);
err = tr_variantFromJson(&top, in.data(), in.size());
err = tr_variantFromJson(&top, in);
EXPECT_EQ(0, err);
EXPECT_TRUE(tr_variantIsDict(&top));
EXPECT_TRUE(tr_variantDictFindStrView(&top, key, &sv));
@ -105,7 +105,7 @@ TEST_P(JSONTest, testUtf8)
}
in = std::string{ R"({ "key": "\u005C" })" };
err = tr_variantFromJson(&top, in.data(), in.size());
err = tr_variantFromJson(&top, in);
EXPECT_EQ(0, err);
EXPECT_TRUE(tr_variantIsDict(&top));
EXPECT_TRUE(tr_variantDictFindStrView(&top, key, &sv));
@ -125,7 +125,7 @@ TEST_P(JSONTest, testUtf8)
* 6. Confirm that the result is UTF-8.
*/
in = std::string{ R"({ "key": "Let\u00f6lt\u00e9sek" })" };
err = tr_variantFromJson(&top, in.data(), in.size());
err = tr_variantFromJson(&top, in);
EXPECT_EQ(0, err);
EXPECT_TRUE(tr_variantIsDict(&top));
EXPECT_TRUE(tr_variantDictFindStrView(&top, key, &sv));
@ -140,7 +140,7 @@ TEST_P(JSONTest, testUtf8)
EXPECT_NE(nullptr, json);
EXPECT_NE(nullptr, strstr(json, "\\u00f6"));
EXPECT_NE(nullptr, strstr(json, "\\u00e9"));
err = tr_variantFromJson(&top, json, strlen(json));
err = tr_variantFromJson(&top, json);
EXPECT_EQ(0, err);
EXPECT_TRUE(tr_variantIsDict(&top));
EXPECT_TRUE(tr_variantDictFindStrView(&top, key, &sv));
@ -172,7 +172,7 @@ TEST_P(JSONTest, test1)
};
tr_variant top;
auto const err = tr_variantFromJson(&top, in.data(), in.size());
auto const err = tr_variantFromJson(&top, in);
auto sv = std::string_view{};
int64_t i;
@ -210,7 +210,7 @@ TEST_P(JSONTest, test2)
auto const in = std::string{ " " };
top.type = 0;
int err = tr_variantFromJson(&top, in.data(), in.size());
int err = tr_variantFromJson(&top, in);
EXPECT_NE(0, err);
EXPECT_FALSE(tr_variantIsDict(&top));
@ -227,7 +227,7 @@ TEST_P(JSONTest, test3)
};
tr_variant top;
auto const err = tr_variantFromJson(&top, in.data(), in.size());
auto const err = tr_variantFromJson(&top, in);
EXPECT_EQ(0, err);
auto sv = std::string_view{};
@ -241,7 +241,7 @@ TEST_P(JSONTest, unescape)
{
tr_variant top;
auto const in = std::string{ R"({ "string-1": "\/usr\/lib" })" };
int const err = tr_variantFromJson(&top, in.data(), in.size());
int const err = tr_variantFromJson(&top, in);
EXPECT_EQ(0, err);
auto sv = std::string_view{};

View File

@ -68,6 +68,14 @@ TEST_F(VariantTest, getType)
EXPECT_FALSE(tr_variantGetBool(&v, &b));
EXPECT_TRUE(tr_variantGetStrView(&v, &sv));
EXPECT_EQ(strkey, sv);
EXPECT_NE(std::data(strkey), std::data(sv));
strkey = "anything"sv;
tr_variantInitStrView(&v, strkey);
EXPECT_TRUE(tr_variantGetStrView(&v, &sv));
EXPECT_EQ(strkey, sv);
EXPECT_EQ(std::data(strkey), std::data(sv)); // literally the same memory
EXPECT_EQ(std::size(strkey), std::size(sv));
strkey = "true"sv;
tr_variantInitStr(&v, strkey);
@ -234,23 +242,21 @@ TEST_F(VariantTest, str)
TEST_F(VariantTest, parse)
{
auto buf = std::array<uint8_t, 512>{};
int64_t i;
tr_variant val;
auto benc = "i64e"sv;
auto i = int64_t{};
auto val = tr_variant{};
char const* end;
auto n = tr_snprintf(buf.data(), buf.size(), "i64e");
auto err = tr_variantFromBencFull(&val, buf.data(), n, nullptr, &end);
auto err = tr_variantFromBencFull(&val, benc, &end);
EXPECT_EQ(0, err);
EXPECT_TRUE(tr_variantGetInt(&val, &i));
EXPECT_EQ(int64_t(64), i);
EXPECT_EQ(reinterpret_cast<char const*>(buf.data()) + n, end);
EXPECT_EQ(std::data(benc) + std::size(benc), end);
tr_variantFree(&val);
n = tr_snprintf(buf.data(), buf.size(), "li64ei32ei16ee");
err = tr_variantFromBencFull(&val, buf.data(), n, nullptr, &end);
benc = "li64ei32ei16ee"sv;
err = tr_variantFromBencFull(&val, benc, &end);
EXPECT_EQ(0, err);
EXPECT_EQ(reinterpret_cast<char const*>(&buf[n]), end);
EXPECT_EQ(std::data(benc) + std::size(benc), end);
EXPECT_EQ(size_t{ 3 }, tr_variantListSize(&val));
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&val, 0), &i));
EXPECT_EQ(64, i);
@ -259,29 +265,28 @@ TEST_F(VariantTest, parse)
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&val, 2), &i));
EXPECT_EQ(16, i);
size_t len;
auto len = size_t{};
auto* saved = tr_variantToStr(&val, TR_VARIANT_FMT_BENC, &len);
EXPECT_EQ(static_cast<size_t>(n), len);
EXPECT_STREQ(reinterpret_cast<char const*>(buf.data()), saved);
EXPECT_EQ(std::size(benc), len);
EXPECT_EQ(benc, saved);
tr_free(saved);
tr_variantFree(&val);
end = nullptr;
n = tr_snprintf(buf.data(), buf.size(), "lllee");
err = tr_variantFromBencFull(&val, buf.data(), n, nullptr, &end);
benc = "lllee"sv;
err = tr_variantFromBencFull(&val, benc, &end);
EXPECT_NE(0, err);
EXPECT_EQ(nullptr, end);
end = nullptr;
n = tr_snprintf(buf.data(), buf.size(), "le");
err = tr_variantFromBencFull(&val, buf.data(), n, nullptr, &end);
benc = "le"sv;
err = tr_variantFromBencFull(&val, benc, &end);
EXPECT_EQ(0, err);
EXPECT_EQ(reinterpret_cast<char const*>(&buf[n]), end);
EXPECT_EQ(std::data(benc) + std::size(benc), end);
saved = tr_variantToStr(&val, TR_VARIANT_FMT_BENC, &len);
EXPECT_EQ(static_cast<size_t>(n), len);
EXPECT_STREQ("le", saved);
EXPECT_EQ(std::size(benc), len);
EXPECT_EQ(benc, saved);
tr_free(saved);
tr_variantFree(&val);
}
@ -290,27 +295,27 @@ TEST_F(VariantTest, bencParseAndReencode)
{
struct LocalTest
{
std::string benc;
std::string_view benc;
bool is_good;
};
auto const tests = std::array<LocalTest, 9>{
LocalTest{ "llleee", true },
{ "d3:cow3:moo4:spam4:eggse", true },
{ "d4:spaml1:a1:bee", true },
{ "d5:greenli1ei2ei3ee4:spamd1:ai123e3:keyi214eee", true },
{ "d9:publisher3:bob17:publisher-webpage15:www.example.com18:publisher.location4:homee", true },
{ "d8:completei1e8:intervali1800e12:min intervali1800e5:peers0:e", true },
{ "d1:ai0e1:be", false }, // odd number of children
{ "", false },
{ " ", false },
};
auto constexpr Tests = std::array<LocalTest, 9>{ {
{ "llleee"sv, true },
{ "d3:cow3:moo4:spam4:eggse"sv, true },
{ "d4:spaml1:a1:bee"sv, true },
{ "d5:greenli1ei2ei3ee4:spamd1:ai123e3:keyi214eee"sv, true },
{ "d9:publisher3:bob17:publisher-webpage15:www.example.com18:publisher.location4:homee"sv, true },
{ "d8:completei1e8:intervali1800e12:min intervali1800e5:peers0:e"sv, true },
{ "d1:ai0e1:be"sv, false }, // odd number of children
{ ""sv, false },
{ " "sv, false },
} };
for (auto const& test : tests)
for (auto const& test : Tests)
{
tr_variant val;
char const* end = nullptr;
auto const err = tr_variantFromBencFull(&val, test.benc.data(), test.benc.size(), nullptr, &end);
auto const err = tr_variantFromBencFull(&val, test.benc, &end);
if (!test.is_good)
{
EXPECT_NE(0, err);
@ -330,18 +335,19 @@ TEST_F(VariantTest, bencParseAndReencode)
TEST_F(VariantTest, bencSortWhenSerializing)
{
auto const in = std::string{ "lld1:bi32e1:ai64eeee" };
auto const expected_out = std::string{ "lld1:ai64e1:bi32eeee" };
auto constexpr In = "lld1:bi32e1:ai64eeee"sv;
auto constexpr ExpectedOut = "lld1:ai64e1:bi32eeee"sv;
tr_variant val;
char const* end;
auto const err = tr_variantFromBencFull(&val, in.data(), in.size(), nullptr, &end);
auto const err = tr_variantFromBencFull(&val, In, &end);
EXPECT_EQ(0, err);
EXPECT_EQ(reinterpret_cast<decltype(end)>(in.data() + in.size()), end);
EXPECT_EQ(std::data(In) + std::size(In), end);
auto len = size_t{};
auto* saved = tr_variantToStr(&val, TR_VARIANT_FMT_BENC, &len);
EXPECT_EQ(expected_out, std::string(saved, len));
auto sv = std::string_view{ saved, len };
EXPECT_EQ(ExpectedOut, sv);
tr_free(saved);
tr_variantFree(&val);
@ -349,18 +355,19 @@ TEST_F(VariantTest, bencSortWhenSerializing)
TEST_F(VariantTest, bencMalformedTooManyEndings)
{
auto const in = std::string{ "leee" };
auto const expected_out = std::string{ "le" };
auto constexpr In = "leee"sv;
auto constexpr ExpectedOut = "le"sv;
tr_variant val;
char const* end;
auto const err = tr_variantFromBencFull(&val, in.data(), in.size(), nullptr, &end);
auto const err = tr_variantFromBencFull(&val, In, &end);
EXPECT_EQ(0, err);
EXPECT_EQ(in.data() + expected_out.size(), end);
EXPECT_EQ(std::data(In) + std::size(ExpectedOut), end);
auto len = size_t{};
auto* saved = tr_variantToStr(&val, TR_VARIANT_FMT_BENC, &len);
EXPECT_EQ(expected_out, std::string(saved, len));
auto sv = std::string_view{ saved, len };
EXPECT_EQ(ExpectedOut, sv);
tr_free(saved);
tr_variantFree(&val);
@ -368,38 +375,39 @@ TEST_F(VariantTest, bencMalformedTooManyEndings)
TEST_F(VariantTest, bencMalformedNoEnding)
{
auto const in = std::string{ "l1:a1:b1:c" };
auto constexpr In = "l1:a1:b1:c"sv;
tr_variant val;
EXPECT_EQ(EILSEQ, tr_variantFromBenc(&val, in.data(), in.size()));
EXPECT_EQ(EILSEQ, tr_variantFromBenc(&val, In));
}
TEST_F(VariantTest, bencMalformedIncompleteString)
{
auto const in = std::string{ "1:" };
auto constexpr In = "1:"sv;
tr_variant val;
EXPECT_EQ(EILSEQ, tr_variantFromBenc(&val, in.data(), in.size()));
EXPECT_EQ(EILSEQ, tr_variantFromBenc(&val, In));
}
TEST_F(VariantTest, bencToJson)
{
struct LocalTest
{
std::string benc;
std::string expected;
std::string_view benc;
std::string_view expected;
};
auto const tests = std::array<LocalTest, 5>{
LocalTest{ "i6e", "6" },
{ "d5:helloi1e5:worldi2ee", R"({"hello":1,"world":2})" },
{ "d5:helloi1e5:worldi2e3:fooli1ei2ei3eee", R"({"foo":[1,2,3],"hello":1,"world":2})" },
{ "d5:helloi1e5:worldi2e3:fooli1ei2ei3ed1:ai0eeee", R"({"foo":[1,2,3,{"a":0}],"hello":1,"world":2})" },
{ "d4:argsd6:statusle7:status2lee6:result7:successe", R"({"args":{"status":[],"status2":[]},"result":"success"})" }
auto constexpr Tests = std::array<LocalTest, 5>{
{ { "i6e"sv, "6"sv },
{ "d5:helloi1e5:worldi2ee"sv, R"({"hello":1,"world":2})"sv },
{ "d5:helloi1e5:worldi2e3:fooli1ei2ei3eee"sv, R"({"foo":[1,2,3],"hello":1,"world":2})"sv },
{ "d5:helloi1e5:worldi2e3:fooli1ei2ei3ed1:ai0eeee"sv, R"({"foo":[1,2,3,{"a":0}],"hello":1,"world":2})"sv },
{ "d4:argsd6:statusle7:status2lee6:result7:successe"sv,
R"({"args":{"status":[],"status2":[]},"result":"success"})"sv } }
};
for (auto const& test : tests)
for (auto const& test : Tests)
{
tr_variant top;
tr_variantFromBenc(&top, test.benc.data(), test.benc.size());
tr_variantFromBenc(&top, test.benc);
auto len = size_t{};
auto* str = tr_variantToStr(&top, TR_VARIANT_FMT_JSON_LEAN, &len);
@ -474,7 +482,7 @@ TEST_F(VariantTest, stackSmash)
// confirm that it parses
char const* end;
tr_variant val;
auto err = tr_variantFromBencFull(&val, in.data(), in.size(), nullptr, &end);
auto err = tr_variantFromBencFull(&val, in, &end);
EXPECT_EQ(0, err);
EXPECT_EQ(in.data() + in.size(), end);

View File

@ -2039,7 +2039,7 @@ static int processResponse(char const* rpcurl, std::string_view response)
TR_PRIsv_ARG(response));
}
if (tr_variantFromJson(&top, std::data(response), std::size(response)) != 0)
if (tr_variantFromJson(&top, response) != 0)
{
tr_logAddNamedError(MY_NAME, "Unable to parse response \"%" TR_PRIsv "\"", TR_PRIsv_ARG(response));
status |= EXIT_FAILURE;

View File

@ -261,7 +261,7 @@ static void doScrape(tr_info const* inf)
bool matched = false;
char const* begin = (char const*)evbuffer_pullup(buf, -1);
if (tr_variantFromBenc(&top, begin, evbuffer_get_length(buf)) == 0)
if (tr_variantFromBenc(&top, { begin, evbuffer_get_length(buf) }) == 0)
{
if (tr_variantDictFindDict(&top, TR_KEY_files, &files))
{