EmbeddedProto 4.0.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- EmbeddedProto/EmbeddedProto.py +122 -0
- EmbeddedProto/Features.py +255 -0
- EmbeddedProto/Field.py +1295 -0
- EmbeddedProto/Oneof.py +74 -0
- EmbeddedProto/ProtoFile.py +210 -0
- EmbeddedProto/TypeDefinitions.py +367 -0
- EmbeddedProto/__init__.py +0 -0
- EmbeddedProto/__main__.py +28 -0
- EmbeddedProto/config.py +173 -0
- EmbeddedProto/custom_header.py +513 -0
- EmbeddedProto/embedded_proto_options.proto +62 -0
- EmbeddedProto/embedded_proto_options_pb2.py +37 -0
- EmbeddedProto/field_options.py +344 -0
- EmbeddedProto/main.py +316 -0
- EmbeddedProto/src/EmbeddedProto/BytesStringCallback.h +476 -0
- EmbeddedProto/src/EmbeddedProto/Defines.h +118 -0
- EmbeddedProto/src/EmbeddedProto/EmptyArray.h +81 -0
- EmbeddedProto/src/EmbeddedProto/Errors.h +53 -0
- EmbeddedProto/src/EmbeddedProto/FieldStringBytes.h +793 -0
- EmbeddedProto/src/EmbeddedProto/Fields.h +832 -0
- EmbeddedProto/src/EmbeddedProto/Functional.h +412 -0
- EmbeddedProto/src/EmbeddedProto/MessageCallback.h +688 -0
- EmbeddedProto/src/EmbeddedProto/MessageInterface.h +792 -0
- EmbeddedProto/src/EmbeddedProto/MessageSizeCalculator.h +109 -0
- EmbeddedProto/src/EmbeddedProto/MessageState.h +207 -0
- EmbeddedProto/src/EmbeddedProto/ReadBufferFixedSize.h +204 -0
- EmbeddedProto/src/EmbeddedProto/ReadBufferInterface.h +181 -0
- EmbeddedProto/src/EmbeddedProto/ReadBufferSection.h +232 -0
- EmbeddedProto/src/EmbeddedProto/RepeatedField.h +1053 -0
- EmbeddedProto/src/EmbeddedProto/RepeatedFieldCallback.h +432 -0
- EmbeddedProto/src/EmbeddedProto/RepeatedFieldFixedSize.h +367 -0
- EmbeddedProto/src/EmbeddedProto/Version.h +39 -0
- EmbeddedProto/src/EmbeddedProto/WireFormatter.h +852 -0
- EmbeddedProto/src/EmbeddedProto/WriteBufferFixedSize.h +114 -0
- EmbeddedProto/src/EmbeddedProto/WriteBufferInterface.h +134 -0
- EmbeddedProto/src/EmbeddedProto.h +55 -0
- EmbeddedProto/templates/FieldBasic_Deserialize.h.jinja2 +26 -0
- EmbeddedProto/templates/FieldBasic_GetSet.h.jinja2 +89 -0
- EmbeddedProto/templates/FieldBytes_GetSet.h.jinja2 +86 -0
- EmbeddedProto/templates/FieldEnum_Deserialize.h.jinja2 +50 -0
- EmbeddedProto/templates/FieldEnum_GetSet.h.jinja2 +93 -0
- EmbeddedProto/templates/FieldErrorRecursive_GetSet.h.jinja2 +29 -0
- EmbeddedProto/templates/FieldMap_GetSet.h.jinja2 +203 -0
- EmbeddedProto/templates/FieldMsg_Deserialize.h.jinja2 +44 -0
- EmbeddedProto/templates/FieldMsg_GetSet.h.jinja2 +93 -0
- EmbeddedProto/templates/FieldRepeated_GetSet.h.jinja2 +94 -0
- EmbeddedProto/templates/FieldString_GetSet.h.jinja2 +86 -0
- EmbeddedProto/templates/Field_DeserializePartial.h.jinja2 +33 -0
- EmbeddedProto/templates/Field_Serialize.h.jinja2 +112 -0
- EmbeddedProto/templates/Field_SerializePartial.h.jinja2 +119 -0
- EmbeddedProto/templates/Header.h.jinja2 +108 -0
- EmbeddedProto/templates/TypeDefEnum.h.jinja2 +45 -0
- EmbeddedProto/templates/TypeDefMsg.h.jinja2 +791 -0
- EmbeddedProto/templates/TypeOneof.h.jinja2 +178 -0
- EmbeddedProto/version.json +3 -0
- embeddedproto-4.0.0b1.dist-info/METADATA +141 -0
- embeddedproto-4.0.0b1.dist-info/RECORD +63 -0
- embeddedproto-4.0.0b1.dist-info/WHEEL +5 -0
- embeddedproto-4.0.0b1.dist-info/entry_points.txt +3 -0
- embeddedproto-4.0.0b1.dist-info/licenses/LICENSE +30 -0
- embeddedproto-4.0.0b1.dist-info/licenses/LICENSES/GPL-3.0-only.txt +674 -0
- embeddedproto-4.0.0b1.dist-info/licenses/LICENSES/LicenseRef-EmbeddedProto-Commercial.txt +12 -0
- embeddedproto-4.0.0b1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2020-2026 Embedded AMS B.V. - All Rights Reserved
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Embedded Proto.
|
|
5
|
+
*
|
|
6
|
+
* Embedded Proto is dual licensed. You may use it under the terms of the
|
|
7
|
+
* GNU General Public License version 3 (GPLv3) as published by the Free
|
|
8
|
+
* Software Foundation, or under a commercial license from Embedded AMS B.V.
|
|
9
|
+
*
|
|
10
|
+
* Under the GPLv3 you must release the source code of
|
|
11
|
+
* any product you distribute that includes Embedded Proto or code
|
|
12
|
+
* generated by it. A commercial license removes that obligation.
|
|
13
|
+
* See <https://embeddedproto.com/pricing/>.
|
|
14
|
+
*
|
|
15
|
+
* Embedded Proto is distributed WITHOUT ANY WARRANTY; without even the
|
|
16
|
+
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
17
|
+
* See the LICENSE file in the root of the repository for details.
|
|
18
|
+
*
|
|
19
|
+
* SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-EmbeddedProto-Commercial
|
|
20
|
+
*
|
|
21
|
+
* Embedded AMS B.V., Hoorn, the Netherlands - info at EmbeddedProto dot com
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#ifndef _MESSAGE_SIZE_CALCULATOR_H_
|
|
25
|
+
#define _MESSAGE_SIZE_CALCULATOR_H_
|
|
26
|
+
|
|
27
|
+
#include "WriteBufferInterface.h"
|
|
28
|
+
|
|
29
|
+
#include <cstdint>
|
|
30
|
+
#include <limits>
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
namespace EmbeddedProto
|
|
34
|
+
{
|
|
35
|
+
//! This class is used in a message to calculate the current serialized size.
|
|
36
|
+
/*!
|
|
37
|
+
To calculate the size of a message given the current data a dummy serialization is performed.
|
|
38
|
+
This class mimics the buffer in which the data is stored. Instead of storing it, only the
|
|
39
|
+
size is incremented for the bytes pushed. No actual data is pushed into a buffer.
|
|
40
|
+
|
|
41
|
+
\see MessageInterface::serialized_size()
|
|
42
|
+
*/
|
|
43
|
+
class MessageSizeCalculator : public WriteBufferInterface
|
|
44
|
+
{
|
|
45
|
+
public:
|
|
46
|
+
MessageSizeCalculator() = default;
|
|
47
|
+
~MessageSizeCalculator() = default;
|
|
48
|
+
|
|
49
|
+
//! Reset the size count of the buffer.
|
|
50
|
+
void clear() override
|
|
51
|
+
{
|
|
52
|
+
size_ = 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//! Obtain the total number of bytes currently stored in the buffer.
|
|
56
|
+
uint32_t get_size() const override
|
|
57
|
+
{
|
|
58
|
+
return size_;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//! To continue serialization return the maximum number that fits in a 32bit unsigned int.
|
|
62
|
+
uint32_t get_max_size() const override
|
|
63
|
+
{
|
|
64
|
+
return std::numeric_limits<uint32_t>::max();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
//! To continue serialization return the maximum number that fits in a 32bit unsigned int.
|
|
68
|
+
uint32_t get_available_size() const override
|
|
69
|
+
{
|
|
70
|
+
return std::numeric_limits<uint32_t>::max();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//! For calculating the size we just increment the counter and always return true.
|
|
74
|
+
bool push(const uint8_t byte) override
|
|
75
|
+
{
|
|
76
|
+
// Ignore the unused parameter
|
|
77
|
+
(void)byte;
|
|
78
|
+
++size_;
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
//! Keep the pointer and length form of push() reachable next to the override below.
|
|
83
|
+
using WriteBufferInterface::push;
|
|
84
|
+
|
|
85
|
+
//! Increment the size with the number of bytes in the view.
|
|
86
|
+
bool push(const const_bytes_view& bytes) override
|
|
87
|
+
{
|
|
88
|
+
size_ += bytes.size;
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//! Only the count matters here, so account for the bytes without receiving them.
|
|
93
|
+
bool count_only(const uint32_t number_of_bytes) override
|
|
94
|
+
{
|
|
95
|
+
size_ += number_of_bytes;
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
private:
|
|
101
|
+
|
|
102
|
+
//! The calculated size of the buffer.
|
|
103
|
+
uint32_t size_ = 0;
|
|
104
|
+
|
|
105
|
+
}; // End of class MessageSizeCalculator
|
|
106
|
+
|
|
107
|
+
} // End of namespace EmbeddedProto
|
|
108
|
+
|
|
109
|
+
#endif
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2020-2026 Embedded AMS B.V. - All Rights Reserved
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Embedded Proto.
|
|
5
|
+
*
|
|
6
|
+
* Embedded Proto is dual licensed. You may use it under the terms of the
|
|
7
|
+
* GNU General Public License version 3 (GPLv3) as published by the Free
|
|
8
|
+
* Software Foundation, or under a commercial license from Embedded AMS B.V.
|
|
9
|
+
*
|
|
10
|
+
* Under the GPLv3 you must release the source code of
|
|
11
|
+
* any product you distribute that includes Embedded Proto or code
|
|
12
|
+
* generated by it. A commercial license removes that obligation.
|
|
13
|
+
* See <https://embeddedproto.com/pricing/>.
|
|
14
|
+
*
|
|
15
|
+
* Embedded Proto is distributed WITHOUT ANY WARRANTY; without even the
|
|
16
|
+
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
17
|
+
* See the LICENSE file in the root of the repository for details.
|
|
18
|
+
*
|
|
19
|
+
* SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-EmbeddedProto-Commercial
|
|
20
|
+
*
|
|
21
|
+
* Embedded AMS B.V., Hoorn, the Netherlands - info at EmbeddedProto dot com
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#ifndef _MESSAGE_STATE_H_
|
|
25
|
+
#define _MESSAGE_STATE_H_
|
|
26
|
+
|
|
27
|
+
#include "WireFormatter.h"
|
|
28
|
+
|
|
29
|
+
#include <array>
|
|
30
|
+
#include <cstdint>
|
|
31
|
+
|
|
32
|
+
namespace EmbeddedProto
|
|
33
|
+
{
|
|
34
|
+
|
|
35
|
+
//! Phase of field processing for partial serialization/deserialization.
|
|
36
|
+
enum class FieldProcessingPhase : uint8_t
|
|
37
|
+
{
|
|
38
|
+
TAG = 0, //<! Reading/writing field tag (field number + wire type)
|
|
39
|
+
SIZE = 1, //<! Reading/writing length prefix (for LENGTH_DELIMITED fields)
|
|
40
|
+
DATA = 2, //<! Reading/writing actual field data
|
|
41
|
+
COMPLETE = 3 //<! Done with this field, ready for next
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
//! State for partial serialization/deserialization of a single message.
|
|
45
|
+
/*!
|
|
46
|
+
This structure tracks the current state of a message during partial
|
|
47
|
+
serialization or deserialization. It is used for both operations to
|
|
48
|
+
maintain consistency.
|
|
49
|
+
*/
|
|
50
|
+
struct MessageState
|
|
51
|
+
{
|
|
52
|
+
//! Default phase for a new field operation.
|
|
53
|
+
static constexpr::EmbeddedProto::FieldProcessingPhase INITIAL_PHASE = ::EmbeddedProto::FieldProcessingPhase::TAG;
|
|
54
|
+
|
|
55
|
+
//! Default wire type value.
|
|
56
|
+
static constexpr WireFormatter::WireType INITIAL_WIRE_TYPE = WireFormatter::WireType::VARINT;
|
|
57
|
+
|
|
58
|
+
//! Current phase of field processing.
|
|
59
|
+
::EmbeddedProto::FieldProcessingPhase phase = INITIAL_PHASE;
|
|
60
|
+
|
|
61
|
+
//! Field number from protobuf definition (1-based, from tag or next to serialize).
|
|
62
|
+
uint32_t field_id = 0;
|
|
63
|
+
|
|
64
|
+
//! Wire type from tag (deserialization only, but stored here for simplicity).
|
|
65
|
+
WireFormatter::WireType wire_type = INITIAL_WIRE_TYPE;
|
|
66
|
+
|
|
67
|
+
//! For repeated fields: index of current element (0-based).
|
|
68
|
+
uint32_t element_index = 0;
|
|
69
|
+
|
|
70
|
+
//! For length-delimited fields: bytes remaining to read/write.
|
|
71
|
+
uint32_t bytes_remaining = 0;
|
|
72
|
+
|
|
73
|
+
//! For length-delimited fields: the size once calculated when serializing or read when deserializing.
|
|
74
|
+
uint32_t size_value = 0;
|
|
75
|
+
|
|
76
|
+
//! Pointer to child state for nested messages (null if leaf).
|
|
77
|
+
MessageState* child = nullptr;
|
|
78
|
+
|
|
79
|
+
//! Default constructor.
|
|
80
|
+
MessageState() = default;
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
//! Reset this state and every state below it to the initial values.
|
|
84
|
+
/*!
|
|
85
|
+
A state is reused whenever a message starts over at its level, for instance for
|
|
86
|
+
the next element of a repeated message field. The nested messages of that element
|
|
87
|
+
used the states further down the chain, so those are reset as well. Otherwise a
|
|
88
|
+
stale COMPLETE phase two levels down silently skips the nested message of the
|
|
89
|
+
next element. The child pointers themselves are kept, they are set at construction.
|
|
90
|
+
*/
|
|
91
|
+
void reset()
|
|
92
|
+
{
|
|
93
|
+
for(MessageState* state = this; nullptr != state; state = state->child)
|
|
94
|
+
{
|
|
95
|
+
state->phase = INITIAL_PHASE;
|
|
96
|
+
state->field_id = 0;
|
|
97
|
+
state->wire_type = INITIAL_WIRE_TYPE;
|
|
98
|
+
state->element_index = 0;
|
|
99
|
+
state->bytes_remaining = 0;
|
|
100
|
+
state->size_value = 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
protected:
|
|
105
|
+
// Protected copy/move to prevent slicing - state should be managed via MessageStateStack
|
|
106
|
+
MessageState(const MessageState&) = default;
|
|
107
|
+
MessageState(MessageState&&) = default;
|
|
108
|
+
MessageState& operator=(const MessageState&) = default;
|
|
109
|
+
MessageState& operator=(MessageState&&) = default;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
//! Fixed-size stack of MessageState objects for nested message handling.
|
|
113
|
+
/*!
|
|
114
|
+
This template class provides a compile-time fixed array of MessageState
|
|
115
|
+
objects, linked together to support nested message serialization and
|
|
116
|
+
deserialization.
|
|
117
|
+
|
|
118
|
+
\tparam DEPTH The maximum nesting depth this stack can handle.
|
|
119
|
+
*/
|
|
120
|
+
template<uint32_t DEPTH>
|
|
121
|
+
class MessageStateStack
|
|
122
|
+
{
|
|
123
|
+
static_assert(DEPTH > 0U, "MessageStateStack needs a DEPTH of at least one: the root message "
|
|
124
|
+
"state lives at index zero and the constructor links DEPTH - 1 child states.");
|
|
125
|
+
|
|
126
|
+
public:
|
|
127
|
+
//! Constructor - links states together in parent-child chain.
|
|
128
|
+
MessageStateStack()
|
|
129
|
+
{
|
|
130
|
+
// Link states together: parent -> child
|
|
131
|
+
// states_[0] is the root (outermost message)
|
|
132
|
+
// states_[DEPTH-1] is the deepest possible nested message
|
|
133
|
+
for(uint32_t i = 0; i < DEPTH - 1; ++i)
|
|
134
|
+
{
|
|
135
|
+
states_[i].child = &states_[i + 1];
|
|
136
|
+
}
|
|
137
|
+
// states_[DEPTH-1].child remains nullptr (leaf)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
//! Default destructor.
|
|
141
|
+
~MessageStateStack() = default;
|
|
142
|
+
|
|
143
|
+
//! Get the root state (for the outermost message).
|
|
144
|
+
/*!
|
|
145
|
+
\return Reference to the root MessageState.
|
|
146
|
+
*/
|
|
147
|
+
MessageState& root()
|
|
148
|
+
{
|
|
149
|
+
return states_[0];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
//! Get the root state (for the outermost message) - const version.
|
|
153
|
+
/*!
|
|
154
|
+
\return Const reference to the root MessageState.
|
|
155
|
+
*/
|
|
156
|
+
const MessageState& root() const
|
|
157
|
+
{
|
|
158
|
+
return states_[0];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
//! Get the state at a specific depth.
|
|
162
|
+
/*!
|
|
163
|
+
\param depth 0 = root, 1 = first nested level, etc.
|
|
164
|
+
\return Reference to the MessageState at the specified depth.
|
|
165
|
+
*/
|
|
166
|
+
MessageState& at(uint32_t depth)
|
|
167
|
+
{
|
|
168
|
+
return states_[depth];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//! Get the state at a specific depth - const version.
|
|
172
|
+
/*!
|
|
173
|
+
\param depth 0 = root, 1 = first nested level, etc.
|
|
174
|
+
\return Const reference to the MessageState at the specified depth.
|
|
175
|
+
*/
|
|
176
|
+
const MessageState& at(uint32_t depth) const
|
|
177
|
+
{
|
|
178
|
+
return states_[depth];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
//! Reset all states to initial values.
|
|
182
|
+
/*!
|
|
183
|
+
The root state resets every state below it through the child chain, so one call
|
|
184
|
+
covers the whole stack.
|
|
185
|
+
*/
|
|
186
|
+
void reset()
|
|
187
|
+
{
|
|
188
|
+
states_[0].reset();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
//! Get the maximum depth this stack can handle.
|
|
192
|
+
/*!
|
|
193
|
+
\return The template parameter DEPTH value.
|
|
194
|
+
*/
|
|
195
|
+
static constexpr uint32_t max_depth()
|
|
196
|
+
{
|
|
197
|
+
return DEPTH;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private:
|
|
201
|
+
//! The array of message states.
|
|
202
|
+
std::array<MessageState, DEPTH> states_{};
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
} // namespace EmbeddedProto
|
|
206
|
+
|
|
207
|
+
#endif // End of _MESSAGE_STATE_H_
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2020-2026 Embedded AMS B.V. - All Rights Reserved
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Embedded Proto.
|
|
5
|
+
*
|
|
6
|
+
* Embedded Proto is dual licensed. You may use it under the terms of the
|
|
7
|
+
* GNU General Public License version 3 (GPLv3) as published by the Free
|
|
8
|
+
* Software Foundation, or under a commercial license from Embedded AMS B.V.
|
|
9
|
+
*
|
|
10
|
+
* Under the GPLv3 you must release the source code of
|
|
11
|
+
* any product you distribute that includes Embedded Proto or code
|
|
12
|
+
* generated by it. A commercial license removes that obligation.
|
|
13
|
+
* See <https://embeddedproto.com/pricing/>.
|
|
14
|
+
*
|
|
15
|
+
* Embedded Proto is distributed WITHOUT ANY WARRANTY; without even the
|
|
16
|
+
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
17
|
+
* See the LICENSE file in the root of the repository for details.
|
|
18
|
+
*
|
|
19
|
+
* SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-EmbeddedProto-Commercial
|
|
20
|
+
*
|
|
21
|
+
* Embedded AMS B.V., Hoorn, the Netherlands - info at EmbeddedProto dot com
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#ifndef _READ_BUFFER_FIXED_H_
|
|
25
|
+
#define _READ_BUFFER_FIXED_H_
|
|
26
|
+
|
|
27
|
+
#include "ReadBufferInterface.h"
|
|
28
|
+
#include <array>
|
|
29
|
+
#include <cstring>
|
|
30
|
+
#include <initializer_list>
|
|
31
|
+
|
|
32
|
+
namespace EmbeddedProto
|
|
33
|
+
{
|
|
34
|
+
|
|
35
|
+
//! This template class implements the ReadBufferInterface.
|
|
36
|
+
/*!
|
|
37
|
+
The template sets the number of bytes which fit in the buffer.
|
|
38
|
+
*/
|
|
39
|
+
template<uint32_t BUFFER_SIZE>
|
|
40
|
+
class ReadBufferFixedSize : public ::EmbeddedProto::ReadBufferInterface
|
|
41
|
+
{
|
|
42
|
+
public:
|
|
43
|
+
//! The default constructor which initializes everything at zero.
|
|
44
|
+
ReadBufferFixedSize() = default;
|
|
45
|
+
|
|
46
|
+
ReadBufferFixedSize(std::initializer_list<uint8_t> init_list)
|
|
47
|
+
{
|
|
48
|
+
// TODO static_assert(init_list.size() <= BUFFER_SIZE, "Initializer does not fit in buffer.");
|
|
49
|
+
set_bytes_written(init_list.size());
|
|
50
|
+
std::copy(init_list.begin(), init_list.end(), data_.begin());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//! The default destructor.
|
|
54
|
+
~ReadBufferFixedSize() = default;
|
|
55
|
+
|
|
56
|
+
//! \see ::EmbeddedProto::ReadBufferInterface::get_size()
|
|
57
|
+
uint32_t get_size() const override
|
|
58
|
+
{
|
|
59
|
+
return write_index_ - read_index_;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
//! \see ::EmbeddedProto::ReadBufferInterface::get_max_size()
|
|
63
|
+
uint32_t get_max_size() const override
|
|
64
|
+
{
|
|
65
|
+
return BUFFER_SIZE;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//! \see ::EmbeddedProto::ReadBufferInterface::peek(uint8_t& byte)
|
|
69
|
+
bool peek(uint8_t& byte) const override
|
|
70
|
+
{
|
|
71
|
+
const bool return_value = write_index_ > read_index_;
|
|
72
|
+
if(return_value)
|
|
73
|
+
{
|
|
74
|
+
byte = data_[read_index_];
|
|
75
|
+
}
|
|
76
|
+
return return_value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//! \see ::EmbeddedProto::ReadBufferInterface::peek(const int32_t n, uint8_t& byte)
|
|
80
|
+
bool peek(const uint32_t n_bytes, uint8_t& byte) const override
|
|
81
|
+
{
|
|
82
|
+
const bool return_value = write_index_ > (read_index_ + n_bytes);
|
|
83
|
+
if(return_value)
|
|
84
|
+
{
|
|
85
|
+
byte = data_[read_index_ + n_bytes];
|
|
86
|
+
}
|
|
87
|
+
return return_value;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
//! \see ::EmbeddedProto::ReadBufferInterface::advance()
|
|
91
|
+
bool advance() override
|
|
92
|
+
{
|
|
93
|
+
const bool return_value = write_index_ > read_index_;
|
|
94
|
+
if(return_value)
|
|
95
|
+
{
|
|
96
|
+
++read_index_;
|
|
97
|
+
}
|
|
98
|
+
return return_value;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//! \see ::EmbeddedProto::ReadBufferInterface::advance(const uint32_t N)
|
|
102
|
+
bool advance(const uint32_t n_bytes) override
|
|
103
|
+
{
|
|
104
|
+
const uint32_t new_read_index = read_index_ + n_bytes;
|
|
105
|
+
const bool return_value = write_index_ >= new_read_index;
|
|
106
|
+
if(return_value)
|
|
107
|
+
{
|
|
108
|
+
read_index_ = new_read_index;
|
|
109
|
+
}
|
|
110
|
+
return return_value;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//! \see ::EmbeddedProto::ReadBufferInterface::pop()
|
|
114
|
+
bool pop(uint8_t& byte) override
|
|
115
|
+
{
|
|
116
|
+
const bool return_value = write_index_ > read_index_;
|
|
117
|
+
if(return_value)
|
|
118
|
+
{
|
|
119
|
+
byte = data_[read_index_];
|
|
120
|
+
++read_index_;
|
|
121
|
+
}
|
|
122
|
+
return return_value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//! Keep the single byte forms of peek() reachable next to the override below.
|
|
126
|
+
using ReadBufferInterface::peek;
|
|
127
|
+
|
|
128
|
+
//! \see ::EmbeddedProto::ReadBufferInterface::peek(const bytes_view&)
|
|
129
|
+
bool peek(const bytes_view& dest) const override
|
|
130
|
+
{
|
|
131
|
+
const bool return_value = (write_index_ - read_index_) >= dest.size;
|
|
132
|
+
if(return_value)
|
|
133
|
+
{
|
|
134
|
+
memcpy(dest.data, data_.data() + read_index_, dest.size);
|
|
135
|
+
}
|
|
136
|
+
return return_value;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//! Keep the pointer and length form of pop() reachable next to the override below.
|
|
140
|
+
using ReadBufferInterface::pop;
|
|
141
|
+
|
|
142
|
+
//! \see ::EmbeddedProto::ReadBufferInterface::pop(const bytes_view&)
|
|
143
|
+
bool pop(const bytes_view& dest) override
|
|
144
|
+
{
|
|
145
|
+
// All-or-nothing: only copy and advance when the whole block is present.
|
|
146
|
+
const bool return_value = (write_index_ - read_index_) >= dest.size;
|
|
147
|
+
if(return_value)
|
|
148
|
+
{
|
|
149
|
+
memcpy(dest.data, data_.data() + read_index_, dest.size);
|
|
150
|
+
read_index_ += dest.size;
|
|
151
|
+
}
|
|
152
|
+
return return_value;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//! Return a pointer to the data array. Use set_bytes_written() when adding data to the array.
|
|
156
|
+
uint8_t* get_data()
|
|
157
|
+
{
|
|
158
|
+
return data_.data();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
//! Set the amount of bytes copied to the buffer when using get_data_array().
|
|
162
|
+
void set_bytes_written(const uint32_t n_bytes)
|
|
163
|
+
{
|
|
164
|
+
write_index_ = std::min(n_bytes, BUFFER_SIZE);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
//! Clear all indices, in effect allowing the data to be overwritten.
|
|
168
|
+
void clear()
|
|
169
|
+
{
|
|
170
|
+
read_index_ = 0;
|
|
171
|
+
write_index_ = 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
//! Push a signle byte of data into the buffer.
|
|
175
|
+
/*!
|
|
176
|
+
\tip If you receive a whole message at once consider using get_data_array() in combination
|
|
177
|
+
with set_bytes_written().
|
|
178
|
+
*/
|
|
179
|
+
bool push(const uint8_t& byte)
|
|
180
|
+
{
|
|
181
|
+
const bool return_value = BUFFER_SIZE > write_index_;
|
|
182
|
+
if(return_value)
|
|
183
|
+
{
|
|
184
|
+
data_[write_index_] = byte;
|
|
185
|
+
++write_index_;
|
|
186
|
+
}
|
|
187
|
+
return return_value;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private:
|
|
191
|
+
|
|
192
|
+
//! The array in which the data received over uart is stored.
|
|
193
|
+
std::array<uint8_t, BUFFER_SIZE> data_ = {0};
|
|
194
|
+
|
|
195
|
+
//! The number of bytes currently received and stored in the data array.
|
|
196
|
+
uint32_t write_index_ = 0;
|
|
197
|
+
|
|
198
|
+
//! The number of bytes read from the data array.
|
|
199
|
+
uint32_t read_index_ = 0;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
} // namespace EmbeddedProto
|
|
203
|
+
|
|
204
|
+
#endif // End of _READ_BUFFER_FIXED_H_
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2020-2026 Embedded AMS B.V. - All Rights Reserved
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Embedded Proto.
|
|
5
|
+
*
|
|
6
|
+
* Embedded Proto is dual licensed. You may use it under the terms of the
|
|
7
|
+
* GNU General Public License version 3 (GPLv3) as published by the Free
|
|
8
|
+
* Software Foundation, or under a commercial license from Embedded AMS B.V.
|
|
9
|
+
*
|
|
10
|
+
* Under the GPLv3 you must release the source code of
|
|
11
|
+
* any product you distribute that includes Embedded Proto or code
|
|
12
|
+
* generated by it. A commercial license removes that obligation.
|
|
13
|
+
* See <https://embeddedproto.com/pricing/>.
|
|
14
|
+
*
|
|
15
|
+
* Embedded Proto is distributed WITHOUT ANY WARRANTY; without even the
|
|
16
|
+
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
17
|
+
* See the LICENSE file in the root of the repository for details.
|
|
18
|
+
*
|
|
19
|
+
* SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-EmbeddedProto-Commercial
|
|
20
|
+
*
|
|
21
|
+
* Embedded AMS B.V., Hoorn, the Netherlands - info at EmbeddedProto dot com
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#ifndef _READ_BUFFER_INTERFACE_H_
|
|
25
|
+
#define _READ_BUFFER_INTERFACE_H_
|
|
26
|
+
|
|
27
|
+
#include "Defines.h"
|
|
28
|
+
|
|
29
|
+
#include <cstdint>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
namespace EmbeddedProto
|
|
33
|
+
{
|
|
34
|
+
//! The pure virtual definition of a message buffer to read from.
|
|
35
|
+
/*!
|
|
36
|
+
The buffer deals with bytes (uint8_t) only.
|
|
37
|
+
*/
|
|
38
|
+
class ReadBufferInterface
|
|
39
|
+
{
|
|
40
|
+
public:
|
|
41
|
+
|
|
42
|
+
ReadBufferInterface() = default;
|
|
43
|
+
|
|
44
|
+
#ifdef VIRTUAL_DESTRUCTORS_ENABLED
|
|
45
|
+
virtual ~ReadBufferInterface() = default;
|
|
46
|
+
#else
|
|
47
|
+
protected:
|
|
48
|
+
//! Protected and non-virtual by default, see VIRTUAL_DESTRUCTORS_ENABLED in Defines.h.
|
|
49
|
+
~ReadBufferInterface() = default;
|
|
50
|
+
|
|
51
|
+
public:
|
|
52
|
+
#endif
|
|
53
|
+
|
|
54
|
+
//! Obtain the total number of bytes currently stored in the buffer.
|
|
55
|
+
virtual uint32_t get_size() const = 0;
|
|
56
|
+
|
|
57
|
+
//! Obtain the total number of bytes which can at most be stored in the buffer.
|
|
58
|
+
virtual uint32_t get_max_size() const = 0;
|
|
59
|
+
|
|
60
|
+
//! Obtain the value of the oldest byte in the buffer.
|
|
61
|
+
/*!
|
|
62
|
+
This function will not alter the buffer read index.
|
|
63
|
+
|
|
64
|
+
The parameter byte will not be set if the buffer was empty.
|
|
65
|
+
|
|
66
|
+
\param[out] byte When the buffer is not empty this variable will hold the oldest value.
|
|
67
|
+
\return True when the buffer was not empty.
|
|
68
|
+
*/
|
|
69
|
+
virtual bool peek(uint8_t& byte) const = 0;
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
//! Obtain the value of a byte which will be returned after calling pop() N times.
|
|
73
|
+
/*!
|
|
74
|
+
This function will not alter the buffer read index.
|
|
75
|
+
|
|
76
|
+
The parameter byte will not be set if the buffer was empty.
|
|
77
|
+
|
|
78
|
+
\param[in] n_bytes The number of bytes to read a head.
|
|
79
|
+
\param[out] byte When the buffer is not empty this variable will hold the oldest value.
|
|
80
|
+
\return True not exceesing the buffer limits.
|
|
81
|
+
*/
|
|
82
|
+
virtual bool peek(const uint32_t n_bytes, uint8_t& byte) const = 0;
|
|
83
|
+
|
|
84
|
+
//! Advances the internal read index by one when the buffer is not empty.
|
|
85
|
+
/*!
|
|
86
|
+
\return True when the buffer was not empty.
|
|
87
|
+
*/
|
|
88
|
+
virtual bool advance() = 0;
|
|
89
|
+
|
|
90
|
+
//! Advances the internal read index by the given value.
|
|
91
|
+
/*!
|
|
92
|
+
The advance is limited to the number of bytes in the buffer.
|
|
93
|
+
\param[in] n_bytes The number of bytes to advance the read index.
|
|
94
|
+
\return True when the buffer held the n_bytes or more.
|
|
95
|
+
*/
|
|
96
|
+
virtual bool advance(const uint32_t n_bytes) = 0;
|
|
97
|
+
|
|
98
|
+
//! Obtain the value of the oldest byte in the buffer and remove it from the buffer.
|
|
99
|
+
/*!
|
|
100
|
+
This function will alter the internal read index.
|
|
101
|
+
|
|
102
|
+
The parameter byte will not be set if the buffer was empty.
|
|
103
|
+
|
|
104
|
+
\param[out] byte When the buffer is not empty this variable will hold the oldest value.
|
|
105
|
+
\return True when the buffer was not empty.
|
|
106
|
+
*/
|
|
107
|
+
virtual bool pop(uint8_t& byte) = 0;
|
|
108
|
+
|
|
109
|
+
//! Copy a block of bytes out of the buffer, advancing the read index.
|
|
110
|
+
/*!
|
|
111
|
+
This is the batched counterpart of pop(uint8_t&): it lets callers read
|
|
112
|
+
a whole fixed-width value, a run of them or a string payload in one
|
|
113
|
+
virtual call instead of one call per byte.
|
|
114
|
+
|
|
115
|
+
The operation is all-or-nothing: when fewer than dest.size bytes are
|
|
116
|
+
available nothing is copied and the read index is left unmoved, matching
|
|
117
|
+
the advance(n_bytes) / pop() semantics which never partially consume the
|
|
118
|
+
buffer.
|
|
119
|
+
|
|
120
|
+
The default implementation pops the bytes one at a time. Concrete buffers
|
|
121
|
+
are encouraged to override it with a single block copy (e.g. memcpy) so
|
|
122
|
+
the batching actually reduces the number of operations.
|
|
123
|
+
|
|
124
|
+
\param[out] dest A view on the destination array, dest.size bytes are copied into it.
|
|
125
|
+
\return True when dest.size bytes were available and copied into dest.
|
|
126
|
+
*/
|
|
127
|
+
virtual bool pop(const bytes_view& dest)
|
|
128
|
+
{
|
|
129
|
+
bool result = get_size() >= dest.size;
|
|
130
|
+
for(uint32_t i = 0; result && (i < dest.size); ++i)
|
|
131
|
+
{
|
|
132
|
+
result = pop(dest.data[i]);
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
//! Copy a block of bytes out of the buffer without advancing the read index.
|
|
138
|
+
/*!
|
|
139
|
+
This is the batched counterpart of peek(n_bytes, byte): the bytes stay in
|
|
140
|
+
the buffer, so a caller which may consume only part of the block, such as a
|
|
141
|
+
callback field offering a window, reads it in one virtual call and calls
|
|
142
|
+
advance() for the part it accepted.
|
|
143
|
+
|
|
144
|
+
All-or-nothing like pop(const bytes_view&): when fewer than dest.size bytes
|
|
145
|
+
are available nothing is copied.
|
|
146
|
+
|
|
147
|
+
The default implementation peeks the bytes one at a time. Concrete buffers
|
|
148
|
+
are encouraged to override it with a single block copy.
|
|
149
|
+
|
|
150
|
+
\param[out] dest A view on the destination array, dest.size bytes are copied into it.
|
|
151
|
+
\return True when dest.size bytes were available and copied into dest.
|
|
152
|
+
*/
|
|
153
|
+
virtual bool peek(const bytes_view& dest) const
|
|
154
|
+
{
|
|
155
|
+
bool result = get_size() >= dest.size;
|
|
156
|
+
for(uint32_t i = 0; result && (i < dest.size); ++i)
|
|
157
|
+
{
|
|
158
|
+
result = peek(i, dest.data[i]);
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
//! Copy a block of bytes out of the buffer, pointer and length form of pop(const bytes_view&).
|
|
164
|
+
/*!
|
|
165
|
+
\deprecated Use the array_view overload pop(const bytes_view&), a view keeps the
|
|
166
|
+
pointer and its bound together.
|
|
167
|
+
\param[out] dest Destination array which must be able to hold length bytes.
|
|
168
|
+
\param[in] length The number of bytes to copy out of the buffer.
|
|
169
|
+
\return True when length bytes were available and copied into dest.
|
|
170
|
+
*/
|
|
171
|
+
[[deprecated("use the array_view overload pop(const bytes_view&)")]]
|
|
172
|
+
virtual bool pop(uint8_t* dest, const uint32_t length)
|
|
173
|
+
{
|
|
174
|
+
return pop(bytes_view{dest, length});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
} // End of namespace EmbeddedProto
|
|
180
|
+
|
|
181
|
+
#endif // End of _READ_BUFFER_INTERFACE_H_
|