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