COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
SequenceSizeFieldPrefix.h
1//
2// Copyright 2015 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: MPL-2.0
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#pragma once
11
12#include "comms/Assert.h"
13#include "comms/ErrorStatus.h"
14
15#include <cstddef>
16#include <iterator>
17#include <utility>
18
19namespace comms
20{
21
22namespace field
23{
24
25namespace adapter
26{
27
28template <typename TSizeField, typename TBase>
29class SequenceSizeFieldPrefix : public TBase
30{
31 using BaseImpl = TBase;
32 using SizeField = TSizeField;
33
34 static const std::size_t MaxAllowedSize =
35 static_cast<std::size_t>(SizeField::maxValue());
36
37 static_assert(!SizeField::isVersionDependent(),
38 "Prefix fields must not be version dependent");
39
40public:
41 using ValueType = typename BaseImpl::ValueType;
42 using ElementType = typename BaseImpl::ElementType;
43
44 SequenceSizeFieldPrefix() = default;
45
46 explicit SequenceSizeFieldPrefix(const ValueType& val)
47 : BaseImpl(val)
48 {
49 }
50
51 explicit SequenceSizeFieldPrefix(ValueType&& val)
52 : BaseImpl(std::move(val))
53 {
54 }
55
56 SequenceSizeFieldPrefix(const SequenceSizeFieldPrefix&) = default;
57 SequenceSizeFieldPrefix(SequenceSizeFieldPrefix&&) = default;
58 SequenceSizeFieldPrefix& operator=(const SequenceSizeFieldPrefix&) = default;
59 SequenceSizeFieldPrefix& operator=(SequenceSizeFieldPrefix&&) = default;
60
61 std::size_t length() const
62 {
63 SizeField sizeField;
64 sizeField.setValue(BaseImpl::getValue().size());
65 return sizeField.length() + BaseImpl::length();
66 }
67
68 static constexpr std::size_t minLength()
69 {
70 return SizeField::minLength();
71 }
72
73 static constexpr std::size_t maxLength()
74 {
75 return SizeField::maxLength() + BaseImpl::maxLength();
76 }
77
78 bool valid() const
79 {
80 if ((!BaseImpl::valid()) || (!canWrite())) {
81 return false;
82 }
83 SizeField sizeField;
84 sizeField.setValue(BaseImpl::getValue().size());
85 return sizeField.valid() && BaseImpl::valid();
86 }
87
88 template <typename TIter>
89 comms::ErrorStatus read(TIter& iter, std::size_t len)
90 {
91 auto fromIter = iter;
92 SizeField sizeField;
93 auto es = sizeField.read(iter, len);
95 return es;
96 }
97
98 auto diff = static_cast<std::size_t>(std::distance(fromIter, iter));
99 COMMS_ASSERT(diff <= len);
100 len -= diff;
101
102 auto count = static_cast<std::size_t>(sizeField.getValue());
103 return BaseImpl::readN(count, iter, len);
104 }
105
106 template <typename TIter>
107 void readNoStatus(TIter& iter)
108 {
109 SizeField sizeField;
110 sizeField.readNoStatus(iter);
111 auto count = static_cast<std::size_t>(sizeField.getValue());
112 BaseImpl::readNoStatusN(count, iter);
113 }
114
115 bool canWrite() const
116 {
117 if (!BaseImpl::canWrite()) {
118 return false;
119 }
120
121 if (MaxAllowedSize < BaseImpl::getValue().size()) {
122 return false;
123 }
124
125 SizeField sizeField;
126 sizeField.setValue(BaseImpl::getValue().size());
127 return sizeField.canWrite();
128 }
129
130 template <typename TIter>
131 comms::ErrorStatus write(TIter& iter, std::size_t len) const
132 {
133 if (!canWrite()) {
135 }
136
137 SizeField sizeField;
138 sizeField.setValue(BaseImpl::getValue().size());
139 auto es = sizeField.write(iter, len);
140 if (es != comms::ErrorStatus::Success) {
141 return es;
142 }
143
144 COMMS_ASSERT(sizeField.length() <= len);
145 return BaseImpl::write(iter, len - sizeField.length());
146 }
147
148 static constexpr bool hasWriteNoStatus()
149 {
150 return false;
151 }
152
153 template <typename TIter>
154 void writeNoStatus(TIter& iter) const = delete;
155};
156
157} // namespace adapter
158
159} // namespace field
160
161} // namespace comms
162
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::SequenceSizeFieldPrefix< TField > SequenceSizeFieldPrefix
Same as comms::option::def::SequenceSizeFieldPrefix.
Definition options.h:1562
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:19
@ Success
Used to indicate successful outcome of the operation.
@ InvalidMsgData
Used to indicate that a message has invalid data.
STL namespace.