COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
SyncPrefixLayer.h
Go to the documentation of this file.
1//
2// Copyright 2015 - 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
10
11#pragma once
12
14#include "comms/protocol/details/ProtocolLayerBase.h"
15#include "comms/protocol/details/SyncPrefixLayerOptionsParser.h"
16#include "comms/protocol/details/ProtocolLayerExtendingClassHelper.h"
17
18#include <iterator>
19
20COMMS_MSVC_WARNING_PUSH
21COMMS_MSVC_WARNING_DISABLE(4189) // Disable erroneous initialized but not referenced variable warning
22
23namespace comms
24{
25
26namespace protocol
27{
28
44template <typename TField, typename TNextLayer, typename... TOptions>
45class SyncPrefixLayer : public
47 TField,
48 TNextLayer,
49 details::ProtocolLayerExtendingClassT<
50 SyncPrefixLayer<TField, TNextLayer, TOptions...>,
51 details::SyncPrefixLayerOptionsParser<TOptions...>
52 >
53 >
54{
55 using BaseImpl =
57 TField,
58 TNextLayer,
59 details::ProtocolLayerExtendingClassT<
60 SyncPrefixLayer<TField, TNextLayer, TOptions...>,
61 details::SyncPrefixLayerOptionsParser<TOptions...>
62 >
63 >;
64
65 using ParsedOptionsInternal = details::SyncPrefixLayerOptionsParser<TOptions...>;
66
67public:
69 using Field = typename BaseImpl::Field;
70
74 using ExtendingClass = typename ParsedOptionsInternal::ExtendingClass;
75
77 SyncPrefixLayer() = default;
78
81
84
86 ~SyncPrefixLayer() noexcept = default;
87
92 static constexpr bool hasExtendingClass()
93 {
94 return ParsedOptionsInternal::HasExtendingClass;
95 }
96
125 template <typename TMsg, typename TIter, typename TNextLayerReader, typename... TExtraValues>
127 Field& field,
128 TMsg& msg,
129 TIter& iter,
130 std::size_t size,
131 TNextLayerReader&& nextLayerReader,
132 TExtraValues... extraValues)
133 {
134 auto& thisObj = BaseImpl::thisLayer();
135 auto* msgPtr = BaseImpl::toMsgPtr(msg);
136 auto beforeReadIter = iter;
137
138 auto es = thisObj.doReadField(msgPtr, field, iter, size);
140 BaseImpl::updateMissingSize(field, size, extraValues...);
141 }
142
143 if (es != comms::ErrorStatus::Success) {
144 return es;
145 }
146
147 bool verified = thisObj.verifyFieldValue(field);
148 if (!verified) {
150 }
151
152 auto fieldLen = static_cast<std::size_t>(std::distance(beforeReadIter, iter));
153 return nextLayerReader.read(msg, iter, size - fieldLen, extraValues...);
154 }
155
173 template <typename TMsg, typename TIter, typename TNextLayerWriter>
175 Field& field,
176 const TMsg& msg,
177 TIter& iter,
178 std::size_t size,
179 TNextLayerWriter&& nextLayerWriter) const
180 {
181 auto& thisObj = BaseImpl::thisLayer();
182 thisObj.prepareFieldForWrite(field);
183 auto es = thisObj.doWriteField(&msg, field, iter, size);
184 if (es != ErrorStatus::Success) {
185 return es;
186 }
187
188 COMMS_ASSERT(field.length() <= size);
189 return nextLayerWriter.write(msg, iter, size - field.length());
190 }
191
192protected:
199 static bool verifyFieldValue(const Field& field)
200 {
201 return field == Field();
202 }
203
211 static void prepareFieldForWrite(Field& field)
212 {
213 static_cast<void>(field);
214 }
215};
216
217namespace details
218{
219template <typename T>
220struct SyncPrefixLayerCheckHelper
221{
222 static const bool Value = false;
223};
224
225template <typename TField, typename TNextLayer>
226struct SyncPrefixLayerCheckHelper<SyncPrefixLayer<TField, TNextLayer> >
227{
228 static const bool Value = true;
229};
230
231} // namespace details
232
236template <typename T>
237constexpr bool isSyncPrefixLayer()
238{
239 return details::SyncPrefixLayerCheckHelper<T>::Value;
240}
241
242} // namespace protocol
243
244} // namespace comms
245
246COMMS_MSVC_WARNING_POP
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
Contains various compiler related definitions.
Base class for all the middle (non MsgDataLayer) protocol transport layers.
Definition ProtocolLayerBase.h:61
Protocol layer that uses "sync" field as a prefix to all the subsequent data written by other (next) ...
Definition SyncPrefixLayer.h:54
SyncPrefixLayer(const SyncPrefixLayer &)=default
Copy constructor.
typename ParsedOptionsInternal::ExtendingClass ExtendingClass
Type of real extending class.
Definition SyncPrefixLayer.h:74
typename BaseImpl::Field Field
Type of the field object used to read/write "sync" value.
Definition SyncPrefixLayer.h:69
constexpr bool isSyncPrefixLayer()
Compile time check of whether the provided type is a variant of SyncPrefixLayer.
Definition SyncPrefixLayer.h:237
comms::ErrorStatus doWrite(Field &field, const TMsg &msg, TIter &iter, std::size_t size, TNextLayerWriter &&nextLayerWriter) const
Customized write functionality, invoked by write().
Definition SyncPrefixLayer.h:174
static bool verifyFieldValue(const Field &field)
Verify the validity of the field.
Definition SyncPrefixLayer.h:199
SyncPrefixLayer()=default
Default constructor.
comms::ErrorStatus doRead(Field &field, TMsg &msg, TIter &iter, std::size_t size, TNextLayerReader &&nextLayerReader, TExtraValues... extraValues)
Customized read functionality, invoked by read().
Definition SyncPrefixLayer.h:126
SyncPrefixLayer(SyncPrefixLayer &&)=default
Move constructor.
~SyncPrefixLayer() noexcept=default
Destructor.
static void prepareFieldForWrite(Field &field)
Prepare field for writing.
Definition SyncPrefixLayer.h:211
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
@ Success
Used to indicate successful outcome of the operation.