Value traverse to Struct parent
This commit is contained in:
+20
-2
@@ -373,11 +373,29 @@ void Value::traverse(const std::string &expr, bool modify)
|
||||
{
|
||||
size_t pos=0;
|
||||
while(desc && pos<expr.size()) {
|
||||
if(expr[pos]=='<') {
|
||||
// attempt traverse to parent
|
||||
if(desc!=store->top->desc.get())
|
||||
{
|
||||
auto pdesc = desc - desc->parent_index;
|
||||
std::shared_ptr<FieldStorage> pstore(store, store.get() - desc->offset + pdesc->offset);
|
||||
store = std::move(pstore);
|
||||
desc = pdesc;
|
||||
pos++;
|
||||
continue;
|
||||
} else {
|
||||
// at top
|
||||
store.reset();
|
||||
desc = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(desc->code.code==TypeCode::Struct) {
|
||||
// attempt traverse to member.
|
||||
// expect: [0-9a-zA-Z_.]+[\[-$]
|
||||
size_t sep = expr.find_first_of("[-", pos);
|
||||
size_t sep = expr.find_first_of("<[-", pos);
|
||||
|
||||
decltype (desc->mlookup)::const_iterator it;
|
||||
|
||||
@@ -409,7 +427,7 @@ void Value::traverse(const std::string &expr, bool modify)
|
||||
|
||||
} else {
|
||||
// select member of Union
|
||||
size_t sep = expr.find_first_of("[-.", pos);
|
||||
size_t sep = expr.find_first_of("<[-.", pos);
|
||||
|
||||
decltype (desc->mlookup)::const_iterator it;
|
||||
|
||||
|
||||
@@ -163,6 +163,7 @@ void from_wire(Buffer& buf, TypeDeserContext& ctxt, unsigned depth)
|
||||
// descs may be re-allocated (invalidating previous refs.)
|
||||
auto& fld = ctxt.descs[index];
|
||||
auto& cfld = ctxt.descs[cindex];
|
||||
cfld.parent_index = cindex-index;
|
||||
|
||||
// update hash
|
||||
// TODO investigate better ways to combine hashes
|
||||
|
||||
@@ -69,6 +69,10 @@ struct FieldDesc {
|
||||
// number of FieldDesc nodes which describe this node and decendents. Inclusive. always >=1
|
||||
// eg. num_index+(FieldDesc*)this jumps to next sibling
|
||||
size_t num_index=0;
|
||||
// number of FieldDesc nodes between this node and it's a parent node (if any).
|
||||
// This value also appears in the parent's miter and mlookup mappings.
|
||||
// Only usable when a StructTop is accessible and this!=StructTop::desc
|
||||
size_t parent_index=0;
|
||||
TypeCode code{TypeCode::Null};
|
||||
|
||||
// number of FieldDesc nodes which describe this node. Inclusive. always size()>=1
|
||||
|
||||
+2
-2
@@ -196,6 +196,7 @@ void build_tree(std::vector<FieldDesc>& desc, const Member& node)
|
||||
|
||||
auto& fld = desc[index];
|
||||
auto& child = desc[cindex];
|
||||
child.parent_index = cindex-index;
|
||||
|
||||
fld.hash ^= std::hash<std::string>{}(cnode.name) ^ child.hash;
|
||||
|
||||
@@ -319,8 +320,7 @@ void FieldDesc_calculate_offset(FieldDesc* const top)
|
||||
{
|
||||
top->offset = 0;
|
||||
uint16_t offset = 1;
|
||||
size_t index = 1;
|
||||
while(index < top->size()) {
|
||||
for(size_t index = 1; index < top->size(); ) {
|
||||
auto& fld = top[index];
|
||||
|
||||
switch (fld.code.code) {
|
||||
|
||||
+21
-1
@@ -342,15 +342,35 @@ void testDeserialize2()
|
||||
}
|
||||
}
|
||||
|
||||
void testTraverse()
|
||||
{
|
||||
auto top = nt::NTScalar{TypeCode::Int32, true}.create();
|
||||
|
||||
testOk1(!top["<"].valid());
|
||||
|
||||
{
|
||||
auto top2 = top["value<"];
|
||||
testOk1(top.compareType(top2));
|
||||
testOk1(top.compareInst(top2));
|
||||
}
|
||||
{
|
||||
auto sevr1 = top["alarm.severity"];
|
||||
auto sevr2 = top["value<alarm.status<severity"];
|
||||
testOk1(sevr1.compareType(sevr2));
|
||||
testOk1(sevr1.compareInst(sevr2));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MAIN(testdata)
|
||||
{
|
||||
testPlan(58);
|
||||
testPlan(63);
|
||||
testSerialize1();
|
||||
testDeserialize1();
|
||||
testSerialize2();
|
||||
testDeserialize2();
|
||||
testTraverse();
|
||||
cleanup_for_valgrind();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user