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 // Chris Murphy <cmurphy@aphysci.com>
8 //
9 //
10 // This file is part of the Dynamic Compact Control Language Library
11 // ("DCCL").
12 //
13 // DCCL is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU Lesser General Public License as published by
15 // the Free Software Foundation, either version 2.1 of the License, or
16 // (at your option) any later version.
17 //
18 // DCCL is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU Lesser General Public License for more details.
22 //
23 // You should have received a copy of the GNU Lesser General Public License
24 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
25 // tests all protobuf types with _default codecs, repeat and non repeat
26 
27 #include <fstream>
28 
29 #include <google/protobuf/descriptor.pb.h>
30 
31 #include "../../binary.h"
32 #include "../../codec.h"
33 #include "test.pb.h"
34 using namespace dccl::test;
35 
36 void decode_check(const std::string& encoded);
37 dccl::Codec codec;
38 TestMsg msg_in;
39 
40 int main(int /*argc*/, char* /*argv*/ [])
41 {
42  dccl::dlog.connect(dccl::logger::ALL, &std::cerr);
43 
44  int i = 0;
45  msg_in.set_double_default_optional(++i + 0.1);
46  msg_in.set_float_default_optional(++i + 0.2);
47 
48  msg_in.set_int32_default_optional(++i);
49  msg_in.set_int64_default_optional(-++i);
50  msg_in.set_uint32_default_optional(++i);
51  msg_in.set_uint64_default_optional(++i);
52  msg_in.set_sint32_default_optional(-++i);
53  msg_in.set_sint64_default_optional(++i);
54  msg_in.set_fixed32_default_optional(++i);
55  msg_in.set_fixed64_default_optional(++i);
56  msg_in.set_sfixed32_default_optional(++i);
57  msg_in.set_sfixed64_default_optional(-++i);
58 
59  msg_in.set_bool_default_optional(true);
60 
61  msg_in.set_string_default_optional("abc123");
62  msg_in.set_bytes_default_optional(dccl::hex_decode("00112233aabbcc1234"));
63 
64  msg_in.set_enum_default_optional(ENUM_C);
65  msg_in.mutable_msg_default_optional()->set_val(++i + 0.3);
66  msg_in.mutable_msg_default_optional()->mutable_msg()->set_val(++i);
67 
68  msg_in.set_double_default_required(++i + 0.1);
69  msg_in.set_float_default_required(++i + 0.2);
70 
71  msg_in.set_int32_default_required(++i);
72  msg_in.set_int64_default_required(-++i);
73  msg_in.set_uint32_default_required(++i);
74  msg_in.set_uint64_default_required(++i);
75  msg_in.set_sint32_default_required(-++i);
76  msg_in.set_sint64_default_required(++i);
77  msg_in.set_fixed32_default_required(++i);
78  msg_in.set_fixed64_default_required(++i);
79  msg_in.set_sfixed32_default_required(++i);
80  msg_in.set_sfixed64_default_required(-++i);
81 
82  msg_in.set_bool_default_required(true);
83 
84  msg_in.set_string_default_required("abc123");
85  msg_in.set_bytes_default_required(dccl::hex_decode("00112233aabbcc1234"));
86 
87  msg_in.set_enum_default_required(ENUM_C);
88  msg_in.mutable_msg_default_required()->set_val(++i + 0.3);
89  msg_in.mutable_msg_default_required()->mutable_msg()->set_val(++i);
90 
91  for (int j = 0; j < 2; ++j)
92  {
93  msg_in.add_double_default_repeat(++i + 0.1);
94  msg_in.add_float_default_repeat(++i + 0.2);
95 
96  msg_in.add_int32_default_repeat(++i);
97  msg_in.add_int64_default_repeat(-++i);
98  msg_in.add_uint32_default_repeat(++i);
99  msg_in.add_uint64_default_repeat(++i);
100  msg_in.add_sint32_default_repeat(-++i);
101  msg_in.add_sint64_default_repeat(++i);
102  msg_in.add_fixed32_default_repeat(++i);
103  msg_in.add_fixed64_default_repeat(++i);
104  msg_in.add_sfixed32_default_repeat(++i);
105  msg_in.add_sfixed64_default_repeat(-++i);
106 
107  msg_in.add_bool_default_repeat(true);
108 
109  msg_in.add_string_default_repeat("abc123");
110 
111  if (j)
112  msg_in.add_bytes_default_repeat(dccl::hex_decode("00aabbcc"));
113  else
114  msg_in.add_bytes_default_repeat(dccl::hex_decode("ffeedd12"));
115 
116  msg_in.add_enum_default_repeat(static_cast<Enum1>((++i % 3) + 1));
117  EmbeddedMsg1* em_msg = msg_in.add_msg_default_repeat();
118  em_msg->set_val(++i + 0.3);
119  em_msg->mutable_msg()->set_val(++i);
120  }
121 
122  codec.info(msg_in.GetDescriptor());
123 
124  std::ofstream fout("/tmp/testmessage.pb");
125  msg_in.SerializeToOstream(&fout);
126 
127  std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
128 
129  codec.load(msg_in.GetDescriptor());
130 
131  std::cout << "Try encode..." << std::endl;
132  std::string bytes;
133  codec.encode(&bytes, msg_in);
134  std::cout << "... got bytes (hex): " << dccl::hex_encode(bytes) << std::endl;
135 
136  std::cout << "Try decode..." << std::endl;
137  decode_check(bytes);
138 
139  // make sure DCCL defaults stay wire compatible
140 
141  // v4
142  decode_check(
143  dccl::hex_decode("047f277b16b95660c0b0188000d8c0132858800008005b98d8588ccccc0488109951dd659"
144  "6a079fd8c7905d01a29015a99800738012eb880010ee0052d4c6c2c466626012244665477"
145  "9925682c55335e8158e310b1127e1d4858fab84454a3104ca2983214c4e7a22ad164aae96"
146  "41373bd69314c6c2c8661626331e2bf7bb70401547799a5ea29b51942f5b7a91600"));
147 
148  // run a bunch of tests with random strings
149  std::string random = bytes;
150  for (unsigned i = 0; i < 10; ++i)
151  {
152  random[(rand() % (bytes.size() - 1) + 1)] = rand() % 256;
153  std::cout << "Using junk bytes: " << dccl::hex_encode(random) << std::endl;
154 
155  try
156  {
157  TestMsg msg_out;
158  codec.decode(random, &msg_out);
159  }
160  catch (dccl::Exception&)
161  {
162  }
163  }
164 
165  // test verbose encode errors output
166  TestMsg empty;
167  try
168  {
169  std::string dummy;
170  codec.encode(&bytes, empty);
171  }
172  catch (const dccl::Exception& e)
173  {
174  // expected long error
175  std::cout << "Expected verbose error encoding empty message: " << e.what() << std::endl;
176  }
177 
178  std::cout << "all tests passed" << std::endl;
179 }
180 
181 void decode_check(const std::string& encoded)
182 {
183  TestMsg msg_out;
184  codec.decode(encoded, &msg_out);
185 
186  std::cout << "... got Message out:\n" << msg_out.DebugString() << std::endl;
187 
188  // truncate to "max_length" as codec should do
189  msg_in.set_string_default_repeat(0, "abc1");
190  msg_in.set_string_default_repeat(1, "abc1");
191 
192  assert(msg_in.SerializeAsString() == msg_out.SerializeAsString());
193 }
dccl::test
Unit test namespace.
Definition: test.cpp:44
dccl::Exception
Exception class for DCCL.
Definition: exception.h:46
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
dccl::hex_decode
void hex_decode(const std::string &in, std::string *out)
Decodes a (little-endian) hexadecimal string to a byte string. Index 0 and 1 (first byte) of in are w...
Definition: binary.h:51