DCCL v4
test.cpp
1 // Copyright 2011-2023:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 // File authors:
6 // Toby Schneider <toby@gobysoft.org>
7 //
8 //
9 // This file is part of the Dynamic Compact Control Language Library
10 // ("DCCL").
11 //
12 // DCCL is free software: you can redistribute it and/or modify
13 // it under the terms of the GNU Lesser General Public License as published by
14 // the Free Software Foundation, either version 2.1 of the License, or
15 // (at your option) any later version.
16 //
17 // DCCL is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public License
23 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
24 // tests all protobuf types with _default codecs, repeat and non repeat
25 
26 #include <fstream>
27 
28 #include <google/protobuf/descriptor.pb.h>
29 
30 #include "../../binary.h"
31 #include "../../codec.h"
32 
33 #if CODEC_VERSION == 3
34 #include "test3.pb.h"
35 #elif CODEC_VERSION == 4
36 #include "test4.pb.h"
37 #endif
38 
39 using namespace dccl::test;
40 
41 dccl::Codec codec;
42 TestMsg msg_in;
43 
44 void decode_check(const std::string& encoded);
45 void test0();
46 void test1();
47 void test2();
48 #if CODEC_VERSION == 4
49 void test3();
50 #endif
51 
52 int main(int /*argc*/, char* /*argv*/ [])
53 {
54  dccl::dlog.connect(dccl::logger::ALL, &std::cerr);
55  test0();
56  test1();
57  test2();
58 #if CODEC_VERSION == 4
59  // oneof
60  test3();
61 #endif
62  std::cout << "all tests passed" << std::endl;
63 }
64 
65 void test0()
66 {
67  msg_in.set_state(TestMsg::STATE_1);
68  msg_in.set_a(40);
69  msg_in.set_b(50);
70  msg_in.set_c(60);
71  msg_in.set_c_center(50);
72  msg_in.add_d(50);
73  msg_in.add_d(100);
74  msg_in.add_d(150);
75  msg_in.add_d(200);
76  msg_in.add_d(250);
77  msg_in.add_d(300);
78  // {
79  // auto c = msg_in.add_child();
80  // c->set_include_i(TestMsg::Child::YES);
81  // c->set_i(1);
82  // }
83  {
84  auto c = msg_in.add_child();
85  c->set_include_i(TestMsg::Child::NO);
86  c->set_i(25);
87  c->set_i2(25);
88  }
89  {
90  auto c = msg_in.add_child();
91  c->set_include_i(TestMsg::Child::YES);
92  c->set_i(45);
93  c->set_i2(45);
94  }
95  {
96  auto c = msg_in.add_child();
97  c->set_include_i(TestMsg::Child::NO);
98  c->set_i(15);
99  c->set_i2(15);
100  }
101 
102  {
103  auto c = msg_in.mutable_child2();
104  c->set_include_i(TestMsg::Child2::NO);
105  c->set_i(13);
106  }
107  {
108  auto c = msg_in.mutable_child3();
109  c->set_include_i(TestMsg::Child3::YES);
110  c->set_i(14);
111 
112  auto sc = c->mutable_subchild();
113  sc->set_include_i(TestMsg::Child2::YES);
114  sc->set_i(15);
115  }
116 
117  codec.info(msg_in.GetDescriptor());
118 
119  std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
120 
121  codec.load(msg_in.GetDescriptor());
122 
123  std::cout << "Try encode..." << std::endl;
124  std::string bytes;
125  codec.encode(&bytes, msg_in);
126  std::cout << "... got bytes (hex): " << dccl::hex_encode(bytes) << std::endl;
127 
128  std::cout << "Try decode..." << std::endl;
129 
130  // b is omitted
131  msg_in.clear_b();
132 
133  // d[3] is omitted
134  msg_in.mutable_d()->erase(msg_in.mutable_d()->begin() + 3);
135 
136  // child[0].i is omitted
137  msg_in.mutable_child(0)->clear_i();
138  msg_in.mutable_child(0)->clear_i2();
139 
140  // child[2].i is omitted
141  msg_in.mutable_child(2)->clear_i();
142  msg_in.mutable_child(2)->clear_i2();
143 
144  msg_in.mutable_child2()->clear_i();
145 
146  decode_check(bytes);
147 }
148 
149 void test1()
150 {
151  msg_in.set_state(TestMsg::STATE_2);
152  msg_in.set_b(15);
153  msg_in.add_d(100);
154  msg_in.add_d(150);
155  msg_in.add_d(200);
156 
157  msg_in.add_d(0);
158 
159  msg_in.add_d(250);
160  msg_in.add_d(300);
161 
162  {
163  auto c = msg_in.add_child();
164  c->set_include_i(TestMsg::Child::YES);
165  c->set_i(50);
166  c->set_i2(45);
167  }
168  {
169  auto c = msg_in.add_child();
170  c->set_include_i(TestMsg::Child::NO);
171  }
172  {
173  auto c = msg_in.mutable_child2();
174  c->set_include_i(TestMsg::Child2::YES);
175  c->set_i(15);
176  }
177 
178  codec.info(msg_in.GetDescriptor());
179 
180  std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
181 
182  codec.load(msg_in.GetDescriptor());
183 
184  std::cout << "Try encode..." << std::endl;
185  std::string bytes;
186  codec.encode(&bytes, msg_in);
187  std::cout << "... got bytes (hex): " << dccl::hex_encode(bytes) << std::endl;
188 
189  std::cout << "Try decode..." << std::endl;
190 
191  msg_in.mutable_d()->erase(msg_in.mutable_d()->begin() + 3);
192 
193  decode_check(bytes);
194 }
195 
196 void test2()
197 {
198  msg_in.set_state(TestMsg::STATE_2);
199  msg_in.set_b(31);
200 
201  {
202  auto c = msg_in.add_child();
203  c->set_include_i(TestMsg::Child::YES);
204  c->set_i(23);
205  c->set_i2(13);
206  }
207  {
208  auto c = msg_in.add_child();
209  c->set_include_i(TestMsg::Child::NO);
210  }
211  {
212  auto c = msg_in.mutable_child2();
213  c->set_include_i(TestMsg::Child2::NO);
214  }
215 
216  codec.info(msg_in.GetDescriptor());
217 
218  std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
219 
220  codec.load(msg_in.GetDescriptor());
221 
222  std::cout << "Try encode..." << std::endl;
223  std::cout << "Min Size: " << codec.min_size(msg_in.GetDescriptor()) << std::endl;
224  std::cout << "Max Size: " << codec.max_size(msg_in.GetDescriptor()) << std::endl;
225  std::vector<char> bytes(codec.size(msg_in), 0);
226 
227  int s = codec.size(msg_in);
228  std::cout << "Size: " << s << std::endl;
229  std::cout << "Bytes Size: " << bytes.size() << std::endl;
230 
231  codec.encode(bytes.data(), bytes.size(), msg_in);
232  std::cout << "... got bytes (hex): "
233  << dccl::hex_encode(std::string(bytes.begin(), bytes.end())) << std::endl;
234 
235  std::cout << "Try decode..." << std::endl;
236 
237  decode_check(std::string(bytes.begin(), bytes.end()));
238 }
239 
240 #if CODEC_VERSION == 4
241 void test3()
242 {
243  msg_in.set_state(TestMsg::STATE_1);
244  msg_in.set_a(10);
245  msg_in.set_c_center(100);
246  msg_in.set_c(100);
247 
248  msg_in.set_y(13);
249  {
250  auto c = msg_in.mutable_child2();
251  c->set_include_i(TestMsg::Child2::NO);
252  }
253 
254  codec.info(msg_in.GetDescriptor());
255 
256  std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
257 
258  codec.load(msg_in.GetDescriptor());
259 
260  std::cout << "Try encode..." << std::endl;
261  std::cout << "Min Size: " << codec.min_size(msg_in.GetDescriptor()) << std::endl;
262  std::cout << "Max Size: " << codec.max_size(msg_in.GetDescriptor()) << std::endl;
263  std::vector<char> bytes(codec.size(msg_in), 0);
264 
265  int s = codec.size(msg_in);
266  std::cout << "Size: " << s << std::endl;
267  std::cout << "Bytes Size: " << bytes.size() << std::endl;
268 
269  codec.encode(bytes.data(), bytes.size(), msg_in);
270  std::cout << "... got bytes (hex): "
271  << dccl::hex_encode(std::string(bytes.begin(), bytes.end())) << std::endl;
272 
273  std::cout << "Try decode..." << std::endl;
274 
275  // y is omitted
276  msg_in.clear_y();
277  decode_check(std::string(bytes.begin(), bytes.end()));
278 }
279 #endif
280 
281 void decode_check(const std::string& encoded)
282 {
283  TestMsg msg_out;
284  codec.decode(encoded, &msg_out);
285 
286  std::cout << "... got Message out:\n" << msg_out.DebugString() << std::endl;
287 
288  assert(msg_in.SerializeAsString() == msg_out.SerializeAsString());
289 
290  msg_in.Clear();
291 }
dccl::test
Unit test namespace.
Definition: test.cpp:44
dccl::Codec
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
Definition: codec.h:62
dccl::Logger::connect
void connect(int verbosity_mask, Slot slot)
Connect the output of one or more given verbosities to a slot (function pointer or similar)
Definition: logger.h:214
dccl::hex_encode
void hex_encode(CharIterator begin, CharIterator end, std::string *out, bool upper_case=false)
Encodes a (little-endian) hexadecimal string from a byte string. Index 0 of begin is written to index...
Definition: binary.h:100