Skip to content

Commit 0892def

Browse files
committed
Fixes to <variant> read functionality when member has non-trivial read.
Fix to #34 github issue.
1 parent 2f7c259 commit 0892def

5 files changed

Lines changed: 69 additions & 2 deletions

File tree

app/commsdsl2comms/src/CommsField.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,11 @@ bool CommsField::commsHasCustomValue() const
401401
return m_customCode.m_hasValue;
402402
}
403403

404+
bool CommsField::commsHasCustomRead() const
405+
{
406+
return (m_customCode.m_hasRead) || (!commsDefReadFuncBodyImpl().empty());
407+
}
408+
404409
bool CommsField::commsHasCustomValid() const
405410
{
406411
return (m_customCode.m_hasValid) || (!commsDefValidFuncBodyImpl().empty());

app/commsdsl2comms/src/CommsField.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class CommsField
9191
std::string commsBareMetalDefaultOptions() const;
9292

9393
bool commsHasCustomValue() const;
94+
bool commsHasCustomRead() const;
9495
bool commsHasCustomValid() const;
9596
bool commsHasCustomLength(bool deepCheck = true) const;
9697
const CommsField* commsFindSibling(const std::string& name) const;

app/commsdsl2comms/src/CommsVariantField.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,22 +360,32 @@ std::string CommsVariantField::commsDefReadFuncBodyImpl() const
360360
static const std::string Templ =
361361
"case #^#VAL#$#:\n"
362362
" {\n"
363+
" #^#ADJUST_ITER#$#\n"
364+
" #^#ADJUST_LEN#$#\n"
363365
" auto& field_#^#BUNDLE_NAME#$# = initField_#^#BUNDLE_NAME#$#();\n"
364366
" COMMS_ASSERT(field_#^#BUNDLE_NAME#$#.field_#^#KEY_NAME#$#().getValue() == commonKeyField.getValue());\n"
365367
" #^#VERSION_ASSIGN#$#\n"
366-
" return field_#^#BUNDLE_NAME#$#.template readFrom<1>(iter, len);\n"
368+
" return field_#^#BUNDLE_NAME#$#.#^#READ#$#(iter, len);\n"
367369
" }";
368370

369371
util::GenReplacementMap repl = {
370372
{"VAL", std::move(valStr)},
371373
{"BUNDLE_NAME", bundleAccName},
372374
{"KEY_NAME", keyAccName},
375+
{"READ", "template readFrom<1>"},
373376
};
374377

375378
if (m->commsIsVersionDependent()) {
376379
auto assignStr = "field_" + bundleAccName + ".setVersion(Base::getVersion());";
377380
repl["VERSION_ASSIGN"] = std::move(assignStr);
378381
}
382+
383+
if (m->commsHasCustomRead()) {
384+
repl["ADJUST_ITER"] = "iter = origIter;";
385+
repl["ADJUST_LEN"] = "len += consumedLen;";
386+
repl["READ"] = "read";
387+
}
388+
379389
cases.push_back(util::genProcessTemplate(Templ, repl));
380390
continue;
381391
}
@@ -385,20 +395,29 @@ std::string CommsVariantField::commsDefReadFuncBodyImpl() const
385395

386396
static const std::string Templ =
387397
"default:\n"
398+
" #^#ADJUST_ITER#$#\n"
399+
" #^#ADJUST_LEN#$#\n"
388400
" initField_#^#BUNDLE_NAME#$#().field_#^#KEY_NAME#$#().setValue(commonKeyField.getValue());\n"
389401
" #^#VERSION_ASSIGN#$#\n"
390-
" return accessField_#^#BUNDLE_NAME#$#().template readFrom<1>(iter, len);";
402+
" return accessField_#^#BUNDLE_NAME#$#().#^#READ#$#(iter, len);";
391403

392404
util::GenReplacementMap repl = {
393405
{"BUNDLE_NAME", bundleAccName},
394406
{"KEY_NAME", keyAccName},
407+
{"READ", "template readFrom<1>"},
395408
};
396409

397410
if (m->commsIsVersionDependent()) {
398411
auto assignStr = "field_" + bundleAccName + ".setVersion(Base::getVersion());";
399412
repl["VERSION_ASSIGN"] = std::move(assignStr);
400413
}
401414

415+
if (m->commsHasCustomRead()) {
416+
repl["ADJUST_ITER"] = "iter = origIter;";
417+
repl["ADJUST_LEN"] = "len += consumedLen;";
418+
repl["READ"] = "read";
419+
}
420+
402421
cases.push_back(util::genProcessTemplate(Templ, repl));
403422
hasDefault = true;
404423
}

app/commsdsl2comms/test/test28/Schema.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@
1515
<int name="type" type="uint8" defaultValidValue="1" failOnInvalid="true" fixedValue="true" />
1616
<int name="val" type="uint8" />
1717
</bundle>
18+
<bundle name="P3">
19+
<int name="type" type="uint8" defaultValidValue="2" failOnInvalid="true" fixedValue="true" />
20+
<set name="flags" length="1">
21+
<bit name="V1Present" idx="0" />
22+
<bit name="V2Present" idx="1" />
23+
</set>
24+
<optional name="v1" cond="$flags.V1Present" defaultMode="missing">
25+
<int name="ActV1" type="uint8" />
26+
</optional>
27+
<optional name="v2" cond="$flags.V2Present" defaultMode="missing">
28+
<int name="ActV2" type="uint8" />
29+
</optional>
30+
</bundle>
1831
</variant>
1932

2033
<variant name="Variant2" reuse="Variant1" defaultMember="P1" />
@@ -602,6 +615,10 @@
602615
<ref field="Variant3" name="F1" />
603616
</message>
604617

618+
<message name="Msg3" id="MsgId.M3">
619+
<ref field="Variant1" name="F1" />
620+
</message>
621+
605622
<frame name="Frame">
606623
<id name="ID" field="MsgId" />
607624
<payload name="Data" />

app/commsdsl2comms/test/test28/test28Test.th

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public:
1212
void test1();
1313
void test2();
1414
void test3();
15+
void test4();
1516

1617
using Interface =
1718
test28::Message<
@@ -65,3 +66,27 @@ void TestSuite::test3()
6566
msg.field_variant1().selectField(1U);
6667
TS_ASSERT_EQUALS(msg.field_variant1().currentField(), 1U);
6768
}
69+
70+
void TestSuite::test4()
71+
{
72+
static const std::uint8_t Buf1[] =
73+
{
74+
3, 2, 0x3, 1, 2
75+
};
76+
static const std::size_t Buf1Size = std::extent<decltype(Buf1)>::value;
77+
78+
Frame::MsgPtr msgPtr;
79+
Frame frame;
80+
81+
auto readIter = comms::readIteratorFor<Interface>(&Buf1[0]);
82+
auto es = frame.read(msgPtr, readIter, Buf1Size);
83+
TS_ASSERT_EQUALS(es, comms::ErrorStatus::Success);
84+
TS_ASSERT(msgPtr);
85+
TS_ASSERT_EQUALS(msgPtr->getId(), test28::MsgId_M3);
86+
auto* msg = static_cast<const Msg3*>(msgPtr.get());
87+
TS_ASSERT_EQUALS(msg->field_f1().currentField(), 2U);
88+
TS_ASSERT(msg->field_f1().accessField_p3().field_v1().doesExist());
89+
TS_ASSERT_EQUALS(msg->field_f1().accessField_p3().field_v1().field().value(), 1);
90+
TS_ASSERT(msg->field_f1().accessField_p3().field_v2().doesExist());
91+
TS_ASSERT_EQUALS(msg->field_f1().accessField_p3().field_v2().field().value(), 2);
92+
}

0 commit comments

Comments
 (0)