COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
SequenceSizeFieldPrefix.h
1//
2// Copyright 2015 - 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 TSizeField, typename TBase>
25class SequenceSizeFieldPrefix : public TBase
26{
27 using BaseImpl = TBase;
28 using SizeField = TSizeField;
29
30 static const std::size_t MaxAllowedSize =
31 static_cast<std::size_t>(SizeField::maxValue());
32
33 static_assert(!SizeField::isVersionDependent(),
34 "Prefix fields must not be version dependent");
35
36public:
37 using ValueType = typename BaseImpl::ValueType;
38 using ElementType = typename BaseImpl::ElementType;
39
40 SequenceSizeFieldPrefix() = default;
41
42 explicit SequenceSizeFieldPrefix(const ValueType& val)
43 : BaseImpl(val)
44 {
45 }
46
47 explicit SequenceSizeFieldPrefix(ValueType&& val)
48 : BaseImpl(std::move(val))
49 {
50 }
51
52 SequenceSizeFieldPrefix(const SequenceSizeFieldPrefix&) = default;
53 SequenceSizeFieldPrefix(SequenceSizeFieldPrefix&&) = default;
54 SequenceSizeFieldPrefix& operator=(const SequenceSizeFieldPrefix&) = default;
55 SequenceSizeFieldPrefix& operator=(SequenceSizeFieldPrefix&&) = default;
56
57 std::size_t length() const
58 {
59 SizeField sizeField;
60 sizeField.setValue(BaseImpl::getValue().size());
61 return sizeField.length() + BaseImpl::length();
62 }
63
64 static constexpr std::size_t minLength()
65 {
66 return SizeField::minLength();
67 }
68
69 static constexpr std::size_t maxLength()
70 {
71 return SizeField::maxLength() + BaseImpl::maxLength();
72 }
73
74 bool valid() const
75 {
76 if ((!BaseImpl::valid()) || (!canWrite())) {
77 return false;
78 }
79 SizeField sizeField;
80 sizeField.setValue(BaseImpl::getValue().size());
81 return sizeField.valid() && BaseImpl::valid();
82 }
83
84 template <typename TIter>
85 comms::ErrorStatus read(TIter& iter, std::size_t len)
86 {
87 auto fromIter = iter;
88 SizeField sizeField;
89 auto es = sizeField.read(iter, len);
91 return es;
92 }
93
94 auto diff = static_cast<std::size_t>(std::distance(fromIter, iter));
95 COMMS_ASSERT(diff <= len);
96 len -= diff;
97
98 auto count = static_cast<std::size_t>(sizeField.getValue());
99 return BaseImpl::readN(count, iter, len);
100 }
101
102 template <typename TIter>
103 void readNoStatus(TIter& iter)
104 {
105 SizeField sizeField;
106 sizeField.readNoStatus(iter);
107 auto count = static_cast<std::size_t>(sizeField.getValue());
108 BaseImpl::readNoStatusN(count, iter);
109 }
110
111 bool canWrite() const
112 {
113 if (!BaseImpl::canWrite()) {
114 return false;
115 }
116
117 if (MaxAllowedSize < BaseImpl::getValue().size()) {
118 return false;
119 }
120
121 SizeField sizeField;
122 sizeField.setValue(BaseImpl::getValue().size());
123 return sizeField.canWrite();
124 }
125
126 template <typename TIter>
127 comms::ErrorStatus write(TIter& iter, std::size_t len) const
128 {
129 if (!canWrite()) {
131 }
132
133 SizeField sizeField;
134 sizeField.setValue(BaseImpl::getValue().size());
135 auto es = sizeField.write(iter, len);
136 if (es != comms::ErrorStatus::Success) {
137 return es;
138 }
139
140 COMMS_ASSERT(sizeField.length() <= len);
141 return BaseImpl::write(iter, len - sizeField.length());
142 }
143
144 static constexpr bool hasWriteNoStatus()
145 {
146 return false;
147 }
148
149 template <typename TIter>
150 void writeNoStatus(TIter& iter) const = delete;
151};
152
153} // namespace adapter
154
155} // namespace field
156
157} // namespace comms
158
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::SequenceSizeFieldPrefix< TField > SequenceSizeFieldPrefix
Same as comms::option::def::SequenceSizeFieldPrefix.
Definition options.h:1560
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.