COMMS
Template library intended to help with implementation of communication protocols.
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 
13 #include "comms/CompileControl.h"
14 #include "comms/protocol/details/ProtocolLayerBase.h"
15 #include "comms/protocol/details/SyncPrefixLayerOptionsParser.h"
16 #include "comms/protocol/details/ProtocolLayerExtendingClassHelper.h"
17 
18 COMMS_MSVC_WARNING_PUSH
19 COMMS_MSVC_WARNING_DISABLE(4189) // Disable erroneous initialized but not referenced variable warning
20 
21 namespace comms
22 {
23 
24 namespace protocol
25 {
26 
42 template <typename TField, typename TNextLayer, typename... TOptions>
43 class 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 
65 public:
67  using Field = typename BaseImpl::Field;
68 
73 
75  SyncPrefixLayer() = default;
76 
78  SyncPrefixLayer(const SyncPrefixLayer&) = default;
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 
190 protected:
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 
215 namespace details
216 {
217 template <typename T>
218 struct SyncPrefixLayerCheckHelper
219 {
220  static const bool Value = false;
221 };
222 
223 template <typename TField, typename TNextLayer>
224 struct SyncPrefixLayerCheckHelper<SyncPrefixLayer<TField, TNextLayer> >
225 {
226  static const bool Value = true;
227 };
228 
229 } // namespace details
230 
234 template <typename T>
235 constexpr bool isSyncPrefixLayer()
236 {
237  return details::SyncPrefixLayerCheckHelper<T>::Value;
238 }
239 
240 } // namespace protocol
241 
242 } // namespace comms
243 
244 COMMS_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
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
comms::option::def::ExtendingClass< T > ExtendingClass
Same as comms::option::def::ExtendingClass.
Definition: options.h:1822
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.