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.
Files changed (63) hide show
  1. EmbeddedProto/EmbeddedProto.py +122 -0
  2. EmbeddedProto/Features.py +255 -0
  3. EmbeddedProto/Field.py +1295 -0
  4. EmbeddedProto/Oneof.py +74 -0
  5. EmbeddedProto/ProtoFile.py +210 -0
  6. EmbeddedProto/TypeDefinitions.py +367 -0
  7. EmbeddedProto/__init__.py +0 -0
  8. EmbeddedProto/__main__.py +28 -0
  9. EmbeddedProto/config.py +173 -0
  10. EmbeddedProto/custom_header.py +513 -0
  11. EmbeddedProto/embedded_proto_options.proto +62 -0
  12. EmbeddedProto/embedded_proto_options_pb2.py +37 -0
  13. EmbeddedProto/field_options.py +344 -0
  14. EmbeddedProto/main.py +316 -0
  15. EmbeddedProto/src/EmbeddedProto/BytesStringCallback.h +476 -0
  16. EmbeddedProto/src/EmbeddedProto/Defines.h +118 -0
  17. EmbeddedProto/src/EmbeddedProto/EmptyArray.h +81 -0
  18. EmbeddedProto/src/EmbeddedProto/Errors.h +53 -0
  19. EmbeddedProto/src/EmbeddedProto/FieldStringBytes.h +793 -0
  20. EmbeddedProto/src/EmbeddedProto/Fields.h +832 -0
  21. EmbeddedProto/src/EmbeddedProto/Functional.h +412 -0
  22. EmbeddedProto/src/EmbeddedProto/MessageCallback.h +688 -0
  23. EmbeddedProto/src/EmbeddedProto/MessageInterface.h +792 -0
  24. EmbeddedProto/src/EmbeddedProto/MessageSizeCalculator.h +109 -0
  25. EmbeddedProto/src/EmbeddedProto/MessageState.h +207 -0
  26. EmbeddedProto/src/EmbeddedProto/ReadBufferFixedSize.h +204 -0
  27. EmbeddedProto/src/EmbeddedProto/ReadBufferInterface.h +181 -0
  28. EmbeddedProto/src/EmbeddedProto/ReadBufferSection.h +232 -0
  29. EmbeddedProto/src/EmbeddedProto/RepeatedField.h +1053 -0
  30. EmbeddedProto/src/EmbeddedProto/RepeatedFieldCallback.h +432 -0
  31. EmbeddedProto/src/EmbeddedProto/RepeatedFieldFixedSize.h +367 -0
  32. EmbeddedProto/src/EmbeddedProto/Version.h +39 -0
  33. EmbeddedProto/src/EmbeddedProto/WireFormatter.h +852 -0
  34. EmbeddedProto/src/EmbeddedProto/WriteBufferFixedSize.h +114 -0
  35. EmbeddedProto/src/EmbeddedProto/WriteBufferInterface.h +134 -0
  36. EmbeddedProto/src/EmbeddedProto.h +55 -0
  37. EmbeddedProto/templates/FieldBasic_Deserialize.h.jinja2 +26 -0
  38. EmbeddedProto/templates/FieldBasic_GetSet.h.jinja2 +89 -0
  39. EmbeddedProto/templates/FieldBytes_GetSet.h.jinja2 +86 -0
  40. EmbeddedProto/templates/FieldEnum_Deserialize.h.jinja2 +50 -0
  41. EmbeddedProto/templates/FieldEnum_GetSet.h.jinja2 +93 -0
  42. EmbeddedProto/templates/FieldErrorRecursive_GetSet.h.jinja2 +29 -0
  43. EmbeddedProto/templates/FieldMap_GetSet.h.jinja2 +203 -0
  44. EmbeddedProto/templates/FieldMsg_Deserialize.h.jinja2 +44 -0
  45. EmbeddedProto/templates/FieldMsg_GetSet.h.jinja2 +93 -0
  46. EmbeddedProto/templates/FieldRepeated_GetSet.h.jinja2 +94 -0
  47. EmbeddedProto/templates/FieldString_GetSet.h.jinja2 +86 -0
  48. EmbeddedProto/templates/Field_DeserializePartial.h.jinja2 +33 -0
  49. EmbeddedProto/templates/Field_Serialize.h.jinja2 +112 -0
  50. EmbeddedProto/templates/Field_SerializePartial.h.jinja2 +119 -0
  51. EmbeddedProto/templates/Header.h.jinja2 +108 -0
  52. EmbeddedProto/templates/TypeDefEnum.h.jinja2 +45 -0
  53. EmbeddedProto/templates/TypeDefMsg.h.jinja2 +791 -0
  54. EmbeddedProto/templates/TypeOneof.h.jinja2 +178 -0
  55. EmbeddedProto/version.json +3 -0
  56. embeddedproto-4.0.0b1.dist-info/METADATA +141 -0
  57. embeddedproto-4.0.0b1.dist-info/RECORD +63 -0
  58. embeddedproto-4.0.0b1.dist-info/WHEEL +5 -0
  59. embeddedproto-4.0.0b1.dist-info/entry_points.txt +3 -0
  60. embeddedproto-4.0.0b1.dist-info/licenses/LICENSE +30 -0
  61. embeddedproto-4.0.0b1.dist-info/licenses/LICENSES/GPL-3.0-only.txt +674 -0
  62. embeddedproto-4.0.0b1.dist-info/licenses/LICENSES/LicenseRef-EmbeddedProto-Commercial.txt +12 -0
  63. embeddedproto-4.0.0b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,792 @@
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_INTERFACE_H_
25
+ #define _MESSAGE_INTERFACE_H_
26
+
27
+ #include "WireFormatter.h"
28
+ #include "Fields.h"
29
+ #include "Errors.h"
30
+ #include "MessageState.h"
31
+ #include "ReadBufferSection.h"
32
+
33
+ #include <cstdint>
34
+
35
+
36
+ namespace EmbeddedProto
37
+ {
38
+
39
+ class MessageInterface : public ::EmbeddedProto::Field
40
+ {
41
+ public:
42
+
43
+ MessageInterface() = default;
44
+
45
+ ~MessageInterface() = default;
46
+
47
+ //! \see Field::deserialize()
48
+ Error deserialize(::EmbeddedProto::ReadBufferInterface& buffer) override = 0;
49
+
50
+ //! \see Field::deserialize()
51
+ Error deserialize_check_type(::EmbeddedProto::ReadBufferInterface& buffer,
52
+ const ::EmbeddedProto::WireFormatter::WireType& wire_type) final;
53
+
54
+ //! Clear the content of this message and set it to it's default state.
55
+ /*!
56
+ The defaults are to be set according to the Protobuf standard.
57
+ */
58
+ void clear() override = 0;
59
+
60
+ //! Serialize this message as a delimited group (editions message_encoding =
61
+ //! DELIMITED).
62
+ /*!
63
+ Writes a START_GROUP tag, this message's fields inline, then an END_GROUP
64
+ tag. Because group framing carries no length prefix there is no size
65
+ pre-pass, which enables single-pass encoding of (nested) messages.
66
+
67
+ \param field_number The field number for the START/END group tags.
68
+ \param buffer The buffer to write to.
69
+ \return Error::NO_ERRORS when successful.
70
+ */
71
+ Error serialize_as_group(const uint32_t field_number, WriteBufferInterface& buffer) const
72
+ {
73
+ Error return_value = WireFormatter::SerializeVarint(
74
+ WireFormatter::MakeTag(field_number, WireFormatter::WireType::START_GROUP), buffer);
75
+ if(Error::NO_ERRORS == return_value)
76
+ {
77
+ return_value = this->serialize(buffer);
78
+ }
79
+ if(Error::NO_ERRORS == return_value)
80
+ {
81
+ return_value = WireFormatter::SerializeVarint(
82
+ WireFormatter::MakeTag(field_number, WireFormatter::WireType::END_GROUP), buffer);
83
+ }
84
+ return return_value;
85
+ }
86
+
87
+ #ifdef PARTIAL_SERIALIZATION_ENABLED
88
+ //! Deserialize message with partial state support.
89
+ /*!
90
+ This method deserializes the message in chunks, allowing deserialization to be paused
91
+ when the buffer ends and resumed with a fresh buffer.
92
+
93
+ A top-level message carries no length prefix, so this function cannot tell where the
94
+ input ends. After the last field it returns to the tag phase and reports
95
+ Error::END_OF_BUFFER when no next tag is available. Only the caller knows whether more
96
+ data will arrive:
97
+
98
+ \code
99
+ Error result = Error::END_OF_BUFFER;
100
+ while((Error::END_OF_BUFFER == result) && receive_next_chunk(buffer))
101
+ {
102
+ result = msg.deserialize_partial(buffer, state.root());
103
+ }
104
+ const bool complete = (Error::END_OF_BUFFER == result)
105
+ && (FieldProcessingPhase::TAG == state.root().phase);
106
+ \endcode
107
+
108
+ \param buffer Read buffer (may be small).
109
+ \param state External state object (must persist between calls).
110
+ \return Error::END_OF_BUFFER with state.phase == FieldProcessingPhase::TAG when the buffer
111
+ ended at a field boundary. When the caller has no more input the message is
112
+ complete, otherwise call again with a fresh buffer.
113
+ \return Error::END_OF_BUFFER with any other phase when a field was cut, call again with a
114
+ fresh buffer.
115
+ \return Error::NO_ERRORS with state.phase == FieldProcessingPhase::COMPLETE when a
116
+ DELIMITED (group) message consumed its END_GROUP tag, see
117
+ deserialize_partial_as_group().
118
+ \return Other errors on failure (state should be reset).
119
+ */
120
+ virtual Error deserialize_partial(ReadBufferInterface& buffer,
121
+ MessageState& state) = 0;
122
+
123
+ //! Serialize message with partial state support.
124
+ /*!
125
+ This method serializes the message in chunks, allowing serialization to be paused
126
+ when the buffer becomes full and resumed with a fresh buffer.
127
+
128
+ \param buffer Write buffer (may be small).
129
+ \param state External state object (must persist between calls).
130
+ \return Error::NO_ERRORS when complete.
131
+ \return Error::BUFFER_FULL when buffer full, call again with fresh buffer.
132
+ \return Other errors on failure (state should be reset).
133
+ */
134
+ virtual Error serialize_partial(WriteBufferInterface& buffer,
135
+ MessageState& state) const = 0;
136
+
137
+ Error serialize_partial_as_field(uint32_t field_number,
138
+ WriteBufferInterface& buffer,
139
+ MessageState& state,
140
+ bool optional) const override
141
+ {
142
+ Error return_value = Error::NO_ERRORS;
143
+
144
+ // The size of this nested message is calculated once, when the field is entered,
145
+ // and kept in the state. Resuming after a full buffer reuses it instead of
146
+ // walking the whole subtree again for every chunk. Whether the field is emitted
147
+ // at all is decided here as well, so no later phase depends on the stored size.
148
+ if(::EmbeddedProto::FieldProcessingPhase::TAG == state.phase)
149
+ {
150
+ state.size_value = serialized_size();
151
+
152
+ // Skip serializing empty fields for non-optional fields (proto3 default behavior)
153
+ if((!optional) && (0U == state.size_value))
154
+ {
155
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
156
+ }
157
+ }
158
+
159
+ // Handle TAG and SIZE phases using helper method
160
+ if((::EmbeddedProto::FieldProcessingPhase::TAG == state.phase) || (::EmbeddedProto::FieldProcessingPhase::SIZE == state.phase))
161
+ {
162
+ return_value = serialize_partial_tag_and_size(field_number, state.size_value, buffer, state, optional);
163
+ }
164
+
165
+ // A zero sized field never reaches the data phase, serialize_partial_tag_and_size()
166
+ // marks it complete, so the size no longer has to be checked here.
167
+ if(::EmbeddedProto::FieldProcessingPhase::DATA == state.phase)
168
+ {
169
+ if(nullptr != state.child)
170
+ {
171
+ return_value = this->serialize_partial(buffer, *state.child);
172
+ if((Error::NO_ERRORS == return_value) && (::EmbeddedProto::FieldProcessingPhase::COMPLETE == state.child->phase))
173
+ {
174
+ state.bytes_remaining = 0U;
175
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
176
+ }
177
+ }
178
+ else
179
+ {
180
+ return_value = Error::NESTING_TOO_DEEP;
181
+ }
182
+ }
183
+
184
+ return return_value;
185
+ }
186
+
187
+ //! Serialize this message as a delimited group with partial state support.
188
+ /*!
189
+ DELIMITED (group) framing has no length prefix, so there is no SIZE phase.
190
+ The phases used are TAG (write START_GROUP) -> DATA (stream the child) ->
191
+ SIZE (reused to write END_GROUP) -> COMPLETE. Each tag is written
192
+ atomically; on a full buffer the phase is left unchanged so the call
193
+ resumes from the same point with a fresh buffer.
194
+
195
+ \param field_number The field number for the START/END group tags.
196
+ \param buffer The (possibly small) write buffer.
197
+ \param state The state for this group field; state.child streams the body.
198
+ \return Error::NO_ERRORS when complete, Error::BUFFER_FULL to resume.
199
+ */
200
+ Error serialize_partial_as_group(uint32_t field_number,
201
+ WriteBufferInterface& buffer,
202
+ MessageState& state) const
203
+ {
204
+ Error return_value = Error::NO_ERRORS;
205
+
206
+ // Phase TAG: write the START_GROUP tag.
207
+ if(::EmbeddedProto::FieldProcessingPhase::TAG == state.phase)
208
+ {
209
+ const uint32_t tag = WireFormatter::MakeTag(field_number, WireFormatter::WireType::START_GROUP);
210
+ if(buffer.get_available_size() >= WireFormatter::VarintSize(tag))
211
+ {
212
+ return_value = WireFormatter::SerializeVarint(tag, buffer);
213
+ if(Error::NO_ERRORS == return_value)
214
+ {
215
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::DATA;
216
+ }
217
+ }
218
+ else
219
+ {
220
+ return_value = Error::BUFFER_FULL;
221
+ }
222
+ }
223
+
224
+ // Phase DATA: stream the child message's fields.
225
+ if((Error::NO_ERRORS == return_value) && (::EmbeddedProto::FieldProcessingPhase::DATA == state.phase))
226
+ {
227
+ if(nullptr != state.child)
228
+ {
229
+ return_value = this->serialize_partial(buffer, *state.child);
230
+ if((Error::NO_ERRORS == return_value) && (::EmbeddedProto::FieldProcessingPhase::COMPLETE == state.child->phase))
231
+ {
232
+ // Body complete; the END_GROUP tag still has to be written. Reuse the
233
+ // (otherwise unused) SIZE phase to mark "END_GROUP pending".
234
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::SIZE;
235
+ }
236
+ }
237
+ else
238
+ {
239
+ return_value = Error::NESTING_TOO_DEEP;
240
+ }
241
+ }
242
+
243
+ // Phase SIZE (reused): write the END_GROUP tag.
244
+ if((Error::NO_ERRORS == return_value) && (::EmbeddedProto::FieldProcessingPhase::SIZE == state.phase))
245
+ {
246
+ const uint32_t tag = WireFormatter::MakeTag(field_number, WireFormatter::WireType::END_GROUP);
247
+ if(buffer.get_available_size() >= WireFormatter::VarintSize(tag))
248
+ {
249
+ return_value = WireFormatter::SerializeVarint(tag, buffer);
250
+ if(Error::NO_ERRORS == return_value)
251
+ {
252
+ state.bytes_remaining = 0U;
253
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
254
+ }
255
+ }
256
+ else
257
+ {
258
+ return_value = Error::BUFFER_FULL;
259
+ }
260
+ }
261
+
262
+ return return_value;
263
+ }
264
+
265
+ //! Deserialize a length-delimited nested message field with partial state support.
266
+ /*!
267
+ Unlike a top-level message the nested message has a known size. Once the declared
268
+ number of bytes has been consumed the nested Error::END_OF_BUFFER is mapped to
269
+ Error::NO_ERRORS and this field is marked COMPLETE. Error::END_OF_BUFFER from this
270
+ function therefore always means more data is needed.
271
+
272
+ \see Field::deserialize_partial_as_field()
273
+ */
274
+ Error deserialize_partial_as_field(ReadBufferInterface& buffer,
275
+ MessageState& state) override;
276
+
277
+ //! Deserialize a delimited (group) message field with partial state support.
278
+ /*!
279
+ The opening START_GROUP tag has been consumed by the caller (phase DATA).
280
+ The child is streamed until it consumes its matching END_GROUP, at which
281
+ point the child returns Error::NO_ERRORS with phase COMPLETE and this field
282
+ is marked COMPLETE. Error::END_OF_BUFFER means more data is needed.
283
+ */
284
+ Error deserialize_partial_as_group(ReadBufferInterface& buffer,
285
+ MessageState& state);
286
+
287
+ //! When partially deserializing skip bytes in the buffer of an unknown field.
288
+ Error skip_unknown_field_partial(::EmbeddedProto::ReadBufferInterface& buffer,
289
+ MessageState& state) const;
290
+
291
+ //! When partially deserializing skip an unknown DELIMITED (group) field.
292
+ /*!
293
+ The START_GROUP tag has been consumed by the caller (phase DATA). The fields
294
+ inside the group are skipped one at a time until the matching END_GROUP tag is
295
+ consumed, at which point the phase is COMPLETE. Nested groups are counted, not
296
+ recursed into, so the skip takes no level of the state stack. The progress is
297
+ kept in the otherwise unused members of the group state itself, see
298
+ SKIP_GROUP_WIRE_TYPE_SHIFT. Returns END_OF_BUFFER when the buffer runs out
299
+ inside the group, to be resumed with the next buffer.
300
+ */
301
+ Error skip_group_partial(::EmbeddedProto::ReadBufferInterface& buffer,
302
+ MessageState& state) const;
303
+ #endif
304
+
305
+ protected:
306
+ //! When deserializing skip the bytes in the buffer of an unknown field.
307
+ /*!
308
+ This function is used when a field with an unknown id is encountered to move through the
309
+ buffer to the next tag.
310
+ */
311
+ Error skip_unknown_field(::EmbeddedProto::ReadBufferInterface& buffer,
312
+ const ::EmbeddedProto::WireFormatter::WireType& wire_type) const;
313
+
314
+ Error skip_varint(::EmbeddedProto::ReadBufferInterface& buffer) const;
315
+ Error skip_fixed32(::EmbeddedProto::ReadBufferInterface& buffer) const;
316
+ Error skip_fixed64(::EmbeddedProto::ReadBufferInterface& buffer) const;
317
+ Error skip_length_delimited(::EmbeddedProto::ReadBufferInterface& buffer) const;
318
+
319
+ //! Skip an unknown DELIMITED (group) field up to its matching END_GROUP.
320
+ Error skip_group(::EmbeddedProto::ReadBufferInterface& buffer) const;
321
+
322
+ #ifdef PARTIAL_SERIALIZATION_ENABLED
323
+ //! Layout of the group state while skipping an unknown DELIMITED (group) field.
324
+ /*!
325
+ The state of the unknown field keeps wire_type START_GROUP and phase DATA, which
326
+ routes it into skip_group_partial(). The members a group has no other use for
327
+ track the field currently being skipped inside the group:
328
+ - element_index holds the nesting depth of groups inside the unknown group,
329
+ - bytes_remaining holds the bytes still to skip of the inner field,
330
+ - size_value holds the wire type and phase of the inner field, packed as
331
+ (wire_type << SKIP_GROUP_WIRE_TYPE_SHIFT) | phase.
332
+ The initial size_value of zero decodes to phase TAG, the first inner tag.
333
+ */
334
+ static constexpr uint32_t SKIP_GROUP_WIRE_TYPE_SHIFT = 8U;
335
+
336
+ //! Mask of one packed inner field of the size_value, see SKIP_GROUP_WIRE_TYPE_SHIFT.
337
+ static constexpr uint32_t SKIP_GROUP_FIELD_MASK = 0xFFU;
338
+
339
+ //! Pack the wire type and phase of the inner field into size_value.
340
+ static constexpr uint32_t pack_skip_group_field(const WireFormatter::WireType wire_type,
341
+ const FieldProcessingPhase phase)
342
+ {
343
+ return (static_cast<uint32_t>(wire_type) << SKIP_GROUP_WIRE_TYPE_SHIFT)
344
+ | static_cast<uint32_t>(phase);
345
+ }
346
+
347
+ //! Unpack the wire type of the inner field from size_value.
348
+ static constexpr WireFormatter::WireType skip_group_field_wire_type(const uint32_t size_value)
349
+ {
350
+ return static_cast<WireFormatter::WireType>((size_value >> SKIP_GROUP_WIRE_TYPE_SHIFT)
351
+ & SKIP_GROUP_FIELD_MASK);
352
+ }
353
+
354
+ //! Unpack the phase of the inner field from size_value.
355
+ static constexpr FieldProcessingPhase skip_group_field_phase(const uint32_t size_value)
356
+ {
357
+ return static_cast<FieldProcessingPhase>(size_value & SKIP_GROUP_FIELD_MASK);
358
+ }
359
+ #endif
360
+
361
+ };
362
+
363
+
364
+ // Definitions of the member functions declared above. The library is header only, so they are
365
+ // inline.
366
+
367
+ inline Error MessageInterface::deserialize_check_type(::EmbeddedProto::ReadBufferInterface& buffer,
368
+ const ::EmbeddedProto::WireFormatter::WireType& wire_type)
369
+ {
370
+ Error return_value = ::EmbeddedProto::WireFormatter::WireType::LENGTH_DELIMITED == wire_type
371
+ ? Error::NO_ERRORS : Error::INVALID_WIRETYPE;
372
+ if(Error::NO_ERRORS == return_value)
373
+ {
374
+ uint32_t size = 0;
375
+ return_value = ::EmbeddedProto::WireFormatter::DeserializeVarint(buffer, size);
376
+ ::EmbeddedProto::ReadBufferSection bufferSection(buffer, size);
377
+ if(::EmbeddedProto::Error::NO_ERRORS == return_value)
378
+ {
379
+ return_value = deserialize(bufferSection);
380
+ if((Error::END_OF_BUFFER == return_value) && (0U == size))
381
+ {
382
+ // A size of zero is a valid empty message (all fields default). The nested
383
+ // deserialize finds no tag in the empty section and reports END_OF_BUFFER,
384
+ // which is the expected clean end here and not a truncated message.
385
+ return_value = Error::NO_ERRORS;
386
+ }
387
+ else if((Error::NO_ERRORS == return_value) && (0U != bufferSection.get_size()))
388
+ {
389
+ // The nested deserialize only stops before the end of its section after
390
+ // consuming an END_GROUP tag. That tag closes group framing and is malformed
391
+ // inside a length-delimited field. Accepting it would leave the rest of the
392
+ // section to be read as fields of this message.
393
+ return_value = Error::INVALID_WIRETYPE;
394
+ }
395
+ else
396
+ {
397
+ // Any other result is passed on as is.
398
+ }
399
+ }
400
+ }
401
+ return return_value;
402
+ }
403
+
404
+ #ifdef PARTIAL_SERIALIZATION_ENABLED
405
+ inline Error MessageInterface::deserialize_partial_as_field(::EmbeddedProto::ReadBufferInterface& buffer,
406
+ MessageState& state)
407
+ {
408
+ Error return_value = Error::NO_ERRORS;
409
+
410
+ if(::EmbeddedProto::FieldProcessingPhase::SIZE == state.phase)
411
+ {
412
+ return_value = deserialize_partial_size_phase(buffer, state);
413
+ }
414
+
415
+ if((Error::NO_ERRORS == return_value) && (::EmbeddedProto::FieldProcessingPhase::DATA == state.phase))
416
+ {
417
+ if(nullptr != state.child)
418
+ {
419
+ // The section is clamped to what is currently in the buffer, which may be
420
+ // less than the declared nested message size. Track progress against the
421
+ // declared size using the number of bytes actually consumed.
422
+ ::EmbeddedProto::ReadBufferSection section(buffer, state.bytes_remaining);
423
+ const uint32_t section_size_before = section.get_max_size();
424
+ return_value = this->deserialize_partial(section, *state.child);
425
+ const uint32_t bytes_consumed = section_size_before - section.get_size();
426
+ state.bytes_remaining -= bytes_consumed;
427
+
428
+ if((Error::NO_ERRORS == return_value)
429
+ && (::EmbeddedProto::FieldProcessingPhase::COMPLETE == state.child->phase))
430
+ {
431
+ // The child only returns NO_ERRORS in the COMPLETE phase after consuming an
432
+ // END_GROUP tag. That tag closes group framing, which is handled by
433
+ // deserialize_partial_as_group. Inside a length-delimited field it is
434
+ // malformed input, accepting it would end the nested message early with
435
+ // bytes of the section left unread.
436
+ return_value = Error::INVALID_WIRETYPE;
437
+ }
438
+
439
+ if(0U == state.bytes_remaining)
440
+ {
441
+ // The whole nested message has been consumed. The child reports
442
+ // END_OF_BUFFER once its bounded section runs out; for a fully received
443
+ // nested message that simply means it is complete.
444
+ if(Error::END_OF_BUFFER == return_value)
445
+ {
446
+ return_value = Error::NO_ERRORS;
447
+ }
448
+ if(Error::NO_ERRORS == return_value)
449
+ {
450
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
451
+ state.child->reset();
452
+ }
453
+ }
454
+ }
455
+ else
456
+ {
457
+ return_value = Error::NESTING_TOO_DEEP;
458
+ }
459
+ }
460
+
461
+ return return_value;
462
+ }
463
+
464
+ inline Error MessageInterface::deserialize_partial_as_group(::EmbeddedProto::ReadBufferInterface& buffer,
465
+ MessageState& state)
466
+ {
467
+ Error return_value = Error::NO_ERRORS;
468
+
469
+ // Groups have no SIZE phase. The caller consumed the START_GROUP tag and set
470
+ // the phase to DATA.
471
+ if(::EmbeddedProto::FieldProcessingPhase::DATA == state.phase)
472
+ {
473
+ if(nullptr != state.child)
474
+ {
475
+ // Stream the child's fields directly from the buffer. The child's partial
476
+ // deserialize stops (reporting completion) when it consumes its matching
477
+ // END_GROUP; otherwise it returns END_OF_BUFFER to resume later with the
478
+ // child state preserved.
479
+ return_value = this->deserialize_partial(buffer, *state.child);
480
+ if((Error::NO_ERRORS == return_value)
481
+ && (::EmbeddedProto::FieldProcessingPhase::COMPLETE == state.child->phase))
482
+ {
483
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
484
+ state.child->reset();
485
+ }
486
+ }
487
+ else
488
+ {
489
+ return_value = Error::NESTING_TOO_DEEP;
490
+ }
491
+ }
492
+
493
+ return return_value;
494
+ }
495
+
496
+ inline Error MessageInterface::skip_unknown_field_partial(::EmbeddedProto::ReadBufferInterface& buffer,
497
+ MessageState& state) const
498
+ {
499
+ Error return_value = Error::STATE_MISMATCH;
500
+
501
+ if(::EmbeddedProto::WireFormatter::WireType::VARINT == state.wire_type)
502
+ {
503
+ if(::EmbeddedProto::FieldProcessingPhase::DATA == state.phase)
504
+ {
505
+ return_value = skip_varint(buffer);
506
+ if(Error::NO_ERRORS == return_value)
507
+ {
508
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
509
+ }
510
+ }
511
+ }
512
+ else if(::EmbeddedProto::WireFormatter::WireType::FIXED32 == state.wire_type)
513
+ {
514
+ if(::EmbeddedProto::FieldProcessingPhase::DATA == state.phase)
515
+ {
516
+ if(0U == state.bytes_remaining)
517
+ {
518
+ state.bytes_remaining = 4U;
519
+ }
520
+
521
+ const uint32_t bytes_to_advance = (state.bytes_remaining < buffer.get_size())
522
+ ? state.bytes_remaining
523
+ : buffer.get_size();
524
+
525
+ buffer.advance(bytes_to_advance);
526
+ state.bytes_remaining -= bytes_to_advance;
527
+
528
+ if(0U == state.bytes_remaining)
529
+ {
530
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
531
+ return_value = Error::NO_ERRORS;
532
+ }
533
+ else
534
+ {
535
+ return_value = Error::END_OF_BUFFER;
536
+ }
537
+ }
538
+ }
539
+ else if(::EmbeddedProto::WireFormatter::WireType::FIXED64 == state.wire_type)
540
+ {
541
+ if(::EmbeddedProto::FieldProcessingPhase::DATA == state.phase)
542
+ {
543
+ if(0U == state.bytes_remaining)
544
+ {
545
+ state.bytes_remaining = 8U;
546
+ }
547
+
548
+ const uint32_t bytes_to_advance = (state.bytes_remaining < buffer.get_size())
549
+ ? state.bytes_remaining
550
+ : buffer.get_size();
551
+
552
+ buffer.advance(bytes_to_advance);
553
+ state.bytes_remaining -= bytes_to_advance;
554
+
555
+ if(0U == state.bytes_remaining)
556
+ {
557
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
558
+ return_value = Error::NO_ERRORS;
559
+ }
560
+ else
561
+ {
562
+ return_value = Error::END_OF_BUFFER;
563
+ }
564
+ }
565
+ }
566
+ else if(::EmbeddedProto::WireFormatter::WireType::LENGTH_DELIMITED == state.wire_type)
567
+ {
568
+ return_value = Error::NO_ERRORS;
569
+
570
+ if(::EmbeddedProto::FieldProcessingPhase::SIZE == state.phase)
571
+ {
572
+ return_value = deserialize_partial_size_phase(buffer, state);
573
+ }
574
+
575
+ if((Error::NO_ERRORS == return_value) && (::EmbeddedProto::FieldProcessingPhase::DATA == state.phase))
576
+ {
577
+ const uint32_t bytes_to_advance = (state.bytes_remaining < buffer.get_size())
578
+ ? state.bytes_remaining
579
+ : buffer.get_size();
580
+
581
+ buffer.advance(bytes_to_advance);
582
+ state.bytes_remaining -= bytes_to_advance;
583
+
584
+ if(0U == state.bytes_remaining)
585
+ {
586
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
587
+ return_value = Error::NO_ERRORS;
588
+ }
589
+ else
590
+ {
591
+ return_value = Error::END_OF_BUFFER;
592
+ }
593
+ }
594
+ }
595
+ else if(::EmbeddedProto::WireFormatter::WireType::START_GROUP == state.wire_type)
596
+ {
597
+ // An unknown DELIMITED field: skip the whole group up to its END_GROUP.
598
+ if(::EmbeddedProto::FieldProcessingPhase::DATA == state.phase)
599
+ {
600
+ return_value = skip_group_partial(buffer, state);
601
+ }
602
+ }
603
+
604
+ return return_value;
605
+ }
606
+
607
+ inline Error MessageInterface::skip_group_partial(::EmbeddedProto::ReadBufferInterface& buffer,
608
+ MessageState& state) const
609
+ {
610
+ Error return_value = Error::NO_ERRORS;
611
+
612
+ // The field inside the group currently being skipped, restored from the members of
613
+ // the group state, see SKIP_GROUP_WIRE_TYPE_SHIFT. It is cleared after every field,
614
+ // so a resume always continues where the previous buffer ran out: at the next tag
615
+ // or inside a field value.
616
+ MessageState field;
617
+ field.wire_type = skip_group_field_wire_type(state.size_value);
618
+ field.phase = skip_group_field_phase(state.size_value);
619
+ field.bytes_remaining = state.bytes_remaining;
620
+
621
+ bool continue_skipping = true;
622
+ while(continue_skipping)
623
+ {
624
+ if(::EmbeddedProto::FieldProcessingPhase::TAG == field.phase)
625
+ {
626
+ return_value = ::EmbeddedProto::WireFormatter::DeserializeTag(buffer, field.wire_type,
627
+ field.field_id);
628
+ if(Error::NO_ERRORS == return_value)
629
+ {
630
+ if(::EmbeddedProto::WireFormatter::WireType::START_GROUP == field.wire_type)
631
+ {
632
+ // A nested group, count it and go on with the tags inside it.
633
+ ++state.element_index;
634
+ }
635
+ else if(::EmbeddedProto::WireFormatter::WireType::END_GROUP == field.wire_type)
636
+ {
637
+ if(0U == state.element_index)
638
+ {
639
+ // The END_GROUP matching the unknown field, the skip is complete.
640
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
641
+ continue_skipping = false;
642
+ }
643
+ else
644
+ {
645
+ // The END_GROUP of a nested group.
646
+ --state.element_index;
647
+ }
648
+ }
649
+ else
650
+ {
651
+ field.phase = (::EmbeddedProto::WireFormatter::WireType::LENGTH_DELIMITED == field.wire_type)
652
+ ? ::EmbeddedProto::FieldProcessingPhase::SIZE
653
+ : ::EmbeddedProto::FieldProcessingPhase::DATA;
654
+ }
655
+ }
656
+ }
657
+
658
+ if(continue_skipping && (Error::NO_ERRORS == return_value)
659
+ && (::EmbeddedProto::FieldProcessingPhase::TAG != field.phase))
660
+ {
661
+ return_value = skip_unknown_field_partial(buffer, field);
662
+ if((Error::NO_ERRORS == return_value)
663
+ && (::EmbeddedProto::FieldProcessingPhase::COMPLETE == field.phase))
664
+ {
665
+ field.reset();
666
+ }
667
+ }
668
+
669
+ if(Error::NO_ERRORS != return_value)
670
+ {
671
+ continue_skipping = false;
672
+ }
673
+ }
674
+
675
+ // Store the inner field for the next buffer, or clear it when the group is complete.
676
+ if(::EmbeddedProto::FieldProcessingPhase::COMPLETE == state.phase)
677
+ {
678
+ state.size_value = 0U;
679
+ state.bytes_remaining = 0U;
680
+ state.element_index = 0U;
681
+ }
682
+ else
683
+ {
684
+ state.size_value = pack_skip_group_field(field.wire_type, field.phase);
685
+ state.bytes_remaining = field.bytes_remaining;
686
+ }
687
+
688
+ return return_value;
689
+ }
690
+ #endif
691
+
692
+
693
+ inline Error MessageInterface::skip_unknown_field(::EmbeddedProto::ReadBufferInterface& buffer,
694
+ const ::EmbeddedProto::WireFormatter::WireType& wire_type) const
695
+ {
696
+ Error return_value = Error::NO_ERRORS;
697
+
698
+ // Depending on the wire type select one of its valid variable types and deserialize the value.
699
+ switch(wire_type) {
700
+ case ::EmbeddedProto::WireFormatter::WireType::VARINT:
701
+ return_value = skip_varint(buffer);
702
+ break;
703
+
704
+ case ::EmbeddedProto::WireFormatter::WireType::FIXED64:
705
+ return_value = skip_fixed64(buffer);
706
+ break;
707
+
708
+ case ::EmbeddedProto::WireFormatter::WireType::LENGTH_DELIMITED:
709
+ return_value = skip_length_delimited(buffer);
710
+ break;
711
+
712
+ case ::EmbeddedProto::WireFormatter::WireType::FIXED32:
713
+ return_value = skip_fixed32(buffer);
714
+ break;
715
+
716
+ case ::EmbeddedProto::WireFormatter::WireType::START_GROUP:
717
+ // An unknown DELIMITED field: skip the whole group up to its END_GROUP.
718
+ return_value = skip_group(buffer);
719
+ break;
720
+
721
+ default:
722
+ // We should never get here. DeserializeTag catches this case.
723
+ break;
724
+ }
725
+
726
+ return return_value;
727
+ }
728
+
729
+ inline Error MessageInterface::skip_group(::EmbeddedProto::ReadBufferInterface& buffer) const
730
+ {
731
+ // The opening START_GROUP tag has already been consumed. Read and discard
732
+ // fields until the matching END_GROUP. Nested groups are skipped recursively
733
+ // (skip_unknown_field routes START_GROUP back here), so the first END_GROUP
734
+ // seen at this level is the matching one.
735
+ Error return_value = Error::NO_ERRORS;
736
+ bool done = false;
737
+ while((!done) && (Error::NO_ERRORS == return_value))
738
+ {
739
+ ::EmbeddedProto::WireFormatter::WireType wire_type;
740
+ uint32_t id = 0;
741
+ return_value = ::EmbeddedProto::WireFormatter::DeserializeTag(buffer, wire_type, id);
742
+ if(Error::NO_ERRORS == return_value)
743
+ {
744
+ if(::EmbeddedProto::WireFormatter::WireType::END_GROUP == wire_type)
745
+ {
746
+ done = true;
747
+ }
748
+ else
749
+ {
750
+ return_value = skip_unknown_field(buffer, wire_type);
751
+ }
752
+ }
753
+ }
754
+ return return_value;
755
+ }
756
+
757
+
758
+ inline Error MessageInterface::skip_varint(::EmbeddedProto::ReadBufferInterface& buffer) const
759
+ {
760
+ // Use a 64 bit variable to decode the maximum possible number of bytes. As we do not know
761
+ // the actual type.
762
+ uint64_t dummy;
763
+ return ::EmbeddedProto::WireFormatter::DeserializeVarint(buffer, dummy);
764
+ }
765
+
766
+ inline Error MessageInterface::skip_fixed32(::EmbeddedProto::ReadBufferInterface& buffer) const
767
+ {
768
+ float dummy;
769
+ return ::EmbeddedProto::WireFormatter::DeserializeFloat(buffer, dummy);
770
+ }
771
+
772
+ inline Error MessageInterface::skip_fixed64(::EmbeddedProto::ReadBufferInterface& buffer) const
773
+ {
774
+ double dummy;
775
+ return ::EmbeddedProto::WireFormatter::DeserializeDouble(buffer, dummy);
776
+ }
777
+
778
+ inline Error MessageInterface::skip_length_delimited(::EmbeddedProto::ReadBufferInterface& buffer) const
779
+ {
780
+ // First read the number of bytes
781
+ uint32_t n_bytes = 0;
782
+ const Error return_value = ::EmbeddedProto::WireFormatter::DeserializeVarint(buffer, n_bytes);
783
+ if(Error::NO_ERRORS == return_value)
784
+ {
785
+ buffer.advance(n_bytes);
786
+ }
787
+ return return_value;
788
+ }
789
+
790
+ } // End of namespace EmbeddedProto
791
+
792
+ #endif // _MESSAGE_INTERFACE_H_