diff --git a/src/data.cpp b/src/data.cpp index 9b9601a..2ba9bf4 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -716,6 +716,8 @@ bool Value::tryCopyIn(const void *ptr, StoreType type) void Value::traverse(const std::string &expr, bool modify) { size_t pos=0; + bool maybedot = false; + while(desc && poscode.code==TypeCode::Struct) { // attempt traverse to member. // expect: [0-9a-zA-Z_.]+[\[-$] + + // skip a leading dot + if(maybedot) { + if(expr[pos]!='.') { + store.reset(); + desc = nullptr; + break; + } + maybedot = false; + pos++; + } + size_t sep = expr.find_first_of("<[-", pos); decltype (desc->mlookup)::const_iterator it; @@ -761,6 +775,8 @@ void Value::traverse(const std::string &expr, bool modify) // attempt to traverse to (and maybe select) member // expect: ->[0-9a-zA-Z_]+[.\[-$] + maybedot = false; + if(expr.size()-pos >= 3 && expr[pos]=='-' && expr[pos+1]=='>') { pos += 2; // skip past "->" @@ -787,6 +803,7 @@ void Value::traverse(const std::string &expr, bool modify) } pos = sep; *this = fld; + maybedot = true; } else { // traversing const Value, can't select Union @@ -805,6 +822,8 @@ void Value::traverse(const std::string &expr, bool modify) // attempt to traverse into array of Struct, Union, or Any // expect: \[[0-9]+\] + maybedot = false; + size_t sep = expr.find_first_of(']', pos); unsigned long long index=0; @@ -819,6 +838,8 @@ void Value::traverse(const std::string &expr, bool modify) { *this = arr[index]; pos = sep+1; + maybedot = true; + } else { // wrong element type or out of range store.reset(); diff --git a/test/testdata.cpp b/test/testdata.cpp index e1961cc..fbcbb52 100644 --- a/test/testdata.cpp +++ b/test/testdata.cpp @@ -333,9 +333,9 @@ void testDeserialize2() testOk1(!val["value"].isMarked()); testOk1(!!val["arbitrary.sarr"].isMarked()); testEq(val["arbitrary.sarr"].as>().size(), 3u*sizeof(Value)); - testEq(val["arbitrary.sarr[0]value"].as(), 0xdeadbeef); - testEq(val["arbitrary.sarr[1]value"].as(), 0x1badfaceu); - testEq(val["arbitrary.sarr[2]value"].type(), TypeCode::Null); + testEq(val["arbitrary.sarr[0].value"].as(), 0xdeadbeef); + testEq(val["arbitrary.sarr[1]"]["value"].as(), 0x1badfaceu); + testEq(val["arbitrary.sarr[2].value"].type(), TypeCode::Null); } { @@ -400,7 +400,7 @@ void testDeserialize2() testOk1(!!val["anya"].isMarked()); testEq(val["anya"].as>().size(), 3u*sizeof(Value)); testEq(val["anya[0]"].as(), 0x7bu); - testEq(val["anya[1]q"].as(), "theq"); + testEq(val["anya[1].q"].as(), "theq"); testEq(val["anya[2]"].type(), TypeCode::Null); } } diff --git a/test/testtype.cpp b/test/testtype.cpp index 27fc7db..e706fb4 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -205,7 +205,7 @@ R"out( fld = arr.freeze().castTo(); - testEq(val["arbitrary.sarr[1]value"].as(), 2.0); + testEq(val["arbitrary.sarr[1].value"].as(), 2.0); } // Union @@ -251,7 +251,7 @@ R"out( fld = arr.freeze().castTo(); testEq(fld["[0]"].as(), 123u); - testEq(fld["[1]q"].as(), "theq"); + testEq(fld["[1].q"].as(), "theq"); } testEq(std::string(SB()<