1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
// Test wrapping of a C++ class inside struct using callback_datatype option.
#include "message.pb.hpp"
#include <pb_encode.h>
#include <pb_decode.h>
#include <algorithm>
#include <cstdio>
// See tests/alltypes_callback, tests/oneoff_callback and examples/network_server for more...
bool TestMessage_values_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field)
{
if (ostream != NULL) {
// Encoding callback, serialize items from vector
const std::vector<int> &v = *(const std::vector<int> *)field->pData;
for (std::vector<int>::const_iterator i = v.begin(); i != v.end(); ++i) {
if (!pb_encode_tag_for_field(ostream, field)) {
return false;
}
SubMessage tmp;
tmp.actual_value = *i;
if (!pb_encode_submessage(ostream, SubMessage_fields, &tmp)) {
return false;
}
}
} else if (istream != NULL) {
// Decoding callback, add items to vector
std::vector<int> &v = *(std::vector<int> *)field->pData;
SubMessage tmp;
if (!pb_decode(istream, SubMessage_fields, &tmp)) {
return false;
}
v.push_back(tmp.actual_value);
}
return true;
}
extern "C"
bool TestMessage_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field)
{
if (field->tag == TestMessage_values_tag) {
return TestMessage_values_callback(istream, ostream, field);
}
return true;
}
extern "C"
int main() {
TestMessage source = TestMessage_init_zero; // Not strictly necessary to initialize, just using it to test the initializer.
source.values.push_back(5);
source.values.push_back(4);
source.values.push_back(3);
source.values.push_back(2);
source.values.push_back(1);
std::vector<uint8_t> serialized;
size_t size = 0;
pb_get_encoded_size(&size, TestMessage_fields, &source);
serialized.resize(size);
pb_ostream_t outstream = pb_ostream_from_buffer(&serialized.front(), serialized.size());
if (!pb_encode(&outstream, TestMessage_fields, &source)) {
fprintf(stderr, "Failed to encode: %s\n", PB_GET_ERROR(&outstream));
return 1;
}
TestMessage destination;
pb_istream_t instream = pb_istream_from_buffer(&serialized.front(), outstream.bytes_written);
if (!pb_decode(&instream, TestMessage_fields, &destination)) {
fprintf(stderr, "Failed to decode: %s\n", PB_GET_ERROR(&instream));
return 2;
}
if (source.values != destination.values) {
fprintf(stderr, "Result does not match\n");
fprintf(stderr, "source(%d): ", (int)source.values.size());
for (std::vector<int>::iterator i = source.values.begin(); i != source.values.end(); ++i)
{
fprintf(stderr, "%d, ", *i);
}
fprintf(stderr, "\nencoded(%d): ", (int)serialized.size());
for (unsigned i = 0; i != std::min(serialized.size(), outstream.bytes_written); ++i) {
fprintf(stderr, "0x%02x ", serialized[i]);
}
fprintf(stderr, "\ndestination(%d): ", (int)destination.values.size());
for (std::vector<int>::iterator i = destination.values.begin(); i != destination.values.end(); ++i)
{
fprintf(stderr, "%d, ", *i);
}
fprintf(stderr, "\n");
return 3;
}
return 0;
}
|