Skip to content

Commit 3dd8ffa

Browse files
committed
[C++]: OTF decode for compoites with sets, enums, and nested composites.
1 parent 92b5300 commit 3dd8ffa

File tree

2 files changed

+117
-39
lines changed

2 files changed

+117
-39
lines changed

sbe-tool/src/main/cpp/otf/OtfMessageDecoder.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,32 @@ static void decodeComposite(
161161
{
162162
listener.onBeginComposite(fieldToken, *tokens.get(), tokenIndex, toIndex);
163163

164-
for (size_t i = tokenIndex + 1; i < toIndex; i++)
164+
for (size_t i = tokenIndex + 1; i < toIndex;)
165165
{
166166
Token &token = tokens->at(i);
167-
listener.onEncoding(token, buffer + bufferIndex + token.offset(), token, actingVersion);
167+
const size_t nextFieldIndex = i + token.componentTokenCount();
168+
169+
const std::size_t offset = static_cast<std::size_t>(token.offset());
170+
171+
switch (token.signal())
172+
{
173+
case Signal::BEGIN_COMPOSITE:
174+
decodeComposite(fieldToken, buffer, bufferIndex + offset, length, tokens, i, nextFieldIndex - 1, actingVersion, listener);
175+
break;
176+
case Signal::BEGIN_ENUM:
177+
listener.onEnum(fieldToken, buffer + bufferIndex + offset, *tokens.get(), i, nextFieldIndex - 1, actingVersion);
178+
break;
179+
case Signal::BEGIN_SET:
180+
listener.onBitSet(fieldToken, buffer + bufferIndex + offset, *tokens.get(), i, nextFieldIndex - 1, actingVersion);
181+
break;
182+
case Signal::ENCODING:
183+
listener.onEncoding(token, buffer + bufferIndex + offset, token, actingVersion);
184+
break;
185+
default:
186+
throw std::runtime_error("incorrect signal type in decodeComposite");
187+
}
188+
189+
i += token.componentTokenCount();
168190
}
169191

170192
listener.onEndComposite(fieldToken, *tokens.get(), tokenIndex, toIndex);

sbe-tool/src/test/cpp/CompositeElementsTest.cpp

Lines changed: 93 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,19 @@ using namespace std;
2626
using namespace composite_elements;
2727
using namespace sbe::otf;
2828

29+
enum EventNumber
30+
{
31+
EN_beginOuter = 0,
32+
EN_enumOne,
33+
EN_zeroth,
34+
EN_setOne,
35+
EN_beginInner,
36+
EN_innerFirst,
37+
EN_innerSecond,
38+
EN_endInner,
39+
EN_endOuter
40+
};
41+
2942
class CompositeElementsTest : public testing::Test, public OtfMessageDecoder::BasicTokenListener
3043
{
3144
public:
@@ -64,46 +77,72 @@ class CompositeElementsTest : public testing::Test, public OtfMessageDecoder::Ba
6477
return hdr.encodedLength() + msg.encodedLength();
6578
}
6679

80+
virtual void onBeginComposite(
81+
Token &fieldToken,
82+
std::vector<Token> &tokens,
83+
std::size_t fromIndex,
84+
std::size_t toIndex)
85+
{
86+
switch (EventNumber(m_eventNumber++))
87+
{
88+
case EN_beginOuter:
89+
EXPECT_EQ(tokens.at(fromIndex).name(), "outer");
90+
break;
91+
case EN_beginInner:
92+
EXPECT_EQ(tokens.at(fromIndex).name(), "inner");
93+
break;
94+
default:
95+
FAIL() << "unknown beginComposite event number " << m_eventNumber - 1;
96+
}
97+
}
98+
99+
virtual void onEndComposite(
100+
Token &fieldToken,
101+
std::vector<Token> &tokens,
102+
std::size_t fromIndex,
103+
std::size_t toIndex)
104+
{
105+
switch (EventNumber(m_eventNumber++))
106+
{
107+
case EN_endInner:
108+
EXPECT_EQ(tokens.at(fromIndex).name(), "inner");
109+
break;
110+
case EN_endOuter:
111+
EXPECT_EQ(tokens.at(fromIndex).name(), "outer");
112+
break;
113+
default:
114+
FAIL() << "unknown endComposite event number " << m_eventNumber - 1;
115+
}
116+
}
117+
67118
virtual void onEncoding(
68119
Token& fieldToken,
69120
const char *buffer,
70121
Token& typeToken,
71122
std::uint64_t actingVersion)
72123
{
73-
switch (m_eventNumber++)
124+
switch (EventNumber(m_eventNumber++))
74125
{
75-
case 0:
76-
{
77-
EXPECT_EQ(typeToken.encoding().primitiveType(), PrimitiveType::UINT64);
78-
EXPECT_EQ(typeToken.encoding().getAsUInt(buffer), 187u);
79-
break;
80-
}
81-
case 3:
126+
case EN_zeroth:
82127
{
83-
EXPECT_EQ(typeToken.encoding().primitiveType(), PrimitiveType::UINT64);
84-
EXPECT_EQ(typeToken.encoding().getAsUInt(buffer), 10u);
128+
EXPECT_EQ(typeToken.encoding().primitiveType(), PrimitiveType::UINT8);
129+
EXPECT_EQ(typeToken.encoding().getAsUInt(buffer), 42u);
85130
break;
86131
}
87-
case 4:
132+
case EN_innerFirst:
88133
{
89134
EXPECT_EQ(typeToken.encoding().primitiveType(), PrimitiveType::INT64);
90-
EXPECT_EQ(typeToken.encoding().getAsInt(buffer), 20);
135+
EXPECT_EQ(typeToken.encoding().getAsInt(buffer), 101l);
91136
break;
92137
}
93-
case 5:
94-
{
95-
EXPECT_EQ(typeToken.encoding().primitiveType(), PrimitiveType::UINT64);
96-
EXPECT_EQ(typeToken.encoding().getAsUInt(buffer), 30u);
97-
break;
98-
}
99-
case 6:
138+
case EN_innerSecond:
100139
{
101140
EXPECT_EQ(typeToken.encoding().primitiveType(), PrimitiveType::INT64);
102-
EXPECT_EQ(typeToken.encoding().getAsInt(buffer), 40);
141+
EXPECT_EQ(typeToken.encoding().getAsInt(buffer), 202l);
103142
break;
104143
}
105144
default:
106-
FAIL() << "unknown event number " << m_eventNumber;
145+
FAIL() << "unknown Encoding event number " << m_eventNumber - 1;
107146
}
108147

109148
}
@@ -116,35 +155,52 @@ class CompositeElementsTest : public testing::Test, public OtfMessageDecoder::Ba
116155
std::size_t toIndex,
117156
std::uint64_t actingVersion)
118157
{
119-
switch (m_eventNumber++)
158+
switch (EventNumber(m_eventNumber++))
120159
{
121-
case 1:
160+
case EN_setOne:
122161
{
123162
const Token& typeToken = tokens.at(fromIndex + 1);
124163
const Encoding& encoding = typeToken.encoding();
125164

126-
EXPECT_EQ(encoding.primitiveType(), PrimitiveType::UINT8);
127-
EXPECT_EQ(encoding.getAsUInt(buffer), 0x2u);
165+
EXPECT_EQ(encoding.primitiveType(), PrimitiveType::UINT32);
166+
EXPECT_EQ(encoding.getAsUInt(buffer), 0x00010000u);
167+
168+
EXPECT_EQ(tokens.at(fromIndex+1).name(), "Bit0");
169+
EXPECT_EQ(tokens.at(fromIndex+2).name(), "Bit16");
170+
EXPECT_EQ(tokens.at(fromIndex+3).name(), "Bit26");
171+
EXPECT_EQ(toIndex - 1 - fromIndex, 3u);
128172
break;
129173
}
130174
default:
131-
FAIL() << "unknown event number " << m_eventNumber;
175+
FAIL() << "unknown BitSet event number " << m_eventNumber - 1;
132176
}
133177
}
134178

135-
virtual void onGroupHeader(
136-
Token& token,
137-
std::uint64_t numInGroup)
179+
virtual void onEnum(
180+
Token &fieldToken,
181+
const char *buffer,
182+
std::vector<Token> &tokens,
183+
std::size_t fromIndex,
184+
std::size_t toIndex,
185+
std::uint64_t actingVersion)
138186
{
139-
switch (m_eventNumber++)
187+
switch (EventNumber(m_eventNumber++))
140188
{
141-
case 2:
189+
case EN_enumOne:
142190
{
143-
EXPECT_EQ(numInGroup, 2u);
191+
const Token& typeToken = tokens.at(fromIndex + 1);
192+
const Encoding& encoding = typeToken.encoding();
193+
194+
EXPECT_EQ(encoding.primitiveType(), PrimitiveType::UINT8);
195+
EXPECT_EQ(encoding.getAsUInt(buffer), 10u);
196+
197+
EXPECT_EQ(tokens.at(fromIndex+1).name(), "Value1");
198+
EXPECT_EQ(tokens.at(fromIndex+2).name(), "Value10");
199+
EXPECT_EQ(toIndex - 1 - fromIndex, 2u);
144200
break;
145201
}
146202
default:
147-
FAIL() << "unknown event number " << m_eventNumber;
203+
FAIL() << "unknown Enum event number " << m_eventNumber - 1;
148204
}
149205
}
150206
};
@@ -213,7 +269,7 @@ TEST_F(CompositeElementsTest, shouldEncodeAndDecodeMsgCorrectly)
213269
EXPECT_EQ(msg.encodedLength(), sz - MessageHeader::encodedLength());
214270
}
215271

216-
TEST_F(CompositeElementsTest, DISABLED_shouldHandleAllEventsCorrectltInOrder)
272+
TEST_F(CompositeElementsTest, shouldHandleAllEventsCorrectltInOrder)
217273
{
218274
std::uint64_t sz = encodeHdrAndMsg();
219275

@@ -231,13 +287,13 @@ TEST_F(CompositeElementsTest, DISABLED_shouldHandleAllEventsCorrectltInOrder)
231287

232288
EXPECT_EQ(headerDecoder.encodedLength(), MessageHeader::encodedLength());
233289
const char *messageBuffer = m_buffer + headerDecoder.encodedLength();
234-
std::size_t length = MessageHeader::encodedLength() - headerDecoder.encodedLength();
290+
std::size_t length = sz - headerDecoder.encodedLength();
235291
std::uint64_t actingVersion = headerDecoder.getSchemaVersion(m_buffer);
236292
std::uint64_t blockLength = headerDecoder.getBlockLength(m_buffer);
237293

238294
const std::size_t result =
239295
OtfMessageDecoder::decode(messageBuffer, length, actingVersion, blockLength, messageTokens, *this);
240-
EXPECT_EQ(result, static_cast<std::size_t>(Msg::sbeBlockLength() - MessageHeader::encodedLength()));
296+
EXPECT_EQ(result, static_cast<std::size_t>(Msg::sbeBlockLength()));
241297

242-
EXPECT_EQ(m_eventNumber, 7);
298+
EXPECT_EQ(m_eventNumber, 9);
243299
}

0 commit comments

Comments
 (0)