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 - 2024 (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
18COMMS_MSVC_WARNING_PUSH
19COMMS_MSVC_WARNING_DISABLE(4189) // Disable erroneous initialized but not referenced variable warning
20
21namespace comms
22{
23
24namespace protocol
25{
26
42template <typename TField, typename TNextLayer, typename... TOptions>
43class SyncPrefixLayer : public
45 TField,
46 TNextLayer,
47 details::ProtocolLayerExtendingClassT<
48 SyncPrefixLayer<TField, TNextLayer, TOptions...>,
49 details::SyncPrefixLayerOptionsParser<TOptions...>
50 >
51 >
52{
53 using BaseImpl =
55 TField,
56 TNextLayer,
57 details::ProtocolLayerExtendingClassT<
58 SyncPrefixLayer<TField, TNextLayer, TOptions...>,
59 details::SyncPrefixLayerOptionsParser<TOptions...>
60 >
61 >;
62
63 using ParsedOptionsInternal = details::SyncPrefixLayerOptionsParser<TOptions...>;
64
65public:
67 using Field = typename BaseImpl::Field;
68
72 using ExtendingClass = typename ParsedOptionsInternal::ExtendingClass;
73
75 SyncPrefixLayer() = default;
76
79
82
84 ~SyncPrefixLayer() noexcept = default;
85
90 static constexpr bool hasExtendingClass()
91 {
92 return ParsedOptionsInternal::HasExtendingClass;
93 }
94
123 template <typename TMsg, typename TIter, typename TNextLayerReader, typename... TExtraValues>
125 Field& field,
126 TMsg& msg,
127 TIter& iter,
128 std::size_t size,
129 TNextLayerReader&& nextLayerReader,
130 TExtraValues... extraValues)
131 {
132 auto& thisObj = BaseImpl::thisLayer();
133 auto* msgPtr = BaseImpl::toMsgPtr(msg);
134 auto beforeReadIter = iter;
135
136 auto es = thisObj.doReadField(msgPtr, field, iter, size);
138 BaseImpl::updateMissingSize(field, size, extraValues...);
139 }
140
141 if (es != comms::ErrorStatus::Success) {
142 return es;
143 }
144
145 bool verified = thisObj.verifyFieldValue(field);
146 if (!verified) {
148 }
149
150 auto fieldLen = static_cast<std::size_t>(std::distance(beforeReadIter, iter));
151 return nextLayerReader.read(msg, iter, size - fieldLen, extraValues...);
152 }
153
171 template <typename TMsg, typename TIter, typename TNextLayerWriter>
173 Field& field,
174 const TMsg& msg,
175 TIter& iter,
176 std::size_t size,
177 TNextLayerWriter&& nextLayerWriter) const
178 {
179 auto& thisObj = BaseImpl::thisLayer();
180 thisObj.prepareFieldForWrite(field);
181 auto es = thisObj.doWriteField(&msg, field, iter, size);
182 if (es != ErrorStatus::Success) {
183 return es;
184 }
185
186 COMMS_ASSERT(field.length() <= size);
187 return nextLayerWriter.write(msg, iter, size - field.length());
188 }
189
190protected:
197 static bool verifyFieldValue(const Field& field)
198 {
199 return field == Field();
200 }
201
209 static void prepareFieldForWrite(Field& field)
210 {
211 static_cast<void>(field);
212 }
213};
214
215namespace details
216{
217template <typename T>
218struct SyncPrefixLayerCheckHelper
219{
220 static const bool Value = false;
221};
222
223template <typename TField, typename TNextLayer>
224struct SyncPrefixLayerCheckHelper<SyncPrefixLayer<TField, TNextLayer> >
225{
226 static const bool Value = true;
227};
228
229} // namespace details
230
234template <typename T>
235constexpr bool isSyncPrefixLayer()
236{
237 return details::SyncPrefixLayerCheckHelper<T>::Value;
238}
239
240} // namespace protocol
241
242} // namespace comms
243
244COMMS_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
TField Field
Type of the field used for this layer.
Definition ProtocolLayerBase.h:64
Protocol layer that uses "sync" field as a prefix to all the subsequent data written by other (next) ...
Definition SyncPrefixLayer.h:52
SyncPrefixLayer(const SyncPrefixLayer &)=default
Copy constructor.
typename ParsedOptionsInternal::ExtendingClass ExtendingClass
Type of real extending class.
Definition SyncPrefixLayer.h:72
typename BaseImpl::Field Field
Type of the field object used to read/write "sync" value.
Definition SyncPrefixLayer.h:67
constexpr bool isSyncPrefixLayer()
Compile time check of whether the provided type is a variant of SyncPrefixLayer.
Definition SyncPrefixLayer.h:235
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:172
static bool verifyFieldValue(const Field &field)
Verify the validity of the field.
Definition SyncPrefixLayer.h:197
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:124
SyncPrefixLayer(SyncPrefixLayer &&)=default
Move constructor.
~SyncPrefixLayer() noexcept=default
Destructor.
static void prepareFieldForWrite(Field &field)
Prepare field for writing.
Definition SyncPrefixLayer.h:209
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.