mirror of
https://github.com/transmission/transmission
synced 2025-03-16 00:39:34 +00:00
feat: new function tr_variantGetStrView() (#2079)
* feat: new method tr_variantGetStrView() * test: add new variant tests
This commit is contained in:
parent
feaf12a205
commit
ba59060737
3 changed files with 113 additions and 38 deletions
|
@ -55,6 +55,8 @@
|
|||
***
|
||||
**/
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
struct locale_context
|
||||
{
|
||||
#ifdef HAVE_USELOCALE
|
||||
|
@ -301,21 +303,38 @@ bool tr_variantGetInt(tr_variant const* v, int64_t* setme)
|
|||
return success;
|
||||
}
|
||||
|
||||
bool tr_variantGetStrView(tr_variant const* v, std::string_view* setme)
|
||||
{
|
||||
if (!tr_variantIsString(v))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char const* const str = tr_variant_string_get_string(&v->val.s);
|
||||
size_t const len = v->val.s.len;
|
||||
*setme = std::string_view{ str, len };
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tr_variantGetStr(tr_variant const* v, char const** setme, size_t* len)
|
||||
{
|
||||
bool const success = tr_variantIsString(v);
|
||||
|
||||
if (success)
|
||||
auto sv = std::string_view{};
|
||||
if (!tr_variantGetStrView(v, &sv))
|
||||
{
|
||||
*setme = getStr(v);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (setme != nullptr)
|
||||
{
|
||||
*setme = std::data(sv);
|
||||
}
|
||||
|
||||
if (len != nullptr)
|
||||
{
|
||||
*len = success ? v->val.s.len : 0;
|
||||
*len = std::size(sv);
|
||||
}
|
||||
|
||||
return success;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tr_variantGetRaw(tr_variant const* v, uint8_t const** setme_raw, size_t* setme_len)
|
||||
|
@ -333,28 +352,35 @@ bool tr_variantGetRaw(tr_variant const* v, uint8_t const** setme_raw, size_t* se
|
|||
|
||||
bool tr_variantGetBool(tr_variant const* v, bool* setme)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (tr_variantIsBool(v))
|
||||
{
|
||||
*setme = v->val.b;
|
||||
success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((!success) && tr_variantIsInt(v) && (v->val.i == 0 || v->val.i == 1))
|
||||
if (tr_variantIsInt(v) && (v->val.i == 0 || v->val.i == 1))
|
||||
{
|
||||
*setme = v->val.i != 0;
|
||||
success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
char const* str = nullptr;
|
||||
if ((!success) && tr_variantGetStr(v, &str, nullptr) && (strcmp(str, "true") == 0 || strcmp(str, "false") == 0))
|
||||
auto sv = std::string_view{};
|
||||
if (tr_variantGetStrView(v, &sv))
|
||||
{
|
||||
*setme = strcmp(str, "true") == 0;
|
||||
success = true;
|
||||
if (sv == "true"sv)
|
||||
{
|
||||
*setme = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sv == "false"sv)
|
||||
{
|
||||
*setme = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tr_variantGetReal(tr_variant const* v, double* setme)
|
||||
|
@ -410,6 +436,12 @@ bool tr_variantDictFindReal(tr_variant* dict, tr_quark const key, double* setme)
|
|||
return tr_variantGetReal(child, setme);
|
||||
}
|
||||
|
||||
bool tr_variantDictFindStrView(tr_variant* dict, tr_quark const key, std::string_view* setme)
|
||||
{
|
||||
tr_variant const* const child = tr_variantDictFind(dict, key);
|
||||
return tr_variantGetStrView(child, setme);
|
||||
}
|
||||
|
||||
bool tr_variantDictFindStr(tr_variant* dict, tr_quark const key, char const** setme, size_t* len)
|
||||
{
|
||||
tr_variant const* const child = tr_variantDictFind(dict, key);
|
||||
|
@ -948,10 +980,9 @@ static void tr_variantListCopy(tr_variant* target, tr_variant const* src)
|
|||
}
|
||||
else if (tr_variantIsString(val))
|
||||
{
|
||||
size_t len = 0;
|
||||
char const* str = nullptr;
|
||||
(void)tr_variantGetStr(val, &str, &len);
|
||||
tr_variantListAddRaw(target, str, len);
|
||||
auto sv = std::string_view{};
|
||||
(void)tr_variantGetStrView(val, &sv);
|
||||
tr_variantListAddRaw(target, std::data(sv), std::size(sv));
|
||||
}
|
||||
else if (tr_variantIsDict(val))
|
||||
{
|
||||
|
@ -1035,10 +1066,9 @@ void tr_variantMergeDicts(tr_variant* target, tr_variant const* source)
|
|||
}
|
||||
else if (tr_variantIsString(val))
|
||||
{
|
||||
size_t len = 0;
|
||||
char const* str = nullptr;
|
||||
(void)tr_variantGetStr(val, &str, &len);
|
||||
tr_variantDictAddRaw(target, key, str, len);
|
||||
auto sv = std::string_view{};
|
||||
(void)tr_variantGetStrView(val, &sv);
|
||||
tr_variantDictAddRaw(target, key, std::data(sv), std::size(sv));
|
||||
}
|
||||
else if (tr_variantIsDict(val) && tr_variantDictFindDict(target, key, &t))
|
||||
{
|
||||
|
|
|
@ -168,6 +168,7 @@ constexpr bool tr_variantIsString(tr_variant const* b)
|
|||
}
|
||||
|
||||
bool tr_variantGetStr(tr_variant const* variant, char const** setme_str, size_t* setme_len);
|
||||
bool tr_variantGetStrView(tr_variant const* variant, std::string_view* setme);
|
||||
|
||||
void tr_variantInitStr(tr_variant* initme, std::string_view);
|
||||
void tr_variantInitQuark(tr_variant* initme, tr_quark const quark);
|
||||
|
@ -269,6 +270,7 @@ bool tr_variantDictFindInt(tr_variant* dict, tr_quark const key, int64_t* setme)
|
|||
bool tr_variantDictFindReal(tr_variant* dict, tr_quark const key, double* setme);
|
||||
bool tr_variantDictFindBool(tr_variant* dict, tr_quark const key, bool* setme);
|
||||
bool tr_variantDictFindStr(tr_variant* dict, tr_quark const key, char const** setme, size_t* len);
|
||||
bool tr_variantDictFindStrView(tr_variant* dict, tr_quark const key, std::string_view* setme);
|
||||
bool tr_variantDictFindRaw(tr_variant* dict, tr_quark const key, uint8_t const** setme_raw, size_t* setme_len);
|
||||
|
||||
/* this is only quasi-supported. don't rely on it too heavily outside of libT */
|
||||
|
|
|
@ -47,6 +47,43 @@ protected:
|
|||
#define STACK_SMASH_DEPTH (100 * 1000)
|
||||
#endif
|
||||
|
||||
TEST_F(VariantTest, getType)
|
||||
{
|
||||
auto i = int64_t{};
|
||||
auto b = bool{};
|
||||
auto d = double{};
|
||||
auto sv = std::string_view{};
|
||||
auto v = tr_variant{};
|
||||
|
||||
tr_variantInitInt(&v, 30);
|
||||
EXPECT_TRUE(tr_variantGetInt(&v, &i));
|
||||
EXPECT_EQ(30, i);
|
||||
EXPECT_TRUE(tr_variantGetReal(&v, &d));
|
||||
EXPECT_EQ(30, int(d));
|
||||
EXPECT_FALSE(tr_variantGetBool(&v, &b));
|
||||
EXPECT_FALSE(tr_variantGetStrView(&v, &sv));
|
||||
|
||||
auto strkey = "foo"sv;
|
||||
tr_variantInitStr(&v, strkey);
|
||||
EXPECT_FALSE(tr_variantGetBool(&v, &b));
|
||||
EXPECT_TRUE(tr_variantGetStrView(&v, &sv));
|
||||
EXPECT_EQ(strkey, sv);
|
||||
|
||||
strkey = "true"sv;
|
||||
tr_variantInitStr(&v, strkey);
|
||||
EXPECT_TRUE(tr_variantGetBool(&v, &b));
|
||||
EXPECT_TRUE(b);
|
||||
EXPECT_TRUE(tr_variantGetStrView(&v, &sv));
|
||||
EXPECT_EQ(strkey, sv);
|
||||
|
||||
strkey = "false"sv;
|
||||
tr_variantInitStr(&v, strkey);
|
||||
EXPECT_TRUE(tr_variantGetBool(&v, &b));
|
||||
EXPECT_FALSE(b);
|
||||
EXPECT_TRUE(tr_variantGetStrView(&v, &sv));
|
||||
EXPECT_EQ(strkey, sv);
|
||||
}
|
||||
|
||||
TEST_F(VariantTest, parseInt)
|
||||
{
|
||||
auto const in = std::string{ "i64e" };
|
||||
|
@ -497,32 +534,38 @@ TEST_F(VariantTest, boolAndIntRecast)
|
|||
|
||||
TEST_F(VariantTest, dictFindType)
|
||||
{
|
||||
auto const expected_str = std::string{ "this-is-a-string" };
|
||||
auto const expected_bool = bool{ true };
|
||||
auto const expected_int = int{ 1234 };
|
||||
auto const expected_real = double{ 0.3 };
|
||||
auto constexpr ExpectedStr = "this-is-a-string"sv;
|
||||
auto constexpr ExpectedBool = bool{ true };
|
||||
auto constexpr ExpectedInt = int{ 1234 };
|
||||
auto constexpr ExpectedReal = double{ 0.3 };
|
||||
|
||||
auto const key_bool = tr_quark_new("this-is-a-bool"sv);
|
||||
auto const key_real = tr_quark_new("this-is-a-real"sv);
|
||||
auto const key_int = tr_quark_new("this-is-an-int"sv);
|
||||
auto const key_str = tr_quark_new("this-is-a-string"sv);
|
||||
auto const key_unknown = tr_quark_new("this-is-a-missing-entry"sv);
|
||||
|
||||
// populate a dict
|
||||
tr_variant top;
|
||||
tr_variantInitDict(&top, 0);
|
||||
tr_variantDictAddBool(&top, key_bool, expected_bool);
|
||||
tr_variantDictAddInt(&top, key_int, expected_int);
|
||||
tr_variantDictAddReal(&top, key_real, expected_real);
|
||||
tr_variantDictAddStr(&top, key_str, expected_str.data());
|
||||
tr_variantDictAddBool(&top, key_bool, ExpectedBool);
|
||||
tr_variantDictAddInt(&top, key_int, ExpectedInt);
|
||||
tr_variantDictAddReal(&top, key_real, ExpectedReal);
|
||||
tr_variantDictAddStr(&top, key_str, ExpectedStr.data());
|
||||
|
||||
// look up the keys as strings
|
||||
char const* str = {};
|
||||
auto len = size_t{};
|
||||
auto sv = std::string_view{};
|
||||
EXPECT_FALSE(tr_variantDictFindStr(&top, key_bool, &str, &len));
|
||||
EXPECT_FALSE(tr_variantDictFindStr(&top, key_real, &str, &len));
|
||||
EXPECT_FALSE(tr_variantDictFindStr(&top, key_int, &str, &len));
|
||||
EXPECT_TRUE(tr_variantDictFindStr(&top, key_str, &str, &len));
|
||||
EXPECT_EQ(expected_str, std::string(str, len));
|
||||
EXPECT_EQ(ExpectedStr, std::string(str, len));
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&top, key_str, &sv));
|
||||
EXPECT_EQ(ExpectedStr, sv);
|
||||
EXPECT_FALSE(tr_variantDictFindStrView(&top, key_unknown, &sv));
|
||||
EXPECT_FALSE(tr_variantDictFindStr(&top, key_unknown, &str, &len));
|
||||
|
||||
// look up the keys as bools
|
||||
auto b = bool{};
|
||||
|
@ -530,25 +573,25 @@ TEST_F(VariantTest, dictFindType)
|
|||
EXPECT_FALSE(tr_variantDictFindBool(&top, key_real, &b));
|
||||
EXPECT_FALSE(tr_variantDictFindBool(&top, key_str, &b));
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&top, key_bool, &b));
|
||||
EXPECT_EQ(expected_bool, b);
|
||||
EXPECT_EQ(ExpectedBool, b);
|
||||
|
||||
// look up the keys as doubles
|
||||
auto d = double{};
|
||||
EXPECT_FALSE(tr_variantDictFindReal(&top, key_bool, &d));
|
||||
EXPECT_TRUE(tr_variantDictFindReal(&top, key_int, &d));
|
||||
EXPECT_EQ(expected_int, std::lrint(d));
|
||||
EXPECT_EQ(ExpectedInt, std::lrint(d));
|
||||
EXPECT_FALSE(tr_variantDictFindReal(&top, key_str, &d));
|
||||
EXPECT_TRUE(tr_variantDictFindReal(&top, key_real, &d));
|
||||
EXPECT_EQ(std::lrint(expected_real * 100), std::lrint(d * 100));
|
||||
EXPECT_EQ(std::lrint(ExpectedReal * 100), std::lrint(d * 100));
|
||||
|
||||
// look up the keys as ints
|
||||
auto i = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&top, key_bool, &i));
|
||||
EXPECT_EQ(expected_bool ? 1 : 0, i);
|
||||
EXPECT_EQ(ExpectedBool ? 1 : 0, i);
|
||||
EXPECT_FALSE(tr_variantDictFindInt(&top, key_real, &i));
|
||||
EXPECT_FALSE(tr_variantDictFindInt(&top, key_str, &i));
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&top, key_int, &i));
|
||||
EXPECT_EQ(expected_int, i);
|
||||
EXPECT_EQ(ExpectedInt, i);
|
||||
|
||||
tr_variantFree(&top);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue