EmbeddedProto 4.0.0.dev19__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 +63 -0
- EmbeddedProto/Field.py +578 -0
- EmbeddedProto/Oneof.py +78 -0
- EmbeddedProto/ProtoFile.py +188 -0
- EmbeddedProto/TypeDefinitions.py +255 -0
- EmbeddedProto/__init__.py +0 -0
- EmbeddedProto/__main__.py +35 -0
- EmbeddedProto/embedded_proto_options_pb2.py +37 -0
- EmbeddedProto/main.py +199 -0
- EmbeddedProto/templates/FieldBasic_Deserialize.h.jinja2 +33 -0
- EmbeddedProto/templates/FieldBasic_GetSet.h.jinja2 +92 -0
- EmbeddedProto/templates/FieldBasic_Serialize.h.jinja2 +37 -0
- EmbeddedProto/templates/FieldBytes_GetSet.h.jinja2 +86 -0
- EmbeddedProto/templates/FieldEnum_Deserialize.h.jinja2 +33 -0
- EmbeddedProto/templates/FieldEnum_GetSet.h.jinja2 +86 -0
- EmbeddedProto/templates/FieldEnum_Serialize.h.jinja2 +37 -0
- EmbeddedProto/templates/FieldErrorRecursive_GetSet.h.jinja2 +36 -0
- EmbeddedProto/templates/FieldMsg_Deserialize.h.jinja2 +33 -0
- EmbeddedProto/templates/FieldMsg_GetSet.h.jinja2 +100 -0
- EmbeddedProto/templates/FieldMsg_Serialize.h.jinja2 +37 -0
- EmbeddedProto/templates/FieldRepeated_GetSet.h.jinja2 +95 -0
- EmbeddedProto/templates/FieldRepeated_Serialize.h.jinja2 +33 -0
- EmbeddedProto/templates/FieldStringBytes_Serialize.h.jinja2 +37 -0
- EmbeddedProto/templates/FieldString_GetSet.h.jinja2 +86 -0
- EmbeddedProto/templates/Header.h.jinja2 +75 -0
- EmbeddedProto/templates/TypeDefEnum.h.jinja2 +35 -0
- EmbeddedProto/templates/TypeDefMsg.h.jinja2 +473 -0
- EmbeddedProto/templates/TypeOneof.h.jinja2 +180 -0
- EmbeddedProto/version.json +3 -0
- EmbeddedProto-4.0.0.dev19.dist-info/METADATA +210 -0
- EmbeddedProto-4.0.0.dev19.dist-info/RECORD +34 -0
- EmbeddedProto-4.0.0.dev19.dist-info/WHEEL +5 -0
- EmbeddedProto-4.0.0.dev19.dist-info/entry_points.txt +3 -0
- EmbeddedProto-4.0.0.dev19.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
{#
|
|
2
|
+
Copyright (C) 2020-2024 Embedded AMS B.V. - All Rights Reserved
|
|
3
|
+
|
|
4
|
+
This file is part of Embedded Proto.
|
|
5
|
+
|
|
6
|
+
Embedded Proto is open source software: you can redistribute it and/or
|
|
7
|
+
modify it under the terms of the GNU General Public License as published
|
|
8
|
+
by the Free Software Foundation, version 3 of the license.
|
|
9
|
+
|
|
10
|
+
Embedded Proto is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU General Public License
|
|
16
|
+
along with Embedded Proto. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
For commercial and closed source application please visit:
|
|
19
|
+
<https://embeddedproto.com/pricing/>.
|
|
20
|
+
|
|
21
|
+
Embedded AMS B.V.
|
|
22
|
+
Info:
|
|
23
|
+
info at EmbeddedProto dot com
|
|
24
|
+
|
|
25
|
+
Postal address:
|
|
26
|
+
Atoomweg 2
|
|
27
|
+
1627 LE, Hoorn
|
|
28
|
+
the Netherlands
|
|
29
|
+
#}
|
|
30
|
+
{% import 'TypeOneof.h.jinja2' as TypeOneof %}
|
|
31
|
+
{% for tmpl_param in typedef.get_templates() %}
|
|
32
|
+
{{"template<\n" if loop.first}} {{tmpl_param['type']}} {{tmpl_param['name']}}{{", " if not loop.last}}{{"\n>" if loop.last}}
|
|
33
|
+
{% endfor %}
|
|
34
|
+
class {{ typedef.get_name() }} final: public ::EmbeddedProto::MessageInterface
|
|
35
|
+
{
|
|
36
|
+
public:
|
|
37
|
+
{{ typedef.get_name() }}() = default;
|
|
38
|
+
{{ typedef.get_name() }}(const {{typedef.get_name()}}& rhs )
|
|
39
|
+
{
|
|
40
|
+
{% if typedef.fields|length == 0 and typedef.oneofs|length == 0%}
|
|
41
|
+
(void)rhs; // Empty message thus unused.
|
|
42
|
+
{% endif %}
|
|
43
|
+
{% for field in typedef.fields %}
|
|
44
|
+
{% if typedef.optional_fields is defined and field in typedef.optional_fields %}
|
|
45
|
+
if(rhs.has_{{field.get_name()}}())
|
|
46
|
+
{
|
|
47
|
+
set_{{ field.get_name() }}(rhs.get_{{ field.get_name() }}());
|
|
48
|
+
}
|
|
49
|
+
else
|
|
50
|
+
{
|
|
51
|
+
clear_{{ field.get_name() }}();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
{% else %}
|
|
55
|
+
set_{{ field.get_name() }}(rhs.get_{{ field.get_name() }}());
|
|
56
|
+
{% endif %}
|
|
57
|
+
{% endfor %}
|
|
58
|
+
{% for oneof in typedef.oneofs %}
|
|
59
|
+
{{ TypeOneof.assign(oneof)|indent(6) }}
|
|
60
|
+
{% endfor %}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
{{ typedef.get_name() }}(const {{typedef.get_name()}}&& rhs ) noexcept
|
|
64
|
+
{
|
|
65
|
+
{% if typedef.fields|length == 0 and typedef.oneofs|length == 0%}
|
|
66
|
+
(void)rhs; // Empty message thus unused.
|
|
67
|
+
{% endif %}
|
|
68
|
+
{% for field in typedef.fields %}
|
|
69
|
+
{% if typedef.optional_fields is defined and field in typedef.optional_fields %}
|
|
70
|
+
if(rhs.has_{{field.get_name()}}())
|
|
71
|
+
{
|
|
72
|
+
set_{{ field.get_name() }}(rhs.get_{{ field.get_name() }}());
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
{
|
|
76
|
+
clear_{{ field.get_name() }}();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
{% else %}
|
|
80
|
+
set_{{ field.get_name() }}(rhs.get_{{ field.get_name() }}());
|
|
81
|
+
{% endif %}
|
|
82
|
+
{% endfor %}
|
|
83
|
+
{% for oneof in typedef.oneofs %}
|
|
84
|
+
{{ TypeOneof.assign(oneof)|indent(6) }}
|
|
85
|
+
{% endfor %}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
~{{ typedef.get_name() }}() override = default;
|
|
89
|
+
|
|
90
|
+
{% for enum in typedef.nested_enum_definitions %}
|
|
91
|
+
{{ enum.render(environment)|indent(4) }}
|
|
92
|
+
|
|
93
|
+
{% endfor %}
|
|
94
|
+
{% for msg in typedef.nested_msg_definitions %}
|
|
95
|
+
{{ msg.render(environment)|indent(4) }}
|
|
96
|
+
|
|
97
|
+
{% endfor %}
|
|
98
|
+
enum class FieldNumber : uint32_t
|
|
99
|
+
{
|
|
100
|
+
NOT_SET = 0,
|
|
101
|
+
{% for id_set in typedef.field_ids %}
|
|
102
|
+
{{id_set[1]}} = {{id_set[0]}}{{ "," if not loop.last }}
|
|
103
|
+
{% endfor %}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
{{ typedef.name }}& operator=(const {{ typedef.name }}& rhs)
|
|
107
|
+
{
|
|
108
|
+
{% if typedef.fields|length == 0 and typedef.oneofs|length == 0%}
|
|
109
|
+
(void)rhs; // Empty message thus unused.
|
|
110
|
+
{% endif %}
|
|
111
|
+
{% for field in typedef.fields %}
|
|
112
|
+
{% if typedef.optional_fields is defined and field in typedef.optional_fields %}
|
|
113
|
+
if(rhs.has_{{field.get_name()}}())
|
|
114
|
+
{
|
|
115
|
+
set_{{ field.get_name() }}(rhs.get_{{ field.get_name() }}());
|
|
116
|
+
}
|
|
117
|
+
else
|
|
118
|
+
{
|
|
119
|
+
clear_{{ field.get_name() }}();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
{% else %}
|
|
123
|
+
set_{{ field.get_name() }}(rhs.get_{{ field.get_name() }}());
|
|
124
|
+
{% endif %}
|
|
125
|
+
{% endfor %}
|
|
126
|
+
{% for oneof in typedef.oneofs %}
|
|
127
|
+
{{ TypeOneof.assign(oneof)|indent(6) }}
|
|
128
|
+
{% endfor %}
|
|
129
|
+
return *this;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
{{ typedef.name }}& operator=(const {{ typedef.name }}&& rhs) noexcept
|
|
133
|
+
{
|
|
134
|
+
{% if typedef.fields|length == 0 and typedef.oneofs|length == 0%}
|
|
135
|
+
(void)rhs; // Empty message thus unused.
|
|
136
|
+
{% endif %}
|
|
137
|
+
{% for field in typedef.fields %}
|
|
138
|
+
{% if typedef.optional_fields is defined and field in typedef.optional_fields %}
|
|
139
|
+
if(rhs.has_{{field.get_name()}}())
|
|
140
|
+
{
|
|
141
|
+
set_{{ field.get_name() }}(rhs.get_{{ field.get_name() }}());
|
|
142
|
+
}
|
|
143
|
+
else
|
|
144
|
+
{
|
|
145
|
+
clear_{{ field.get_name() }}();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
{% else %}
|
|
149
|
+
set_{{ field.get_name() }}(rhs.get_{{ field.get_name() }}());
|
|
150
|
+
{% endif %}
|
|
151
|
+
{% endfor %}
|
|
152
|
+
{% for oneof in typedef.oneofs %}
|
|
153
|
+
{{ TypeOneof.assign(oneof)|indent(6) }}
|
|
154
|
+
{% endfor %}
|
|
155
|
+
return *this;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
{% for field in typedef.fields %}
|
|
159
|
+
{{ field.render_get_set(environment)|indent(4) }}
|
|
160
|
+
|
|
161
|
+
{% endfor %}
|
|
162
|
+
{% for oneof in typedef.oneofs %}
|
|
163
|
+
FieldNumber get_which_{{oneof.get_name()}}() const { return {{oneof.get_which_oneof()}}; }
|
|
164
|
+
|
|
165
|
+
{% for field in oneof.fields %}
|
|
166
|
+
{{ field.render_get_set(environment)|indent(4) }}
|
|
167
|
+
|
|
168
|
+
{% endfor %}
|
|
169
|
+
{% endfor %}
|
|
170
|
+
|
|
171
|
+
::EmbeddedProto::Error serialize(::EmbeddedProto::WriteBufferInterface& buffer) const override
|
|
172
|
+
{
|
|
173
|
+
{% if typedef.fields|length == 0 and typedef.oneofs|length == 0%}
|
|
174
|
+
(void)buffer; // Empty message thus unused.
|
|
175
|
+
{% endif %}
|
|
176
|
+
::EmbeddedProto::Error return_value = ::EmbeddedProto::Error::NO_ERRORS;
|
|
177
|
+
|
|
178
|
+
{% for field in typedef.fields %}
|
|
179
|
+
{{ field.render_serialize(environment)|indent(6) }}
|
|
180
|
+
|
|
181
|
+
{% endfor %}
|
|
182
|
+
{% for oneof in typedef.oneofs %}
|
|
183
|
+
switch({{oneof.get_which_oneof()}})
|
|
184
|
+
{
|
|
185
|
+
{% for field in oneof.get_fields() %}
|
|
186
|
+
case FieldNumber::{{field.variable_id_name}}:
|
|
187
|
+
{{ field.render_serialize(environment)|indent(10) }}
|
|
188
|
+
break;
|
|
189
|
+
|
|
190
|
+
{% endfor %}
|
|
191
|
+
default:
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
{% endfor %}
|
|
196
|
+
return return_value;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
::EmbeddedProto::Error deserialize(::EmbeddedProto::ReadBufferInterface& buffer) override
|
|
200
|
+
{
|
|
201
|
+
::EmbeddedProto::Error return_value = ::EmbeddedProto::Error::NO_ERRORS;
|
|
202
|
+
::EmbeddedProto::WireFormatter::WireType wire_type = ::EmbeddedProto::WireFormatter::WireType::VARINT;
|
|
203
|
+
uint32_t id_number = 0;
|
|
204
|
+
FieldNumber id_tag = FieldNumber::NOT_SET;
|
|
205
|
+
|
|
206
|
+
::EmbeddedProto::Error tag_value = ::EmbeddedProto::WireFormatter::DeserializeTag(buffer, wire_type, id_number);
|
|
207
|
+
while((::EmbeddedProto::Error::NO_ERRORS == return_value) && (::EmbeddedProto::Error::NO_ERRORS == tag_value))
|
|
208
|
+
{
|
|
209
|
+
id_tag = static_cast<FieldNumber>(id_number);
|
|
210
|
+
switch(id_tag)
|
|
211
|
+
{
|
|
212
|
+
{% for field in typedef.fields %}
|
|
213
|
+
case FieldNumber::{{field.get_variable_id_name()}}:
|
|
214
|
+
{{ field.render_deserialize(environment)|indent(12) }}
|
|
215
|
+
break;
|
|
216
|
+
|
|
217
|
+
{% endfor %}
|
|
218
|
+
{% for oneof in typedef.oneofs %}
|
|
219
|
+
{% for field in oneof.get_fields() %}
|
|
220
|
+
case FieldNumber::{{field.get_variable_id_name()}}:
|
|
221
|
+
{% endfor %}
|
|
222
|
+
return_value = deserialize_{{oneof.get_name()}}(id_tag, buffer, wire_type);
|
|
223
|
+
break;
|
|
224
|
+
|
|
225
|
+
{% endfor %}
|
|
226
|
+
case FieldNumber::NOT_SET:
|
|
227
|
+
return_value = ::EmbeddedProto::Error::INVALID_FIELD_ID;
|
|
228
|
+
break;
|
|
229
|
+
|
|
230
|
+
default:
|
|
231
|
+
return_value = skip_unknown_field(buffer, wire_type);
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if(::EmbeddedProto::Error::NO_ERRORS == return_value)
|
|
236
|
+
{
|
|
237
|
+
// Read the next tag.
|
|
238
|
+
tag_value = ::EmbeddedProto::WireFormatter::DeserializeTag(buffer, wire_type, id_number);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// When an error was detect while reading the tag but no other errors where found, set it in the return value.
|
|
243
|
+
if((::EmbeddedProto::Error::NO_ERRORS == return_value)
|
|
244
|
+
&& (::EmbeddedProto::Error::NO_ERRORS != tag_value)
|
|
245
|
+
&& (::EmbeddedProto::Error::END_OF_BUFFER != tag_value)) // The end of the buffer is not an array in this case.
|
|
246
|
+
{
|
|
247
|
+
return_value = tag_value;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return return_value;
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
void clear() override
|
|
254
|
+
{
|
|
255
|
+
{% for field in typedef.fields %}
|
|
256
|
+
clear_{{field.get_name()}}();
|
|
257
|
+
{% endfor %}
|
|
258
|
+
{% for oneof in typedef.oneofs %}
|
|
259
|
+
clear_{{oneof.get_name()}}();
|
|
260
|
+
{% endfor %}
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
static char const* field_number_to_name(const FieldNumber fieldNumber)
|
|
265
|
+
{
|
|
266
|
+
char const* name = nullptr;
|
|
267
|
+
switch(fieldNumber)
|
|
268
|
+
{
|
|
269
|
+
{% for field in typedef.fields %}
|
|
270
|
+
case FieldNumber::{{field.get_variable_id_name()}}:
|
|
271
|
+
name = {{field.get_name()|upper}}_NAME;
|
|
272
|
+
break;
|
|
273
|
+
{% endfor %}
|
|
274
|
+
{% for oneof in typedef.oneofs %}
|
|
275
|
+
{% for field in oneof.fields %}
|
|
276
|
+
case FieldNumber::{{field.get_variable_id_name()}}:
|
|
277
|
+
name = {{field.get_name()|upper}}_NAME;
|
|
278
|
+
break;
|
|
279
|
+
{% endfor %}
|
|
280
|
+
{% endfor %}
|
|
281
|
+
default:
|
|
282
|
+
name = "Invalid FieldNumber";
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
return name;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
//! Calculate the maximum number of bytes required to serialize this type of message.
|
|
289
|
+
/*!
|
|
290
|
+
This function does not take into account a possible id of this message object is self.
|
|
291
|
+
\return The number of bytes required at most to serialize this message type.
|
|
292
|
+
*/
|
|
293
|
+
static constexpr uint32_t max_serialized_size()
|
|
294
|
+
{
|
|
295
|
+
using namespace ::EmbeddedProto;
|
|
296
|
+
return
|
|
297
|
+
{% for field in typedef.fields %}
|
|
298
|
+
{{" +" if not loop.first }}{{field.get_type()}}::max_serialized_size(static_cast<uint32_t>(FieldNumber::{{field.variable_id_name}}))
|
|
299
|
+
{% endfor %}
|
|
300
|
+
{% for oneof in typedef.oneofs %}
|
|
301
|
+
{{"+ " if not loop.first or typedef.fields|length != 0}}max_serialized_size_{{oneof.get_name()}}()
|
|
302
|
+
{% endfor %}
|
|
303
|
+
{% if typedef.fields|length == 0 and typedef.oneofs|length == 0 %}
|
|
304
|
+
0
|
|
305
|
+
{% endif %}
|
|
306
|
+
;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
//! Calculate the maximum number of bytes required to serialize this message including the field id number and tag.
|
|
310
|
+
/*!
|
|
311
|
+
\return The number of bytes required at most to serialize this message type.
|
|
312
|
+
*/
|
|
313
|
+
static constexpr uint32_t max_serialized_size(const uint32_t field_number)
|
|
314
|
+
{
|
|
315
|
+
using namespace ::EmbeddedProto;
|
|
316
|
+
return WireFormatter::VarintSize(WireFormatter::MakeTag(field_number, WireFormatter::WireType::LENGTH_DELIMITED)) // Size of the tag
|
|
317
|
+
+ WireFormatter::VarintSize(max_serialized_size()) // Length delimted value
|
|
318
|
+
+ max_serialized_size(); // Length of the serialized content
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
#ifdef MSG_TO_STRING
|
|
322
|
+
|
|
323
|
+
::EmbeddedProto::string_view to_string(::EmbeddedProto::string_view& str) const
|
|
324
|
+
{
|
|
325
|
+
return this->to_string(str, 0, nullptr, true);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
::EmbeddedProto::string_view to_string(::EmbeddedProto::string_view& str, const uint32_t indent_level, char const* name, const bool first_field) const override
|
|
329
|
+
{
|
|
330
|
+
::EmbeddedProto::string_view left_chars = str;
|
|
331
|
+
int32_t n_chars_used = 0;
|
|
332
|
+
|
|
333
|
+
if(!first_field)
|
|
334
|
+
{
|
|
335
|
+
// Add a comma behind the previous field.
|
|
336
|
+
n_chars_used = snprintf(left_chars.data, left_chars.size, ",\n");
|
|
337
|
+
if(0 < n_chars_used)
|
|
338
|
+
{
|
|
339
|
+
// Update the character pointer and characters left in the array.
|
|
340
|
+
left_chars.data += n_chars_used;
|
|
341
|
+
left_chars.size -= n_chars_used;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if(nullptr != name)
|
|
346
|
+
{
|
|
347
|
+
if( 0 == indent_level)
|
|
348
|
+
{
|
|
349
|
+
n_chars_used = snprintf(left_chars.data, left_chars.size, "\"%s\": {\n", name);
|
|
350
|
+
}
|
|
351
|
+
else
|
|
352
|
+
{
|
|
353
|
+
n_chars_used = snprintf(left_chars.data, left_chars.size, "%*s\"%s\": {\n", indent_level, " ", name);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
else
|
|
357
|
+
{
|
|
358
|
+
if( 0 == indent_level)
|
|
359
|
+
{
|
|
360
|
+
n_chars_used = snprintf(left_chars.data, left_chars.size, "{\n");
|
|
361
|
+
}
|
|
362
|
+
else
|
|
363
|
+
{
|
|
364
|
+
n_chars_used = snprintf(left_chars.data, left_chars.size, "%*s{\n", indent_level, " ");
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if(0 < n_chars_used)
|
|
369
|
+
{
|
|
370
|
+
left_chars.data += n_chars_used;
|
|
371
|
+
left_chars.size -= n_chars_used;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
{% for field in typedef.fields %}
|
|
375
|
+
{%if "FieldErrorRecursive" != field.descriptor.type_name %}{# Test if this is an FieldErrorRecursive #}
|
|
376
|
+
left_chars = {{field.get_variable_name()}}.to_string(left_chars, indent_level + 2, {{field.get_name()|upper}}_NAME, {{ loop.first|lower }});
|
|
377
|
+
{% endif %}
|
|
378
|
+
{% endfor %}
|
|
379
|
+
{% for oneof in typedef.oneofs %}
|
|
380
|
+
left_chars = to_string_{{oneof.get_name()}}(left_chars, indent_level + 2, {{((typedef.fields|length == 0) and loop.first)|lower }});
|
|
381
|
+
{% endfor %}
|
|
382
|
+
if( 0 == indent_level)
|
|
383
|
+
{
|
|
384
|
+
n_chars_used = snprintf(left_chars.data, left_chars.size, "\n}");
|
|
385
|
+
}
|
|
386
|
+
else
|
|
387
|
+
{
|
|
388
|
+
n_chars_used = snprintf(left_chars.data, left_chars.size, "\n%*s}", indent_level, " ");
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if(0 < n_chars_used)
|
|
392
|
+
{
|
|
393
|
+
left_chars.data += n_chars_used;
|
|
394
|
+
left_chars.size -= n_chars_used;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return left_chars;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
#endif // End of MSG_TO_STRING
|
|
401
|
+
|
|
402
|
+
private:
|
|
403
|
+
|
|
404
|
+
{% if typedef.optional_fields is defined and typedef.optional_fields|length > 0 %}
|
|
405
|
+
// Define constants for tracking the presence of fields.
|
|
406
|
+
// Use a struct to scope the variables from user fields as namespaces are not allowed within classes.
|
|
407
|
+
struct presence
|
|
408
|
+
{
|
|
409
|
+
// An enumeration with all the fields for which presence has to be tracked.
|
|
410
|
+
enum class fields : uint32_t
|
|
411
|
+
{
|
|
412
|
+
{% for field in typedef.optional_fields %}
|
|
413
|
+
{{field.get_name().upper()}}{{ "," if not loop.last }}
|
|
414
|
+
{% endfor %}
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
// The number of fields for which presence has to be tracked.
|
|
418
|
+
static constexpr uint32_t N_FIELDS = {{typedef.optional_fields|length}};
|
|
419
|
+
|
|
420
|
+
// Which type are we using to track presence.
|
|
421
|
+
using TYPE = uint32_t;
|
|
422
|
+
|
|
423
|
+
// How many bits are there in the presence type.
|
|
424
|
+
static constexpr uint32_t N_BITS = std::numeric_limits<TYPE>::digits;
|
|
425
|
+
|
|
426
|
+
// How many variables of TYPE do we need to bit mask all presence fields.
|
|
427
|
+
static constexpr uint32_t SIZE = (N_FIELDS / N_BITS) + ((N_FIELDS % N_BITS) > 0 ? 1 : 0);
|
|
428
|
+
|
|
429
|
+
// Obtain the index of a given field in the presence array.
|
|
430
|
+
static constexpr uint32_t index(const fields& field) { return static_cast<uint32_t>(field) / N_BITS; }
|
|
431
|
+
|
|
432
|
+
// Obtain the bit mask for the given field assuming we are at the correct index in the presence array.
|
|
433
|
+
static constexpr TYPE mask(const fields& field)
|
|
434
|
+
{
|
|
435
|
+
return static_cast<uint32_t>(0x01) << (static_cast<uint32_t>(field) % N_BITS);
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
// Create an array in which the presence flags are stored.
|
|
440
|
+
typename presence::TYPE presence_[presence::SIZE] = {0};
|
|
441
|
+
{% endif %}
|
|
442
|
+
|
|
443
|
+
{% for field in typedef.fields %}
|
|
444
|
+
{% if field.get_default_value() %}
|
|
445
|
+
{{field.get_type()}} {{field.get_variable_name()}} = {{field.get_default_value()}};
|
|
446
|
+
{% else %}
|
|
447
|
+
{{field.get_type()}} {{field.get_variable_name()}};
|
|
448
|
+
{% endif %}
|
|
449
|
+
{% endfor %}
|
|
450
|
+
|
|
451
|
+
{% for oneof in typedef.oneofs %}
|
|
452
|
+
FieldNumber {{oneof.get_which_oneof()}} = FieldNumber::NOT_SET;
|
|
453
|
+
union {{oneof.get_name()}}
|
|
454
|
+
{
|
|
455
|
+
{{oneof.get_name()}}() {}
|
|
456
|
+
~{{oneof.get_name()}}() {}
|
|
457
|
+
{% for field in oneof.fields %}
|
|
458
|
+
{# Here we use the field name variable instead of the get_ function as the get function will add the oneof
|
|
459
|
+
name. This is the only place where this is required. #}
|
|
460
|
+
{{field.get_type()}} {{field.variable_name}};
|
|
461
|
+
{% endfor %}
|
|
462
|
+
};
|
|
463
|
+
{{oneof.get_name()}} {{oneof.get_variable_name()}};
|
|
464
|
+
|
|
465
|
+
{{ TypeOneof.init(oneof)|indent(6) }}
|
|
466
|
+
{{ TypeOneof.clear(oneof)|indent(6) }}
|
|
467
|
+
{{ TypeOneof.deserialize(oneof, environment)|indent(6) }}
|
|
468
|
+
{{ TypeOneof.max_serialized_size(oneof)|indent(6) }}
|
|
469
|
+
#ifdef MSG_TO_STRING
|
|
470
|
+
{{ TypeOneof.to_string(oneof)|indent(6) }}
|
|
471
|
+
#endif // End of MSG_TO_STRING
|
|
472
|
+
{% endfor %}
|
|
473
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
{#
|
|
2
|
+
Copyright (C) 2020-2024 Embedded AMS B.V. - All Rights Reserved
|
|
3
|
+
|
|
4
|
+
This file is part of Embedded Proto.
|
|
5
|
+
|
|
6
|
+
Embedded Proto is open source software: you can redistribute it and/or
|
|
7
|
+
modify it under the terms of the GNU General Public License as published
|
|
8
|
+
by the Free Software Foundation, version 3 of the license.
|
|
9
|
+
|
|
10
|
+
Embedded Proto is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU General Public License
|
|
16
|
+
along with Embedded Proto. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
For commercial and closed source application please visit:
|
|
19
|
+
<https://embeddedproto.com/pricing/>.
|
|
20
|
+
|
|
21
|
+
Embedded AMS B.V.
|
|
22
|
+
Info:
|
|
23
|
+
info at EmbeddedProto dot com
|
|
24
|
+
|
|
25
|
+
Postal address:
|
|
26
|
+
Atoomweg 2
|
|
27
|
+
1627 LE, Hoorn
|
|
28
|
+
the Netherlands
|
|
29
|
+
#}
|
|
30
|
+
{% macro assign(_oneof) %}
|
|
31
|
+
if(rhs.get_which_{{_oneof.get_name()}}() != {{_oneof.get_which_oneof()}})
|
|
32
|
+
{
|
|
33
|
+
// First delete the old object in the oneof.
|
|
34
|
+
clear_{{_oneof.get_name()}}();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
switch(rhs.get_which_{{_oneof.get_name()}}())
|
|
38
|
+
{
|
|
39
|
+
{% for field in _oneof.get_fields() %}
|
|
40
|
+
case FieldNumber::{{field.get_variable_id_name()}}:
|
|
41
|
+
set_{{field.get_name()}}(rhs.get_{{field.name}}());
|
|
42
|
+
break;
|
|
43
|
+
|
|
44
|
+
{% endfor %}
|
|
45
|
+
default:
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
{% endmacro %}
|
|
49
|
+
{# #}
|
|
50
|
+
{# ------------------------------------------------------------------------------------------------------------------ #}
|
|
51
|
+
{# #}
|
|
52
|
+
{% macro init(_oneof) %}
|
|
53
|
+
void init_{{_oneof.get_name()}}(const FieldNumber field_id)
|
|
54
|
+
{
|
|
55
|
+
if(FieldNumber::NOT_SET != {{_oneof.get_which_oneof()}})
|
|
56
|
+
{
|
|
57
|
+
// First delete the old object in the oneof.
|
|
58
|
+
clear_{{_oneof.get_name()}}();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
{% if _oneof.oneof_allocation_required() %}
|
|
62
|
+
// C++11 unions only support nontrivial members when you explicitly call the placement new statement.
|
|
63
|
+
switch(field_id)
|
|
64
|
+
{
|
|
65
|
+
{% for field in _oneof.get_fields() %}
|
|
66
|
+
{% if field.oneof_allocation_required() %}
|
|
67
|
+
case FieldNumber::{{field.get_variable_id_name()}}:
|
|
68
|
+
new(&{{field.get_variable_name()}}) {{field.get_type()}};
|
|
69
|
+
break;
|
|
70
|
+
|
|
71
|
+
{% endif %}
|
|
72
|
+
{% endfor %}
|
|
73
|
+
default:
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
{% endif %}
|
|
78
|
+
{{_oneof.get_which_oneof()}} = field_id;
|
|
79
|
+
}
|
|
80
|
+
{% endmacro %}
|
|
81
|
+
{# #}
|
|
82
|
+
{# ------------------------------------------------------------------------------------------------------------------ #}
|
|
83
|
+
{# #}
|
|
84
|
+
{% macro clear(_oneof) %}
|
|
85
|
+
void clear_{{_oneof.get_name()}}()
|
|
86
|
+
{
|
|
87
|
+
switch({{_oneof.get_which_oneof()}})
|
|
88
|
+
{
|
|
89
|
+
{% for field in _oneof.get_fields() %}
|
|
90
|
+
case FieldNumber::{{field.get_variable_id_name()}}:
|
|
91
|
+
{% if field.oneof_allocation_required() %}
|
|
92
|
+
::EmbeddedProto::destroy_at(&{{field.get_variable_name()}});
|
|
93
|
+
{% elif field.of_type_enum %}
|
|
94
|
+
{{field.get_variable_name()}} = {{field.get_default_value()}};
|
|
95
|
+
{% else %}
|
|
96
|
+
{{field.get_variable_name()}}.set(0);
|
|
97
|
+
{% endif %}
|
|
98
|
+
break;
|
|
99
|
+
{% endfor %}
|
|
100
|
+
default:
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
{{_oneof.get_which_oneof()}} = FieldNumber::NOT_SET;
|
|
104
|
+
}
|
|
105
|
+
{% endmacro %}
|
|
106
|
+
{# #}
|
|
107
|
+
{# ------------------------------------------------------------------------------------------------------------------ #}
|
|
108
|
+
{# #}
|
|
109
|
+
{% macro deserialize(_oneof, _environment) %}
|
|
110
|
+
::EmbeddedProto::Error deserialize_{{_oneof.get_name()}}(const FieldNumber field_id,
|
|
111
|
+
::EmbeddedProto::ReadBufferInterface& buffer,
|
|
112
|
+
const ::EmbeddedProto::WireFormatter::WireType wire_type)
|
|
113
|
+
{
|
|
114
|
+
::EmbeddedProto::Error return_value = ::EmbeddedProto::Error::NO_ERRORS;
|
|
115
|
+
|
|
116
|
+
if(field_id != {{_oneof.get_which_oneof()}})
|
|
117
|
+
{
|
|
118
|
+
init_{{_oneof.get_name()}}(field_id);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
switch({{_oneof.get_which_oneof()}})
|
|
122
|
+
{
|
|
123
|
+
{% for field in _oneof.get_fields() %}
|
|
124
|
+
case FieldNumber::{{field.get_variable_id_name()}}:
|
|
125
|
+
{{ field.render_deserialize(_environment)|indent(6) }}
|
|
126
|
+
break;
|
|
127
|
+
{% endfor %}
|
|
128
|
+
default:
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if(::EmbeddedProto::Error::NO_ERRORS != return_value)
|
|
133
|
+
{
|
|
134
|
+
clear_{{_oneof.get_name()}}();
|
|
135
|
+
}
|
|
136
|
+
return return_value;
|
|
137
|
+
}
|
|
138
|
+
{% endmacro %}
|
|
139
|
+
{# #}
|
|
140
|
+
{# ------------------------------------------------------------------------------------------------------------------ #}
|
|
141
|
+
{# #}
|
|
142
|
+
{% macro to_string(_oneof) %}
|
|
143
|
+
::EmbeddedProto::string_view to_string_{{_oneof.get_name()}}(::EmbeddedProto::string_view& str, const uint32_t indent_level, const bool first_field) const
|
|
144
|
+
{
|
|
145
|
+
::EmbeddedProto::string_view left_chars = str;
|
|
146
|
+
|
|
147
|
+
switch({{_oneof.get_which_oneof()}})
|
|
148
|
+
{
|
|
149
|
+
{% for field in _oneof.get_fields() %}
|
|
150
|
+
case FieldNumber::{{field.get_variable_id_name()}}:
|
|
151
|
+
left_chars = {{field.get_variable_name()}}.to_string(left_chars, indent_level, {{field.get_name()|upper}}_NAME, first_field);
|
|
152
|
+
break;
|
|
153
|
+
{% endfor %}
|
|
154
|
+
default:
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return left_chars;
|
|
159
|
+
}
|
|
160
|
+
{% endmacro %}
|
|
161
|
+
{# #}
|
|
162
|
+
{# ------------------------------------------------------------------------------------------------------------------ #}
|
|
163
|
+
{# #}
|
|
164
|
+
{% macro max_serialized_size(_oneof) %}
|
|
165
|
+
static constexpr uint32_t max_serialized_size_{{_oneof.get_name()}}()
|
|
166
|
+
{
|
|
167
|
+
using namespace EmbeddedProto;
|
|
168
|
+
return
|
|
169
|
+
{% for field in _oneof.get_fields() %}
|
|
170
|
+
{% if not loop.last %}
|
|
171
|
+
{{ ' ' * (loop.index0 * 2) }}max({{field.get_type()}}::max_serialized_size(static_cast<uint32_t>(FieldNumber::{{field.variable_id_name}})),
|
|
172
|
+
{% else %}
|
|
173
|
+
{{ ' ' * (2 + (loop.index0 * 2))}}{{field.get_type()}}::max_serialized_size(static_cast<uint32_t>(FieldNumber::{{field.variable_id_name}}))
|
|
174
|
+
{% endif %}
|
|
175
|
+
{% endfor %}
|
|
176
|
+
{% for i in range(_oneof.get_fields() | length - 1) %}
|
|
177
|
+
{{ ' ' * (5 + (loop.revindex * 2)) }}){{ ";" if loop.last }}
|
|
178
|
+
{% endfor %}
|
|
179
|
+
}
|
|
180
|
+
{% endmacro %}
|