Skip to content

Commit 84fa21f

Browse files
committed
Fixes to handling GenericMessage in framing.
1 parent d108073 commit 84fa21f

6 files changed

Lines changed: 107 additions & 5 deletions

File tree

include/comms/MessageBase.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,13 @@ class MessageBase : public details::MessageImplBuilderT<TMessage, TOptions...>
184184
static constexpr bool hasCustomName()
185185
{
186186
return ImplOptions::HasName;
187-
}
187+
}
188+
189+
/// @brief Compile type inquiry whether the class provides @ref doGetId() member function.
190+
static constexpr bool hasDoGetId()
191+
{
192+
return ImplOptions::HasStaticMsgId || ImplOptions::HasDoGetId;
193+
}
188194

189195
#ifdef FOR_DOXYGEN_DOC_ONLY
190196

include/comms/frame/MsgIdLayer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,10 @@ class MsgIdLayer : public comms::frame::details::MsgIdLayerBase<TField, TMessage
601601
using MsgType = typename std::decay<decltype(msg)>::type;
602602
static_assert(comms::isMessageBase<MsgType>(),
603603
"The message class is expected to inherit from comms::MessageBase");
604-
static_assert(MsgType::hasStaticMsgId(),
604+
static_assert(MsgType::hasDoGetId(),
605605
"The message class must expose direct ID retrieval functionality, "
606-
"use comms::option::app::StaticNumIdImpl option to define it.");
606+
"use comms::option::app::StaticNumIdImpl option to define it or "
607+
"comms::option::app::HasDoGetId option to mark the class as providing one");
607608
return msg.doGetId();
608609
}
609610

include/comms/frame/details/FrameLayerDetails.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ struct FrameLayerHasDoGetIdHelper;
5252
template <typename T>
5353
struct FrameLayerHasDoGetIdHelper<T, true>
5454
{
55-
static const bool Value = T::hasStaticMsgId();
55+
static const bool Value = T::hasDoGetId();
5656
};
5757

5858
template <typename T>

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ if (TARGET cxxtest::cxxtest)
5858
test_func ("CustomSyncPrefixLayer")
5959
test_func ("Dispatch")
6060
test_func ("MsgFactory")
61+
test_func ("GenericMessage")
6162
else ()
6263
message (Warning "Testing is enabled, but cxxtest hasn't been found!")
6364
endif ()

test/CustomMsgIdLayer.th

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ private:
210210
>;
211211
public:
212212
COMMS_FRAME_LAYERS_NAMES_OUTER(id, payload);
213-
};
213+
};
214214
};
215215

216216
void CustomMsgIdLayerTestSuite::test1()

test/GenericMessage.th

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//
2+
// Copyright 2025 - 2025 (C). Alex Robenko. All rights reserved.
3+
//
4+
// This Source Code Form is subject to the terms of the Mozilla Public
5+
// License, v. 2.0. If a copy of the MPL was not distributed with this
6+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
8+
#include "CommsTestCommon.h"
9+
10+
#include "comms/CompileControl.h"
11+
#include "comms/GenericMessage.h"
12+
#include "comms/frame/MsgIdLayer.h"
13+
#include "comms/frame/MsgDataLayer.h"
14+
15+
CC_DISABLE_WARNINGS()
16+
#include "cxxtest/TestSuite.h"
17+
CC_ENABLE_WARNINGS()
18+
19+
class GenericMessageTestSuite : public CxxTest::TestSuite
20+
{
21+
public:
22+
void test1();
23+
24+
private:
25+
using BeFieldBase = comms::Field<comms::option::BigEndian>;
26+
using BeIdField1 = comms::field::EnumValue<BeFieldBase, MessageType, comms::option::def::FixedLength<1U>>;
27+
28+
template <typename... TOpts>
29+
using BeMsgBase =
30+
comms::Message<
31+
comms::option::BigEndian,
32+
TOpts...
33+
>;
34+
35+
using BePolymorphicMsgBase =
36+
BeMsgBase<
37+
comms::option::MsgIdType<MessageType>,
38+
comms::option::IdInfoInterface,
39+
comms::option::ReadIterator<const char*>,
40+
comms::option::WriteIterator<char*>,
41+
comms::option::ValidCheckInterface,
42+
comms::option::LengthInfoInterface
43+
>;
44+
45+
46+
template <typename TIdField, typename TMessage, template<class> class TAllMessages = AllTestMessages>
47+
class SimpleFrame : public
48+
comms::frame::MsgIdLayer<
49+
TIdField,
50+
TMessage,
51+
TAllMessages<TMessage>,
52+
comms::frame::MsgDataLayer<>,
53+
comms::option::SupportGenericMessage<comms::GenericMessage<TMessage> >
54+
>
55+
{
56+
using Base =
57+
comms::frame::MsgIdLayer<
58+
TIdField,
59+
TMessage,
60+
TAllMessages<TMessage>,
61+
comms::frame::MsgDataLayer<>,
62+
comms::option::SupportGenericMessage<comms::GenericMessage<TMessage> >
63+
>;
64+
public:
65+
COMMS_FRAME_LAYERS_NAMES_OUTER(id, payload);
66+
};
67+
};
68+
69+
void GenericMessageTestSuite::test1()
70+
{
71+
using Msg = comms::GenericMessage<BePolymorphicMsgBase>;
72+
using TestFrame = SimpleFrame<BeIdField1, BePolymorphicMsgBase>;
73+
74+
TestFrame frame;
75+
Msg msg(MessageType5);
76+
77+
static const char Buf[] = {
78+
MessageType5, 0x01, 0x02, 0x03,
79+
};
80+
81+
static const std::size_t BufSize = std::extent<decltype(Buf)>::value;
82+
83+
auto iter = comms::readIteratorFor(msg, Buf);
84+
auto es = frame.read(msg, iter, BufSize);
85+
TS_ASSERT_EQUALS(es, comms::ErrorStatus::Success);
86+
87+
std::vector<char> outBuf;
88+
outBuf.reserve(BufSize);
89+
auto outIter = std::back_inserter(outBuf);
90+
es = frame.write(msg, outIter, outBuf.max_size());
91+
TS_ASSERT_EQUALS(es, comms::ErrorStatus::Success);
92+
TS_ASSERT_EQUALS(outBuf.size(), BufSize);
93+
TS_ASSERT(std::equal(outBuf.begin(), outBuf.end(), std::begin(Buf)));
94+
}

0 commit comments

Comments
 (0)