COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
SequenceElemLengthForcing.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 <iterator>
11#include <limits>
12
13#include "comms/Assert.h"
14#include "comms/ErrorStatus.h"
15#include "comms/field/basic/CommonFuncs.h"
16
17namespace comms
18{
19
20namespace field
21{
22
23namespace adapter
24{
25
26template <typename TBase>
27class SequenceElemLengthForcing : public TBase
28{
29 using BaseImpl = TBase;
30public:
31 using ValueType = typename BaseImpl::ValueType;
32 using ElementType = typename BaseImpl::ElementType;
33
34 SequenceElemLengthForcing() = default;
35
36 explicit SequenceElemLengthForcing(const ValueType& val)
37 : BaseImpl(val)
38 {
39 }
40
41 explicit SequenceElemLengthForcing(ValueType&& val)
42 : BaseImpl(std::move(val))
43 {
44 }
45
46 SequenceElemLengthForcing(const SequenceElemLengthForcing&) = default;
47 SequenceElemLengthForcing(SequenceElemLengthForcing&&) = default;
48 SequenceElemLengthForcing& operator=(const SequenceElemLengthForcing&) = default;
49 SequenceElemLengthForcing& operator=(SequenceElemLengthForcing&&) = default;
50
51 void forceReadElemLength(std::size_t val)
52 {
53 COMMS_ASSERT(val != Cleared);
54 forced_ = val;
55 }
56
57 void clearReadElemLengthForcing()
58 {
59 forced_ = Cleared;
60 }
61
62 std::size_t length() const
63 {
64 if (forced_ != Cleared) {
65 return BaseImpl::getValue().size() * forced_;
66 }
67
68 return BaseImpl::length();
69 }
70
71 std::size_t elementLength(const ElementType& elem) const
72 {
73 if (forced_ != Cleared) {
74 return forced_;
75 }
76 return BaseImpl::elementLength(elem);
77 }
78
79 static constexpr std::size_t maxElementLength()
80 {
81 return basic::CommonFuncs::maxSupportedLength();
82 }
83
84 template <typename TIter>
85 ErrorStatus readElement(ElementType& elem, TIter& iter, std::size_t& len) const
86 {
87 using IterType = typename std::decay<decltype(iter)>::type;
88 using IterTag = typename std::iterator_traits<IterType>::iterator_category;
89 static_assert(std::is_base_of<std::random_access_iterator_tag, IterTag>::value,
90 "Only random access iterator for reading is supported with comms::option::def::SequenceElemLengthForcingEnabled option");
91
92 if (forced_ == Cleared) {
93 return BaseImpl::readElement(elem, iter, len);
94 }
95
96 if (len < forced_) {
98 }
99
100 auto iterTmp = iter;
101 auto remLen = forced_;
102 std::advance(iter, forced_);
103 len -= forced_;
104 return BaseImpl::readElement(elem, iterTmp, remLen);
105 }
106
107 template <typename TIter>
108 void readElementNoStatus(ElementType& elem, TIter& iter) const
109 {
110 using IterType = typename std::decay<decltype(iter)>::type;
111 using IterTag = typename std::iterator_traits<IterType>::iterator_category;
112 static_assert(std::is_base_of<std::random_access_iterator_tag, IterTag>::value,
113 "Only random access iterator for reading is supported with comms::option::def::SequenceElemLengthForcingEnabled option");
114
115 if (forced_ == Cleared) {
116 return BaseImpl::readElementNoStatus(elem, iter);
117 }
118
119 auto fromIter = iter;
120 auto es = BaseImpl::readElementNoStatus(elem, iter);
121 if (es != comms::ErrorStatus::Success) {
122 return es;
123 }
124
125 auto consumed = std::distance(fromIter, iter);
126 if (consumed < forced_) {
127 std::advance(iter, forced_ - consumed);
128 }
129 }
130
131 template <typename TIter>
132 comms::ErrorStatus read(TIter& iter, std::size_t len)
133 {
134 return basic::CommonFuncs::readSequence(*this, iter, len);
135 }
136
137 static constexpr bool hasReadNoStatus()
138 {
139 return false;
140 }
141
142 template <typename TIter>
143 void readNoStatus(TIter& iter) = delete;
144
145 template <typename TIter>
146 ErrorStatus readN(std::size_t count, TIter& iter, std::size_t& len)
147 {
148 return basic::CommonFuncs::readSequenceN(*this, count, iter, len);
149 }
150
151 template <typename TIter>
152 void readNoStatusN(std::size_t count, TIter& iter) = delete;
153// {
154// basic::CommonFuncs::readSequenceNoStatusN(*this, count, iter);
155// }
156
157private:
158
159 static const std::size_t Cleared = std::numeric_limits<std::size_t>::max();
160 std::size_t forced_ = Cleared;
161};
162
163} // namespace adapter
164
165} // namespace field
166
167} // namespace comms
168
169
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.
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.
STL namespace.