COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
SequenceSerLengthFieldPrefix.h
1//
2// Copyright 2017 - 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#pragma once
9
10#include "comms/Assert.h"
11#include "comms/ErrorStatus.h"
12
13#include <iterator>
14
15namespace comms
16{
17
18namespace field
19{
20
21namespace adapter
22{
23
24template <typename TLenField, comms::ErrorStatus TStatus, typename TBase>
25class SequenceSerLengthFieldPrefix : public TBase
26{
27 using BaseImpl = TBase;
28 using LenField = TLenField;
29
30 static const std::size_t MaxAllowedLength =
31 static_cast<std::size_t>(LenField::maxValue());
32
33 static_assert(!LenField::isVersionDependent(),
34 "Prefix fields must not be version dependent");
35
36public:
37 using ValueType = typename BaseImpl::ValueType;
38 using ElementType = typename BaseImpl::ElementType;
39
41
42 explicit SequenceSerLengthFieldPrefix(const ValueType& val)
43 : BaseImpl(val)
44 {
45 }
46
47 explicit SequenceSerLengthFieldPrefix(ValueType&& val)
48 : BaseImpl(std::move(val))
49 {
50 }
51
52 SequenceSerLengthFieldPrefix(const SequenceSerLengthFieldPrefix&) = default;
53 SequenceSerLengthFieldPrefix(SequenceSerLengthFieldPrefix&&) = default;
54 SequenceSerLengthFieldPrefix& operator=(const SequenceSerLengthFieldPrefix&) = default;
55 SequenceSerLengthFieldPrefix& operator=(SequenceSerLengthFieldPrefix&&) = default;
56
57 std::size_t length() const
58 {
59 auto valLength = BaseImpl::length();
60 LenField lenField;
61 lenField.setValue(std::min(valLength, std::size_t(MaxAllowedLength)));
62 return lenField.length() + valLength;
63 }
64
65 static constexpr std::size_t minLength()
66 {
67 return LenField::minLength();
68 }
69
70 static constexpr std::size_t maxLength()
71 {
72 return LenField::maxLength() + BaseImpl::maxLength();
73 }
74
75 bool valid() const
76 {
77 if ((!BaseImpl::valid()) || (!canWrite())) {
78 return false;
79 }
80
81 LenField lenField;
82 auto lenValue = std::min(BaseImpl::length(), std::size_t(MaxAllowedLength));
83 lenField.setValue(lenValue);
84 return lenField.valid();
85 }
86
87 template <typename TIter>
88 comms::ErrorStatus read(TIter& iter, std::size_t len)
89 {
90 auto fromIter = iter;
91 LenField lenField;
92 auto es = lenField.read(iter, len);
94 return es;
95 }
96
97 auto diff = static_cast<std::size_t>(std::distance(fromIter, iter));
98 COMMS_ASSERT(diff <= len);
99 len -= diff;
100 auto remLen = static_cast<std::size_t>(lenField.getValue());
101 if (len < remLen) {
102 return TStatus;
103 }
104
105 es = BaseImpl::read(iter, remLen);
107 return TStatus;
108 }
109
110 return es;
111 }
112
113 static constexpr bool hasReadNoStatus()
114 {
115 return false;
116 }
117
118 template <typename TIter>
119 void readNoStatus(TIter& iter) = delete;
120
121 bool canWrite() const
122 {
123 if (!BaseImpl::canWrite()) {
124 return false;
125 }
126
127 auto len = BaseImpl::length();
128 if (MaxAllowedLength < len) {
129 return false;
130 }
131
132 LenField lenField;
133 lenField.setValue(len);
134 return lenField.canWrite();
135 }
136
137 template <typename TIter>
138 comms::ErrorStatus write(TIter& iter, std::size_t len) const
139 {
140 if (!canWrite()) {
142 }
143
144 auto lenVal = BaseImpl::length();
145 LenField lenField;
146 lenField.setValue(lenVal);
147 auto es = lenField.write(iter, len);
148 if (es != comms::ErrorStatus::Success) {
149 return es;
150 }
151
152 COMMS_ASSERT(lenField.length() <= len);
153 return BaseImpl::write(iter, lenVal);
154 }
155
156 static constexpr bool hasWriteNoStatus()
157 {
158 return false;
159 }
160
161 template <typename TIter>
162 void writeNoStatus(TIter& iter) const = delete;
163};
164
165} // namespace adapter
166
167} // namespace field
168
169} // namespace comms
170
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:168
This file contain definition of error statuses used by comms module.
comms::option::def::SequenceSerLengthFieldPrefix< TField, TReadErrorStatus > SequenceSerLengthFieldPrefix
Same as comms::option::def::SequenceSerLengthFieldPrefix.
Definition options.h:1566
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.
@ InvalidMsgData
Used to indicate that a message has invalid data.
STL namespace.