Skip to content

Commit a23fb9b

Browse files
committed
Added support for "verifyBeforeRead" property to <sync> suffix layer.
1 parent 2e5b8c8 commit a23fb9b

11 files changed

Lines changed: 286 additions & 6 deletions

File tree

app/commsdsl2comms/src/CommsSyncLayer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ std::string CommsSyncLayer::commsDefBaseTypeImpl(const std::string& prevName) co
133133
opts.push_back("comms::option::def::FrameLayerSeekField<" + escFieldOpt + ">");
134134
}
135135

136+
if (parseObj.parseVerifyBeforeRead()) {
137+
opts.push_back("comms::option::def::FrameLayerVerifyBeforeRead");
138+
}
139+
136140
util::GenReplacementMap repl = {
137141
{"FIELD_TYPE", commsDefFieldType()},
138142
{"PREV_LAYER", prevName},
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<schema name="test57" endian="big">
3+
<description>
4+
Testing sync suffix with verifyBeforeRead property
5+
</description>
6+
<fields>
7+
<enum name="MsgId" type="uint8" semanticType="messageId" >
8+
<validValue name="M1" val="0" />
9+
<validValue name="M2" val="1" />
10+
</enum>
11+
</fields>
12+
13+
<message name="Msg1" id="MsgId.M1">
14+
<data name="F1" />
15+
</message>
16+
17+
<message name="Msg2" id="MsgId.M2">
18+
<string name="F1" />
19+
</message>
20+
21+
<frame name="Frame">
22+
<sync name="Prefix">
23+
<int name="PrefixField" type="uint16" defaultValue="0x3d3d" />
24+
</sync>
25+
<size name="Size">
26+
<int name="SizeField" type="uint16" />
27+
</size>
28+
<id name="Id" field="MsgId" />
29+
<payload name="Data" />
30+
<sync name="Suffix" verifyBeforeRead="true" from="Id">
31+
<int name="SuffixField" type="uint16" defaultValue="0x4040" />
32+
</sync>
33+
</frame>
34+
</schema>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include "cxxtest/TestSuite.h"
2+
3+
#include "test57/Message.h"
4+
#include "test57/frame/Frame.h"
5+
6+
#include "comms/process.h"
7+
8+
#include <cstdint>
9+
#include <type_traits>
10+
11+
class TestSuite : public CxxTest::TestSuite
12+
{
13+
public:
14+
void test1();
15+
16+
// struct Handler
17+
// {
18+
// template <typename TMsg>
19+
// void handle(TMsg& msg)
20+
// {
21+
// static_cast<void>(msg);
22+
// }
23+
// };
24+
25+
using Interface = test57::Message<
26+
comms::option::app::IdInfoInterface,
27+
comms::option::app::LengthInfoInterface,
28+
comms::option::app::ReadIterator<const std::uint8_t*>,
29+
comms::option::app::WriteIterator<std::uint8_t*>,
30+
comms::option::app::NameInterface
31+
>;
32+
using Frame = test57::frame::Frame<Interface>;
33+
34+
TEST57_ALIASES_FOR_ALL_MESSAGES_DEFAULT_OPTIONS(,,Interface);
35+
};
36+
37+
void TestSuite::test1()
38+
{
39+
const std::uint8_t Buf[] = {
40+
0x3d, 0x3d, // Prefix
41+
0x00, 0x08,
42+
static_cast<std::uint8_t>(test57::MsgId_M2),
43+
'h', 'e', 'l', 'l', 'o',
44+
0x40, 0x40, // Suffix
45+
};
46+
const std::size_t BufSize = std::extent<decltype(Buf)>::value;
47+
48+
Frame frame;
49+
Frame::MsgPtr msgPtr;
50+
51+
auto iter = comms::readIteratorFor<Interface>(Buf);
52+
auto es = frame.read(msgPtr, iter, BufSize);
53+
TS_ASSERT_EQUALS(es, comms::ErrorStatus::Success);
54+
TS_ASSERT(msgPtr);
55+
TS_ASSERT_EQUALS(msgPtr->getId(), test57::MsgId_M2);
56+
57+
auto* msg2 = static_cast<const Msg2*>(msgPtr.get());
58+
TS_ASSERT_EQUALS(msg2->field_f1().value(), "hello");
59+
60+
std::vector<std::uint8_t> outputBuf;
61+
outputBuf.resize(frame.length(*msgPtr));
62+
63+
auto writeIter = comms::writeIteratorFor<Interface>(outputBuf.data());
64+
es = frame.write(*msgPtr, writeIter, outputBuf.size());
65+
TS_ASSERT_EQUALS(es, comms::ErrorStatus::Success);
66+
TS_ASSERT_EQUALS(outputBuf.size(), BufSize);
67+
TS_ASSERT(std::equal(outputBuf.begin(), outputBuf.end(), Buf));
68+
}
69+

lib/include/commsdsl/parse/ParseLayer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ class COMMSDSL_API ParseSyncLayer : public ParseLayer
117117
bool parseHasEscField() const;
118118
ParseField parseEscField() const;
119119
const std::string& parseFromLayer() const;
120+
bool parseVerifyBeforeRead() const;
120121
bool parseIsAfterPayload() const;
121122
};
122123

lib/src/parse/ParseLayer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ const std::string& ParseSyncLayer::parseFromLayer() const
216216
return asSync(m_pImpl)->parseFrom();
217217
}
218218

219+
bool ParseSyncLayer::parseVerifyBeforeRead() const
220+
{
221+
return asSync(m_pImpl)->parseVerifyBeforeRead();
222+
}
223+
219224
bool ParseSyncLayer::parseIsAfterPayload() const
220225
{
221226
return asSync(m_pImpl)->parseIsAfterPayload();

lib/src/parse/ParseSyncLayerImpl.cpp

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const ParseXmlWrap::ParseNamesList& ParseSyncLayerImpl::parseExtraPropsNamesImpl
4343
static const ParseXmlWrap::ParseNamesList Names = {
4444
common::parseSeekFieldStr(),
4545
common::parseFromStr(),
46+
common::parseVerifyBeforeReadStr(),
4647
};
4748

4849
return Names;
@@ -62,6 +63,7 @@ bool ParseSyncLayerImpl::parseImpl()
6263
return
6364
parseUpdateSeekFieldInternal() &&
6465
parseUpdateEscFieldInternal() &&
66+
parseUpdateVerifyBeforeReadInternal() &&
6567
parseUpdateFromInternal();
6668
}
6769

@@ -89,17 +91,17 @@ bool ParseSyncLayerImpl::parseVerifyImpl(const ParseLayersList& layers)
8991
}
9092

9193
// After payload
92-
if ((!m_seekField) && (parseFrom().empty())) {
93-
return true;
94-
}
95-
9694
if (m_seekField && parseFrom().empty()) {
9795
parseLogError() << ParseXmlWrap::parseLogPrefix(parseGetNode()) <<
9896
"The usage of \"" << common::parseFromStr() << "\" property is required when \""
9997
<< common::parseSeekFieldStr() << "\" property is set to true for <sync> after <payload>.";
10098
return false;
10199
}
102100

101+
if (parseFrom().empty()) {
102+
return true;
103+
}
104+
103105
auto fromIdx = parseFindLayerIndex(layers, parseFrom());
104106
if (layers.size() <= fromIdx) {
105107
parseReportUnexpectedPropertyValue(common::parseFromStr(), parseFrom());
@@ -172,6 +174,41 @@ bool ParseSyncLayerImpl::parseUpdateEscFieldInternal()
172174
return true;
173175
}
174176

177+
bool ParseSyncLayerImpl::parseUpdateVerifyBeforeReadInternal()
178+
{
179+
auto& prop = common::parseVerifyBeforeReadStr();
180+
if (!parseValidateSinglePropInstance(prop)) {
181+
return false;
182+
}
183+
184+
auto iter = parseProps().find(prop);
185+
if (iter == parseProps().end()) {
186+
return true;
187+
}
188+
189+
if (m_seekField) {
190+
parseLogError() << ParseXmlWrap::parseLogPrefix(parseGetNode()) <<
191+
"The properties \"" << prop << "\" and \"" << common::parseSeekFieldStr() << "\" are mutually exclusive.";
192+
return false;
193+
}
194+
195+
if (!parseProtocol().parseIsSyncSuffixLayerSupported()) {
196+
parseLogWarning() << ParseXmlWrap::parseLogPrefix(parseGetNode()) <<
197+
"Property \"" << prop << "\" of <sync> layer is not supported for selected dslVersion, ignoring...";
198+
m_from = nullptr;
199+
return true;
200+
}
201+
202+
bool ok = false;
203+
m_verifyBeforeRead = common::parseStrToBool(iter->second, &ok);
204+
if (!ok) {
205+
parseReportUnexpectedPropertyValue(prop, iter->second);
206+
return false;
207+
}
208+
209+
return true;
210+
}
211+
175212
bool ParseSyncLayerImpl::parseUpdateFromInternal()
176213
{
177214
auto& prop = common::parseFromStr();
@@ -183,9 +220,10 @@ bool ParseSyncLayerImpl::parseUpdateFromInternal()
183220
return true;
184221
}
185222

186-
if (!m_seekField) {
223+
if ((!m_seekField) && (!m_verifyBeforeRead)) {
187224
parseLogError() << ParseXmlWrap::parseLogPrefix(parseGetNode()) <<
188-
"The usage of \"" << prop << "\" is allowed only in conjunction with setting \"" << common::parseSeekFieldStr() << "\" to true.";
225+
"The usage of \"" << prop << "\" is allowed only in conjunction with setting \"" <<
226+
common::parseSeekFieldStr() << "\" or \"" << common::parseVerifyBeforeReadStr() << "\" to true.";
189227
return false;
190228
}
191229

lib/src/parse/ParseSyncLayerImpl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ class ParseSyncLayerImpl final : public ParseLayerImpl
5050
return m_seekField;
5151
}
5252

53+
bool parseVerifyBeforeRead() const
54+
{
55+
return m_verifyBeforeRead;
56+
}
57+
5358
const std::string& parseFrom() const
5459
{
5560
return *m_from;
@@ -70,6 +75,7 @@ class ParseSyncLayerImpl final : public ParseLayerImpl
7075
private:
7176
bool parseUpdateSeekFieldInternal();
7277
bool parseUpdateEscFieldInternal();
78+
bool parseUpdateVerifyBeforeReadInternal();
7379
bool parseUpdateFromInternal();
7480
bool parseCheckEscFieldFromRefInternal();
7581
bool parseCheckEscFieldAsChildInternal();
@@ -78,6 +84,7 @@ class ParseSyncLayerImpl final : public ParseLayerImpl
7884
ParseFieldImplPtr m_escField;
7985
const std::string* m_from = nullptr;
8086
bool m_seekField = false;
87+
bool m_verifyBeforeRead = false;
8188
bool m_afterPayload = false;
8289
};
8390

lib/test/frame/Schema38.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<schema name="Schema38" endian="big">
3+
<!-- Testing sync layer after <payload> with seekField and varifyBeforeRead -->
4+
<frame name="Frame">
5+
<sync name="Sync">
6+
<int name="Sync" type="uint16" defaultValue="0xabcd" />
7+
</sync>
8+
<size name="Size">
9+
<int name="Size" type="uint16" />
10+
</size>
11+
<id name="Id">
12+
<int name="Id" type="uint8" />
13+
</id>
14+
<payload name="Data" />
15+
<sync name="Sync2" seekField="true" from="Data" verifyBeforeRead="true">
16+
<int name="Sync2" type="uint16" defaultValue="0xdead" />
17+
</sync>
18+
</frame>
19+
</schema>

lib/test/frame/Schema39.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<schema name="Schema39" endian="big">
3+
<!-- Testing sync layer after <payload> with varifyBeforeRead -->
4+
<frame name="Frame">
5+
<sync name="Sync">
6+
<int name="Sync" type="uint16" defaultValue="0xabcd" />
7+
</sync>
8+
<size name="Size">
9+
<int name="Size" type="uint16" />
10+
</size>
11+
<id name="Id">
12+
<int name="Id" type="uint8" />
13+
</id>
14+
<payload name="Data" />
15+
<sync name="Sync2" verifyBeforeRead="true">
16+
<int name="Sync2" type="uint16" defaultValue="0xdead" />
17+
</sync>
18+
</frame>
19+
</schema>

lib/test/frame/Schema40.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<schema name="Schema40" endian="big">
3+
<!-- Testing sync layer after <payload> with varifyBeforeRead and from -->
4+
<frame name="Frame">
5+
<sync name="Sync">
6+
<int name="Sync" type="uint16" defaultValue="0xabcd" />
7+
</sync>
8+
<size name="Size">
9+
<int name="Size" type="uint16" />
10+
</size>
11+
<id name="Id">
12+
<int name="Id" type="uint8" />
13+
</id>
14+
<payload name="Data" />
15+
<sync name="Sync2" verifyBeforeRead="true" from="Id">
16+
<int name="Sync2" type="uint16" defaultValue="0xdead" />
17+
</sync>
18+
</frame>
19+
</schema>

0 commit comments

Comments
 (0)