// Copyright (c) FIRST and other WPILib contributors. // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. #include #include #include #include #include "TestProtoInner.h" #include "wpi/protobuf/ProtobufCallbacks.h" #include "wpiutil.npb.h" struct RepeatedTestProto { std::vector double_msg; std::vector float_msg; std::vector int32_msg; std::vector int64_msg; std::vector uint32_msg; std::vector uint64_msg; std::vector sint32_msg; std::vector sint64_msg; std::vector fixed32_msg; std::vector fixed64_msg; std::vector sfixed32_msg; std::vector sfixed64_msg; wpi::SmallVector bool_msg; std::vector string_msg; std::vector> bytes_msg; std::vector TestProtoInner_msg; }; template <> struct wpi::Protobuf { using MessageStruct = wpi_proto_RepeatedTestProto; using InputStream = wpi::ProtoInputStream; using OutputStream = wpi::ProtoOutputStream; static std::optional Unpack(InputStream& stream); static bool Pack(OutputStream& stream, const RepeatedTestProto& value); }; std::optional wpi::Protobuf::Unpack( InputStream& stream) { RepeatedTestProto toRet; wpi::DirectUnpackCallback> double_msg{ toRet.double_msg}; wpi::DirectUnpackCallback> float_msg{ toRet.float_msg}; wpi::DirectUnpackCallback> int32_msg{ toRet.int32_msg}; wpi::DirectUnpackCallback> int64_msg{ toRet.int64_msg}; wpi::DirectUnpackCallback> uint32_msg{ toRet.uint32_msg}; wpi::DirectUnpackCallback> uint64_msg{ toRet.uint64_msg}; wpi::DirectUnpackCallback> sint32_msg{ toRet.sint32_msg}; wpi::DirectUnpackCallback> sint64_msg{ toRet.sint64_msg}; wpi::DirectUnpackCallback> fixed32_msg{ toRet.fixed32_msg}; wpi::DirectUnpackCallback> fixed64_msg{ toRet.fixed64_msg}; wpi::DirectUnpackCallback> sfixed32_msg{ toRet.sfixed32_msg}; wpi::DirectUnpackCallback> sfixed64_msg{ toRet.sfixed64_msg}; wpi::DirectUnpackCallback> bool_msg{ toRet.bool_msg}; wpi::DirectUnpackCallback> string_msg{ toRet.string_msg}; wpi::DirectUnpackCallback, std::vector>> bytes_msg{toRet.bytes_msg}; wpi::DirectUnpackCallback> TestProtoInner_msg{toRet.TestProtoInner_msg}; wpi_proto_RepeatedTestProto msg{ .double_msg = double_msg.Callback(), .float_msg = float_msg.Callback(), .int32_msg = int32_msg.Callback(), .int64_msg = int64_msg.Callback(), .uint32_msg = uint32_msg.Callback(), .uint64_msg = uint64_msg.Callback(), .sint32_msg = sint32_msg.Callback(), .sint64_msg = sint64_msg.Callback(), .fixed32_msg = fixed32_msg.Callback(), .fixed64_msg = fixed64_msg.Callback(), .sfixed32_msg = sfixed32_msg.Callback(), .sfixed64_msg = sfixed64_msg.Callback(), .bool_msg = bool_msg.Callback(), .string_msg = string_msg.Callback(), .bytes_msg = bytes_msg.Callback(), .TestProtoInner_msg = TestProtoInner_msg.Callback(), }; if (!stream.Decode(msg)) { return {}; } return toRet; } bool wpi::Protobuf::Pack(OutputStream& stream, const RepeatedTestProto& value) { wpi::PackCallback double_msg{value.double_msg}; wpi::PackCallback float_msg{value.float_msg}; wpi::PackCallback int32_msg{value.int32_msg}; wpi::PackCallback int64_msg{value.int64_msg}; wpi::PackCallback uint32_msg{value.uint32_msg}; wpi::PackCallback uint64_msg{value.uint64_msg}; wpi::PackCallback sint32_msg{value.sint32_msg}; wpi::PackCallback sint64_msg{value.sint64_msg}; wpi::PackCallback fixed32_msg{value.fixed32_msg}; wpi::PackCallback fixed64_msg{value.fixed64_msg}; wpi::PackCallback sfixed32_msg{value.sfixed32_msg}; wpi::PackCallback sfixed64_msg{value.sfixed64_msg}; wpi::PackCallback bool_msg{value.bool_msg}; wpi::PackCallback string_msg{value.string_msg}; wpi::PackCallback> bytes_msg{value.bytes_msg}; wpi::PackCallback TestProtoInner_msg{ value.TestProtoInner_msg}; wpi_proto_RepeatedTestProto msg{ .double_msg = double_msg.Callback(), .float_msg = float_msg.Callback(), .int32_msg = int32_msg.Callback(), .int64_msg = int64_msg.Callback(), .uint32_msg = uint32_msg.Callback(), .uint64_msg = uint64_msg.Callback(), .sint32_msg = sint32_msg.Callback(), .sint64_msg = sint64_msg.Callback(), .fixed32_msg = fixed32_msg.Callback(), .fixed64_msg = fixed64_msg.Callback(), .sfixed32_msg = sfixed32_msg.Callback(), .sfixed64_msg = sfixed64_msg.Callback(), .bool_msg = bool_msg.Callback(), .string_msg = string_msg.Callback(), .bytes_msg = bytes_msg.Callback(), .TestProtoInner_msg = TestProtoInner_msg.Callback(), }; return stream.Encode(msg); } namespace { using ProtoType = wpi::Protobuf; } // namespace TEST(RepeatedTestProtoTest, RoundtripNanopb) { RepeatedTestProto kExpectedData = RepeatedTestProto{}; kExpectedData.bool_msg.emplace_back(true); kExpectedData.bool_msg.emplace_back(false); kExpectedData.double_msg.emplace_back(5.05); wpi::ProtobufMessage message; wpi::SmallVector buf; ASSERT_TRUE(message.Pack(buf, kExpectedData)); auto unpacked_data = message.Unpack(buf); ASSERT_TRUE(unpacked_data.has_value()); ASSERT_EQ(kExpectedData.double_msg.size(), unpacked_data->double_msg.size()); ASSERT_EQ(kExpectedData.float_msg.size(), unpacked_data->float_msg.size()); ASSERT_EQ(kExpectedData.int32_msg.size(), unpacked_data->int32_msg.size()); ASSERT_EQ(kExpectedData.int64_msg.size(), unpacked_data->int64_msg.size()); ASSERT_EQ(kExpectedData.uint32_msg.size(), unpacked_data->uint32_msg.size()); ASSERT_EQ(kExpectedData.uint64_msg.size(), unpacked_data->uint64_msg.size()); ASSERT_EQ(kExpectedData.sint32_msg.size(), unpacked_data->sint32_msg.size()); ASSERT_EQ(kExpectedData.sint64_msg.size(), unpacked_data->sint64_msg.size()); ASSERT_EQ(kExpectedData.fixed32_msg.size(), unpacked_data->fixed32_msg.size()); ASSERT_EQ(kExpectedData.fixed64_msg.size(), unpacked_data->fixed64_msg.size()); ASSERT_EQ(kExpectedData.sfixed32_msg.size(), unpacked_data->sfixed32_msg.size()); ASSERT_EQ(kExpectedData.sfixed64_msg.size(), unpacked_data->sfixed64_msg.size()); ASSERT_EQ(kExpectedData.bool_msg.size(), unpacked_data->bool_msg.size()); ASSERT_EQ(kExpectedData.string_msg.size(), unpacked_data->string_msg.size()); ASSERT_EQ(kExpectedData.bytes_msg.size(), unpacked_data->bytes_msg.size()); ASSERT_EQ(kExpectedData.TestProtoInner_msg.size(), unpacked_data->TestProtoInner_msg.size()); }