feat: new function tr_variantGetStrView() (#2079)

* feat: new method tr_variantGetStrView()

* test: add new variant tests
This commit is contained in:
Charles Kerr 2021-11-01 16:30:18 -05:00 committed by GitHub
parent feaf12a205
commit ba59060737
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 113 additions and 38 deletions

View File

@ -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))
{

View File

@ -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 */

View File

@ -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);
}