diff options
author | Scott James Remnant <keybuk@google.com> | 2022-03-23 17:28:18 -0700 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-03-26 01:03:45 +0000 |
commit | a8a1dbd62fb2b7badd7fc08c593fb1895776ae46 (patch) | |
tree | bfe429b9b9a54832b796db536b10decd2e7f3497 | |
parent | 5c95ca3998e63248eb7d1c218844362bb5be9d99 (diff) | |
download | pigweed-a8a1dbd62fb2b7badd7fc08c593fb1895776ae46.tar.gz |
pw_protobuf: Support encoding from pw::Vector
Extend StreamEncoder (and MemoryEncoder) to have WriteRepeatedInt32 etc.
methods that mirror the equivalent ReadRepeatedInt32 etc. methods on
StreamDecoder.
Likewise extend encoder codegen to have a WriteFoo override that accepts
a vector.
Change-Id: I09d374dfa60e36feea8bb3b9f6d5fb701eb7c9b4
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/88963
Reviewed-by: Armando Montanez <amontanez@google.com>
Commit-Queue: Scott James Remnant <keybuk@google.com>
Pigweed-Auto-Submit: Scott James Remnant <keybuk@google.com>
-rw-r--r-- | pw_protobuf/codegen_encoder_test.cc | 35 | ||||
-rw-r--r-- | pw_protobuf/docs.rst | 12 | ||||
-rw-r--r-- | pw_protobuf/encoder_test.cc | 76 | ||||
-rw-r--r-- | pw_protobuf/public/pw_protobuf/encoder.h | 150 | ||||
-rw-r--r-- | pw_protobuf/py/pw_protobuf/codegen_pwpb.py | 202 |
5 files changed, 440 insertions, 35 deletions
diff --git a/pw_protobuf/codegen_encoder_test.cc b/pw_protobuf/codegen_encoder_test.cc index 2787681e3..673213d88 100644 --- a/pw_protobuf/codegen_encoder_test.cc +++ b/pw_protobuf/codegen_encoder_test.cc @@ -343,6 +343,41 @@ TEST(CodegenRepeated, PackedBool) { 0); } +TEST(CodegenRepeated, PackedScalarVector) { + std::byte encode_buffer[32]; + + stream::MemoryWriter writer(encode_buffer); + RepeatedTest::StreamEncoder repeated_test(writer, ByteSpan()); + const pw::Vector<uint32_t, 4> values = {0, 16, 32, 48}; + repeated_test.WriteUint32s(values) + .IgnoreError(); // TODO(pwbug/387): Handle Status properly + repeated_test.WriteFixed32s(values) + .IgnoreError(); // TODO(pwbug/387): Handle Status properly + + // clang-format off + constexpr uint8_t expected_proto[] = { + // uint32s[], v={0, 16, 32, 48} + 0x0a, 0x04, + 0x00, + 0x10, + 0x20, + 0x30, + // fixed32s[]. v={0, 16, 32, 48} + 0x32, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, + }; + // clang-format on + + ConstByteSpan result = writer.WrittenData(); + ASSERT_EQ(repeated_test.status(), OkStatus()); + EXPECT_EQ(result.size(), sizeof(expected_proto)); + EXPECT_EQ(std::memcmp(result.data(), expected_proto, sizeof(expected_proto)), + 0); +} + TEST(CodegenRepeated, NonScalar) { std::byte encode_buffer[32]; diff --git a/pw_protobuf/docs.rst b/pw_protobuf/docs.rst index 84ce59372..9c6d98453 100644 --- a/pw_protobuf/docs.rst +++ b/pw_protobuf/docs.rst @@ -315,6 +315,18 @@ Example ``example_server.cc``: PW_LOG_INFO("Failed to decode proto; %s", client.status().str()); } +Repeated Fields +--------------- +Repeated fields can be encoded a value at a time by repeatedly calling +`WriteInt32` etc., or as a packed field by calling e.g. `WritePackedInt32` with +a `std::span<Type>` or `WriteRepeatedInt32` with a `pw::Vector<Type>` (see +:ref:`module-pw_containers` for details). + +The codegen wrappers provide a `WriteFieldName` method with three signatures. +One that encodes a single value at a time, one that encodes a packed field +from a `std::span<Type>`, and one that encodes a packed field from a +`pw::Vector<Type>`. All three return `Status`. + -------- Decoding -------- diff --git a/pw_protobuf/encoder_test.cc b/pw_protobuf/encoder_test.cc index 3c01c5570..6417f699f 100644 --- a/pw_protobuf/encoder_test.cc +++ b/pw_protobuf/encoder_test.cc @@ -307,6 +307,37 @@ TEST(StreamEncoder, PackedVarintInsufficientSpace) { EXPECT_EQ(encoder.status(), Status::ResourceExhausted()); } +TEST(StreamEncoder, PackedVarintVector) { + std::byte encode_buffer[32]; + MemoryEncoder encoder(encode_buffer); + + // repeated uint32 values = 1; + const pw::Vector<uint32_t, 5> values = {0, 50, 100, 150, 200}; + encoder.WriteRepeatedUint32(1, values) + .IgnoreError(); // TODO(pwbug/387): Handle Status properly + + constexpr uint8_t encoded_proto[] = { + 0x0a, 0x07, 0x00, 0x32, 0x64, 0x96, 0x01, 0xc8, 0x01}; + // key size v[0] v[1] v[2] v[3] v[4] + + ASSERT_EQ(encoder.status(), OkStatus()); + ConstByteSpan result(encoder); + EXPECT_EQ(result.size(), sizeof(encoded_proto)); + EXPECT_EQ(std::memcmp(result.data(), encoded_proto, sizeof(encoded_proto)), + 0); +} + +TEST(StreamEncoder, PackedVarintVectorInsufficientSpace) { + std::byte encode_buffer[8]; + MemoryEncoder encoder(encode_buffer); + + const pw::Vector<uint32_t, 5> values = {0, 50, 100, 150, 200}; + encoder.WriteRepeatedUint32(1, values) + .IgnoreError(); // TODO(pwbug/387): Handle Status properly + + EXPECT_EQ(encoder.status(), Status::ResourceExhausted()); +} + TEST(StreamEncoder, PackedBool) { std::byte encode_buffer[32]; MemoryEncoder encoder(encode_buffer); @@ -353,6 +384,32 @@ TEST(StreamEncoder, PackedFixed) { 0); } +TEST(StreamEncoder, PackedFixedVector) { + std::byte encode_buffer[32]; + MemoryEncoder encoder(encode_buffer); + + // repeated fixed32 values = 1; + const pw::Vector<uint32_t, 5> values = {0, 50, 100, 150, 200}; + encoder.WriteRepeatedFixed32(1, values) + .IgnoreError(); // TODO(pwbug/387): Handle Status properly + + // repeated fixed64 values64 = 2; + const pw::Vector<uint64_t, 1> values64 = {0x0102030405060708}; + encoder.WriteRepeatedFixed64(2, values64) + .IgnoreError(); // TODO(pwbug/387): Handle Status properly + + constexpr uint8_t encoded_proto[] = { + 0x0a, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, + 0x12, 0x08, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01}; + + ASSERT_EQ(encoder.status(), OkStatus()); + ConstByteSpan result(encoder); + EXPECT_EQ(result.size(), sizeof(encoded_proto)); + EXPECT_EQ(std::memcmp(result.data(), encoded_proto, sizeof(encoded_proto)), + 0); +} + TEST(StreamEncoder, PackedZigzag) { std::byte encode_buffer[32]; MemoryEncoder encoder(encode_buffer); @@ -372,6 +429,25 @@ TEST(StreamEncoder, PackedZigzag) { 0); } +TEST(StreamEncoder, PackedZigzagVector) { + std::byte encode_buffer[32]; + MemoryEncoder encoder(encode_buffer); + + // repeated sint32 values = 1; + const pw::Vector<int32_t, 7> values = {-100, -25, -1, 0, 1, 25, 100}; + encoder.WriteRepeatedSint32(1, values) + .IgnoreError(); // TODO(pwbug/387): Handle Status properly + + constexpr uint8_t encoded_proto[] = { + 0x0a, 0x09, 0xc7, 0x01, 0x31, 0x01, 0x00, 0x02, 0x32, 0xc8, 0x01}; + + ASSERT_EQ(encoder.status(), OkStatus()); + ConstByteSpan result(encoder); + EXPECT_EQ(result.size(), sizeof(encoded_proto)); + EXPECT_EQ(std::memcmp(result.data(), encoded_proto, sizeof(encoded_proto)), + 0); +} + TEST(StreamEncoder, ParentUnavailable) { std::byte encode_buffer[32]; MemoryEncoder parent(encode_buffer); diff --git a/pw_protobuf/public/pw_protobuf/encoder.h b/pw_protobuf/public/pw_protobuf/encoder.h index 41117db28..f5b427382 100644 --- a/pw_protobuf/public/pw_protobuf/encoder.h +++ b/pw_protobuf/public/pw_protobuf/encoder.h @@ -24,6 +24,7 @@ #include "pw_assert/assert.h" #include "pw_bytes/endian.h" #include "pw_bytes/span.h" +#include "pw_containers/vector.h" #include "pw_protobuf/config.h" #include "pw_protobuf/wire_format.h" #include "pw_status/status.h" @@ -177,6 +178,16 @@ class StreamEncoder { return WritePackedVarints(field_number, values, VarintEncodeType::kNormal); } + // Writes a repeated uint32 using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedUint32(uint32_t field_number, + const pw::Vector<uint32_t>& values) { + return WritePackedVarints(field_number, + std::span(values.data(), values.size()), + VarintEncodeType::kNormal); + } + // Writes a proto uint64 key-value pair. // // Precondition: Encoder has no active child encoder. @@ -192,6 +203,16 @@ class StreamEncoder { return WritePackedVarints(field_number, values, VarintEncodeType::kNormal); } + // Writes a repeated uint64 using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedUint64(uint32_t field_number, + const pw::Vector<uint64_t>& values) { + return WritePackedVarints(field_number, + std::span(values.data(), values.size()), + VarintEncodeType::kNormal); + } + // Writes a proto int32 key-value pair. // // Precondition: Encoder has no active child encoder. @@ -211,6 +232,18 @@ class StreamEncoder { VarintEncodeType::kNormal); } + // Writes a repeated int32 using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedInt32(uint32_t field_number, + const pw::Vector<int32_t>& values) { + return WritePackedVarints( + field_number, + std::span(reinterpret_cast<const uint32_t*>(values.data()), + values.size()), + VarintEncodeType::kNormal); + } + // Writes a proto int64 key-value pair. // // Precondition: Encoder has no active child encoder. @@ -230,6 +263,18 @@ class StreamEncoder { VarintEncodeType::kNormal); } + // Writes a repeated int64 using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedInt64(uint32_t field_number, + const pw::Vector<int64_t>& values) { + return WritePackedVarints( + field_number, + std::span(reinterpret_cast<const uint64_t*>(values.data()), + values.size()), + VarintEncodeType::kNormal); + } + // Writes a proto sint32 key-value pair. // // Precondition: Encoder has no active child encoder. @@ -249,6 +294,18 @@ class StreamEncoder { VarintEncodeType::kZigZag); } + // Writes a repeated sint32 using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedSint32(uint32_t field_number, + const pw::Vector<int32_t>& values) { + return WritePackedVarints( + field_number, + std::span(reinterpret_cast<const uint32_t*>(values.data()), + values.size()), + VarintEncodeType::kZigZag); + } + // Writes a proto sint64 key-value pair. // // Precondition: Encoder has no active child encoder. @@ -268,6 +325,18 @@ class StreamEncoder { VarintEncodeType::kZigZag); } + // Writes a repeated sint64 using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedSint64(uint32_t field_number, + const pw::Vector<int64_t>& values) { + return WritePackedVarints( + field_number, + std::span(reinterpret_cast<const uint64_t*>(values.data()), + values.size()), + VarintEncodeType::kZigZag); + } + // Writes a proto bool key-value pair. // // Precondition: Encoder has no active child encoder. @@ -288,6 +357,21 @@ class StreamEncoder { VarintEncodeType::kNormal); } + // Writes a repeated bool using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedBool(uint32_t field_number, + const pw::Vector<bool>& values) { + static_assert(sizeof(bool) == sizeof(uint8_t), + "bool must be same size as uint8_t"); + + return WritePackedVarints( + field_number, + std::span(reinterpret_cast<const uint8_t*>(values.data()), + values.size()), + VarintEncodeType::kNormal); + } + // Writes a proto fixed32 key-value pair. // // Precondition: Encoder has no active child encoder. @@ -306,6 +390,17 @@ class StreamEncoder { field_number, std::as_bytes(values), sizeof(uint32_t)); } + // Writes a repeated fixed32 field using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedFixed32(uint32_t field_number, + const pw::Vector<uint32_t>& values) { + return WritePackedFixed( + field_number, + std::as_bytes(std::span(values.data(), values.size())), + sizeof(uint32_t)); + } + // Writes a proto fixed64 key-value pair. // // Precondition: Encoder has no active child encoder. @@ -324,6 +419,17 @@ class StreamEncoder { field_number, std::as_bytes(values), sizeof(uint64_t)); } + // Writes a repeated fixed64 field using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedFixed64(uint32_t field_number, + const pw::Vector<uint64_t>& values) { + return WritePackedFixed( + field_number, + std::as_bytes(std::span(values.data(), values.size())), + sizeof(uint64_t)); + } + // Writes a proto sfixed32 key-value pair. // // Precondition: Encoder has no active child encoder. @@ -340,6 +446,17 @@ class StreamEncoder { field_number, std::as_bytes(values), sizeof(int32_t)); } + // Writes a repeated fixed32 field using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedSfixed32(uint32_t field_number, + const pw::Vector<int32_t>& values) { + return WritePackedFixed( + field_number, + std::as_bytes(std::span(values.data(), values.size())), + sizeof(int32_t)); + } + // Writes a proto sfixed64 key-value pair. // // Precondition: Encoder has no active child encoder. @@ -356,6 +473,17 @@ class StreamEncoder { field_number, std::as_bytes(values), sizeof(int64_t)); } + // Writes a repeated fixed64 field using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedFixed64(uint32_t field_number, + const pw::Vector<int64_t>& values) { + return WritePackedFixed( + field_number, + std::as_bytes(std::span(values.data(), values.size())), + sizeof(int64_t)); + } + // Writes a proto float key-value pair. // // Precondition: Encoder has no active child encoder. @@ -377,6 +505,17 @@ class StreamEncoder { return WritePackedFixed(field_number, std::as_bytes(values), sizeof(float)); } + // Writes a repeated float field using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedFloat(uint32_t field_number, + const pw::Vector<float>& values) { + return WritePackedFixed( + field_number, + std::as_bytes(std::span(values.data(), values.size())), + sizeof(float)); + } + // Writes a proto double key-value pair. // // Precondition: Encoder has no active child encoder. @@ -399,6 +538,17 @@ class StreamEncoder { field_number, std::as_bytes(values), sizeof(double)); } + // Writes a repeated double field using packed encoding. + // + // Precondition: Encoder has no active child encoder. + Status WriteRepeatedDouble(uint32_t field_number, + const pw::Vector<double>& values) { + return WritePackedFixed( + field_number, + std::as_bytes(std::span(values.data(), values.size())), + sizeof(double)); + } + // Writes a proto `bytes` field as a key-value pair. This can also be used to // write a pre-encoded nested submessage directly without using a nested // encoder. diff --git a/pw_protobuf/py/pw_protobuf/codegen_pwpb.py b/pw_protobuf/py/pw_protobuf/codegen_pwpb.py index ae54bd88f..fc28fba72 100644 --- a/pw_protobuf/py/pw_protobuf/codegen_pwpb.py +++ b/pw_protobuf/py/pw_protobuf/codegen_pwpb.py @@ -398,6 +398,15 @@ class PackedDoubleWriteMethod(PackedWriteMethod): return 'WritePackedDouble' +class PackedDoubleWriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of doubles.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<double>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedDouble' + + class DoubleReadMethod(ReadMethod): """Method which reads a proto double value.""" def _result_type(self) -> str: @@ -443,6 +452,15 @@ class PackedFloatWriteMethod(PackedWriteMethod): return 'WritePackedFloat' +class PackedFloatWriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of floats.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<float>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedFloat' + + class FloatReadMethod(ReadMethod): """Method which reads a proto float value.""" def _result_type(self) -> str: @@ -488,6 +506,15 @@ class PackedInt32WriteMethod(PackedWriteMethod): return 'WritePackedInt32' +class PackedInt32WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of int32.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<int32_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedInt32' + + class Int32ReadMethod(ReadMethod): """Method which reads a proto int32 value.""" def _result_type(self) -> str: @@ -533,6 +560,15 @@ class PackedSint32WriteMethod(PackedWriteMethod): return 'WritePackedSint32' +class PackedSint32WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of sint32.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<int32_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedSint32' + + class Sint32ReadMethod(ReadMethod): """Method which reads a proto sint32 value.""" def _result_type(self) -> str: @@ -578,6 +614,15 @@ class PackedSfixed32WriteMethod(PackedWriteMethod): return 'WritePackedSfixed32' +class PackedSfixed32WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of sfixed32.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<int32_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedSfixed32' + + class Sfixed32ReadMethod(ReadMethod): """Method which reads a proto sfixed32 value.""" def _result_type(self) -> str: @@ -615,7 +660,7 @@ class Int64WriteMethod(WriteMethod): class PackedInt64WriteMethod(PackedWriteMethod): - """Method which writes a proto int64 value.""" + """Method which writes a packed list of int64.""" def params(self) -> List[Tuple[str, str]]: return [('std::span<const int64_t>', 'values')] @@ -623,6 +668,15 @@ class PackedInt64WriteMethod(PackedWriteMethod): return 'WritePackedInt64' +class PackedInt64WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of int64.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<int64_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedInt64' + + class Int64ReadMethod(ReadMethod): """Method which reads a proto int64 value.""" def _result_type(self) -> str: @@ -660,7 +714,7 @@ class Sint64WriteMethod(WriteMethod): class PackedSint64WriteMethod(PackedWriteMethod): - """Method which writes a proto sint64 value.""" + """Method which writes a packst list of sint64.""" def params(self) -> List[Tuple[str, str]]: return [('std::span<const int64_t>', 'values')] @@ -668,6 +722,15 @@ class PackedSint64WriteMethod(PackedWriteMethod): return 'WritePackedSint64' +class PackedSint64WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of sint64.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<int64_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedSint64' + + class Sint64ReadMethod(ReadMethod): """Method which reads a proto sint64 value.""" def _result_type(self) -> str: @@ -705,7 +768,7 @@ class Sfixed64WriteMethod(WriteMethod): class PackedSfixed64WriteMethod(PackedWriteMethod): - """Method which writes a proto sfixed64 value.""" + """Method which writes a packed list of sfixed64.""" def params(self) -> List[Tuple[str, str]]: return [('std::span<const int64_t>', 'values')] @@ -713,6 +776,15 @@ class PackedSfixed64WriteMethod(PackedWriteMethod): return 'WritePackedSfixed4' +class PackedSfixed64WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of sfixed64.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<int64_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedSfixed4' + + class Sfixed64ReadMethod(ReadMethod): """Method which reads a proto sfixed64 value.""" def _result_type(self) -> str: @@ -750,7 +822,7 @@ class Uint32WriteMethod(WriteMethod): class PackedUint32WriteMethod(PackedWriteMethod): - """Method which writes a proto uint32 value.""" + """Method which writes a packed list of uint32.""" def params(self) -> List[Tuple[str, str]]: return [('std::span<const uint32_t>', 'values')] @@ -758,6 +830,15 @@ class PackedUint32WriteMethod(PackedWriteMethod): return 'WritePackedUint32' +class PackedUint32WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of uint32.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<uint32_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedUint32' + + class Uint32ReadMethod(ReadMethod): """Method which reads a proto uint32 value.""" def _result_type(self) -> str: @@ -795,7 +876,7 @@ class Fixed32WriteMethod(WriteMethod): class PackedFixed32WriteMethod(PackedWriteMethod): - """Method which writes a proto fixed32 value.""" + """Method which writes a packed list of fixed32.""" def params(self) -> List[Tuple[str, str]]: return [('std::span<const uint32_t>', 'values')] @@ -803,6 +884,15 @@ class PackedFixed32WriteMethod(PackedWriteMethod): return 'WritePackedFixed32' +class PackedFixed32WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of fixed32.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<uint32_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedFixed32' + + class Fixed32ReadMethod(ReadMethod): """Method which reads a proto fixed32 value.""" def _result_type(self) -> str: @@ -840,7 +930,7 @@ class Uint64WriteMethod(WriteMethod): class PackedUint64WriteMethod(PackedWriteMethod): - """Method which writes a proto uint64 value.""" + """Method which writes a packed list of uint64.""" def params(self) -> List[Tuple[str, str]]: return [('std::span<const uint64_t>', 'values')] @@ -848,6 +938,15 @@ class PackedUint64WriteMethod(PackedWriteMethod): return 'WritePackedUint64' +class PackedUint64WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of uint64.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<uint64_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedUint64' + + class Uint64ReadMethod(ReadMethod): """Method which reads a proto uint64 value.""" def _result_type(self) -> str: @@ -885,7 +984,7 @@ class Fixed64WriteMethod(WriteMethod): class PackedFixed64WriteMethod(PackedWriteMethod): - """Method which writes a proto fixed64 value.""" + """Method which writes a packed list of fixed64.""" def params(self) -> List[Tuple[str, str]]: return [('std::span<const uint64_t>', 'values')] @@ -893,6 +992,15 @@ class PackedFixed64WriteMethod(PackedWriteMethod): return 'WritePackedFixed64' +class PackedFixed64WriteVectorMethod(PackedWriteMethod): + """Method which writes a packed list of fixed64.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<uint64_t>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedFixed64' + + class Fixed64ReadMethod(ReadMethod): """Method which reads a proto fixed64 value.""" def _result_type(self) -> str: @@ -938,6 +1046,15 @@ class PackedBoolWriteMethod(PackedWriteMethod): return 'WritePackedBool' +class PackedBoolWriteVectorMethod(PackedWriteMethod): + """Method which writes a packed vector of bools.""" + def params(self) -> List[Tuple[str, str]]: + return [('const ::pw::Vector<bool>&', 'values')] + + def _encoder_fn(self) -> str: + return 'WriteRepeatedBool' + + class BoolReadMethod(ReadMethod): """Method which reads a proto bool value.""" def _result_type(self) -> str: @@ -1046,40 +1163,55 @@ class EnumReadMethod(ReadMethod): # Mapping of protobuf field types to their method definitions. PROTO_FIELD_WRITE_METHODS: Dict[int, List] = { - descriptor_pb2.FieldDescriptorProto.TYPE_DOUBLE: - [DoubleWriteMethod, PackedDoubleWriteMethod], + descriptor_pb2.FieldDescriptorProto.TYPE_DOUBLE: [ + DoubleWriteMethod, PackedDoubleWriteMethod, + PackedDoubleWriteVectorMethod + ], descriptor_pb2.FieldDescriptorProto.TYPE_FLOAT: - [FloatWriteMethod, PackedFloatWriteMethod], + [FloatWriteMethod, PackedFloatWriteMethod, PackedFloatWriteVectorMethod], descriptor_pb2.FieldDescriptorProto.TYPE_INT32: - [Int32WriteMethod, PackedInt32WriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_SINT32: - [Sint32WriteMethod, PackedSint32WriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_SFIXED32: - [Sfixed32WriteMethod, PackedSfixed32WriteMethod], + [Int32WriteMethod, PackedInt32WriteMethod, PackedInt32WriteVectorMethod], + descriptor_pb2.FieldDescriptorProto.TYPE_SINT32: [ + Sint32WriteMethod, PackedSint32WriteMethod, + PackedSint32WriteVectorMethod + ], + descriptor_pb2.FieldDescriptorProto.TYPE_SFIXED32: [ + Sfixed32WriteMethod, PackedSfixed32WriteMethod, + PackedSfixed32WriteVectorMethod + ], descriptor_pb2.FieldDescriptorProto.TYPE_INT64: - [Int64WriteMethod, PackedInt64WriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_SINT64: - [Sint64WriteMethod, PackedSint64WriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_SFIXED64: - [Sfixed64WriteMethod, PackedSfixed64WriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_UINT32: - [Uint32WriteMethod, PackedUint32WriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_FIXED32: - [Fixed32WriteMethod, PackedFixed32WriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_UINT64: - [Uint64WriteMethod, PackedUint64WriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_FIXED64: - [Fixed64WriteMethod, PackedFixed64WriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_BOOL: [ - BoolWriteMethod, PackedBoolWriteMethod + [Int64WriteMethod, PackedInt64WriteMethod, PackedInt64WriteVectorMethod], + descriptor_pb2.FieldDescriptorProto.TYPE_SINT64: [ + Sint64WriteMethod, PackedSint64WriteMethod, + PackedSint64WriteVectorMethod ], - descriptor_pb2.FieldDescriptorProto.TYPE_BYTES: [BytesWriteMethod], - descriptor_pb2.FieldDescriptorProto.TYPE_STRING: [ - StringLenWriteMethod, StringWriteMethod + descriptor_pb2.FieldDescriptorProto.TYPE_SFIXED64: [ + Sfixed64WriteMethod, PackedSfixed64WriteMethod, + PackedSfixed64WriteVectorMethod + ], + descriptor_pb2.FieldDescriptorProto.TYPE_UINT32: [ + Uint32WriteMethod, PackedUint32WriteMethod, + PackedUint32WriteVectorMethod ], - descriptor_pb2.FieldDescriptorProto.TYPE_MESSAGE: [ - SubMessageEncoderMethod + descriptor_pb2.FieldDescriptorProto.TYPE_FIXED32: [ + Fixed32WriteMethod, PackedFixed32WriteMethod, + PackedFixed32WriteVectorMethod + ], + descriptor_pb2.FieldDescriptorProto.TYPE_UINT64: [ + Uint64WriteMethod, PackedUint64WriteMethod, + PackedUint64WriteVectorMethod ], + descriptor_pb2.FieldDescriptorProto.TYPE_FIXED64: [ + Fixed64WriteMethod, PackedFixed64WriteMethod, + PackedFixed64WriteVectorMethod + ], + descriptor_pb2.FieldDescriptorProto.TYPE_BOOL: + [BoolWriteMethod, PackedBoolWriteMethod, PackedBoolWriteVectorMethod], + descriptor_pb2.FieldDescriptorProto.TYPE_BYTES: [BytesWriteMethod], + descriptor_pb2.FieldDescriptorProto.TYPE_STRING: + [StringLenWriteMethod, StringWriteMethod], + descriptor_pb2.FieldDescriptorProto.TYPE_MESSAGE: + [SubMessageEncoderMethod], descriptor_pb2.FieldDescriptorProto.TYPE_ENUM: [EnumWriteMethod], } |