Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
3.1 KiB
86 lines
3.1 KiB
|
|
#include <cstddef> |
|
#include <cstdio> |
|
#include <string> |
|
#include <vector> |
|
|
|
#include <gtest/gtest.h> |
|
#include "google/protobuf/test_messages_proto2.upb.h" |
|
#include "google/protobuf/test_messages_proto2.upb_minitable.h" |
|
#include "upb/base/string_view.h" |
|
#include "upb/base/upcast.h" |
|
#include "upb/mem/arena.h" |
|
#include "upb/message/compare.h" |
|
#include "upb/mini_table/message.h" |
|
#include "upb/wire/decode.h" |
|
#include "upb/wire/encode.h" |
|
|
|
namespace { |
|
|
|
static const upb_MiniTable* kTestMiniTable = |
|
&protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init; |
|
|
|
static void TestEncodeDecodeRoundTrip( |
|
upb_Arena* arena, |
|
std::vector<protobuf_test_messages_proto2_TestAllTypesProto2*> msgs) { |
|
// Encode all of the messages and put their serializations contiguously. |
|
std::string s; |
|
for (auto msg : msgs) { |
|
char* buf; |
|
size_t size; |
|
ASSERT_TRUE(upb_EncodeLengthPrefixed(UPB_UPCAST(msg), kTestMiniTable, 0, |
|
arena, &buf, |
|
&size) == kUpb_EncodeStatus_Ok); |
|
ASSERT_GT(size, 0); // Even empty messages are 1 byte in this encoding. |
|
s.append(std::string(buf, size)); |
|
} |
|
|
|
// Now decode all of the messages contained in the contiguous block. |
|
std::vector<protobuf_test_messages_proto2_TestAllTypesProto2*> decoded; |
|
while (!s.empty()) { |
|
protobuf_test_messages_proto2_TestAllTypesProto2* msg = |
|
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena); |
|
size_t num_bytes_read; |
|
ASSERT_TRUE(upb_DecodeLengthPrefixed( |
|
s.data(), s.length(), UPB_UPCAST(msg), &num_bytes_read, |
|
kTestMiniTable, nullptr, 0, arena) == kUpb_DecodeStatus_Ok); |
|
ASSERT_GT(num_bytes_read, 0); |
|
decoded.push_back(msg); |
|
s = s.substr(num_bytes_read); |
|
} |
|
|
|
// Make sure that the values round tripped correctly. |
|
ASSERT_EQ(msgs.size(), decoded.size()); |
|
for (size_t i = 0; i < msgs.size(); ++i) { |
|
ASSERT_TRUE(upb_Message_IsEqual(UPB_UPCAST(msgs[i]), UPB_UPCAST(decoded[i]), |
|
kTestMiniTable, 0)); |
|
} |
|
} |
|
|
|
TEST(LengthPrefixedTest, OneEmptyMessage) { |
|
upb_Arena* arena = upb_Arena_New(); |
|
protobuf_test_messages_proto2_TestAllTypesProto2* msg = |
|
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena); |
|
TestEncodeDecodeRoundTrip(arena, {msg}); |
|
upb_Arena_Free(arena); |
|
} |
|
|
|
TEST(LengthPrefixedTest, AFewMessages) { |
|
upb_Arena* arena = upb_Arena_New(); |
|
protobuf_test_messages_proto2_TestAllTypesProto2* a = |
|
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena); |
|
protobuf_test_messages_proto2_TestAllTypesProto2* b = |
|
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena); |
|
protobuf_test_messages_proto2_TestAllTypesProto2* c = |
|
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena); |
|
|
|
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_bool(a, true); |
|
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_int32(b, 1); |
|
protobuf_test_messages_proto2_TestAllTypesProto2_set_oneof_string( |
|
c, upb_StringView_FromString("string")); |
|
|
|
TestEncodeDecodeRoundTrip(arena, {a, b, c}); |
|
upb_Arena_Free(arena); |
|
} |
|
|
|
} // namespace
|
|
|