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