27#include "../../arithmetic/field_codec_arithmetic.h"
28#include "../../codec.h"
30#include "test_arithmetic.pb.h"
32#include "../../binary.h"
33using namespace dccl::test::arith;
36 const google::protobuf::Message& msg_in,
bool set_model =
true)
44 void* dl_handle = dlopen(DCCL_ARITHMETIC_NAME, RTLD_LAZY);
47 std::cerr <<
"Failed to open " << DCCL_ARITHMETIC_NAME << std::endl;
50 codec.load_library(dl_handle);
55 model.set_name(
"model");
56 dccl::arith::ModelManager::set_model(codec, model);
59 if (dccl::dlog.is(dccl::logger::INFO))
60 codec.info(msg_in.GetDescriptor(), &dccl::dlog);
62 codec.load(msg_in.GetDescriptor());
64 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Message in:\n"
65 << msg_in.DebugString() << std::endl;
67 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Try encode..." << std::endl;
69 codec.encode(&bytes, msg_in);
70 dccl::dlog.
is(dccl::logger::INFO) &&
71 dccl::dlog <<
"... got bytes (hex): " <<
dccl::hex_encode(bytes) << std::endl;
73 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Try decode..." << std::endl;
75 std::shared_ptr<google::protobuf::Message> msg_out(msg_in.New());
76 codec.decode(bytes, msg_out.get());
78 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"... got Message out:\n"
79 << msg_out->DebugString() << std::endl;
81 assert(msg_in.SerializeAsString() == msg_out->SerializeAsString());
93 run_test(model, msg_in);
97int main(
int argc,
char* argv[])
100 bool legacy_verbose =
false;
101 for (
int i = 1; i < argc; ++i)
103 if (argv[i] && argv[i][0] ==
'-' && argv[i][1] ==
'v' && argv[i][2] ==
'\0')
105 else if (argv[i] && std::string(argv[i]) ==
"1")
106 legacy_verbose =
true;
110 dccl::dlog.
connect(dccl::logger::ALL, &std::cerr);
111 else if (legacy_verbose)
112 dccl::dlog.
connect(dccl::logger::DEBUG3_PLUS, &std::cerr);
114 dccl::dlog.
connect(dccl::logger::WARN_PLUS, &std::cerr);
122 model.set_eof_frequency(4);
124 model.add_value_bound(0);
125 model.add_frequency(5);
127 model.add_value_bound(1);
128 model.add_frequency(1);
130 model.add_value_bound(2);
132 model.set_out_of_range_frequency(0);
134 ArithmeticDoubleTestMsg msg_in;
141 run_test(model, msg_in);
148 model.add_value_bound(100.0);
149 model.add_frequency(100);
151 model.add_value_bound(100.1);
152 model.add_frequency(100);
154 model.add_value_bound(100.2);
155 model.add_frequency(100);
157 model.add_value_bound(100.3);
158 model.add_frequency(100);
160 model.add_value_bound(100.4);
161 model.add_frequency(90);
163 model.add_value_bound(100.5);
164 model.add_frequency(125);
166 model.add_value_bound(100.6);
167 model.add_frequency(125);
169 model.add_value_bound(100.7);
170 model.add_frequency(125);
172 model.add_value_bound(100.8);
174 model.set_eof_frequency(25);
175 model.set_out_of_range_frequency(10);
177 ArithmeticDoubleTestMsg msg_in;
179 msg_in.add_value(100.5);
180 msg_in.add_value(100.7);
181 msg_in.add_value(100.2);
183 run_test(model, msg_in);
190 model.set_eof_frequency(10);
191 model.set_out_of_range_frequency(0);
193 model.add_value_bound(1);
194 model.add_frequency(2);
196 model.add_value_bound(2);
197 model.add_frequency(3);
199 model.add_value_bound(3);
200 model.add_frequency(85);
202 model.add_value_bound(4);
204 ArithmeticEnumTestMsg msg_in;
206 msg_in.add_value(ENUM_C);
207 msg_in.add_value(ENUM_C);
208 msg_in.add_value(ENUM_C);
209 msg_in.add_value(ENUM_C);
211 run_test(model, msg_in);
218 model.set_eof_frequency(10);
219 model.set_out_of_range_frequency(0);
221 model.add_value_bound(1);
222 model.add_frequency(2);
224 model.add_value_bound(2);
225 model.add_frequency(3);
227 model.add_value_bound(3);
228 model.add_frequency(85);
230 model.add_value_bound(4);
232 ArithmeticEnumTestMsg msg_in;
234 msg_in.add_value(ENUM_A);
235 msg_in.add_value(ENUM_A);
236 msg_in.add_value(ENUM_A);
237 msg_in.add_value(ENUM_A);
239 run_test(model, msg_in);
245 model.set_eof_frequency(10);
246 model.set_out_of_range_frequency(0);
248 model.add_value_bound(1);
249 model.add_frequency(2);
251 model.add_value_bound(2);
252 model.add_frequency(3);
254 model.add_value_bound(3);
255 model.add_frequency(85);
257 model.add_value_bound(4);
259 ArithmeticSingleEnumTestMsg msg_in;
261 msg_in.set_value(ENUM_B);
263 run_test(model, msg_in);
270 model.set_eof_frequency(1);
272 model.add_value_bound(0);
273 model.add_frequency(1);
275 model.add_value_bound(1);
276 model.add_frequency(1);
278 model.add_value_bound(2);
280 model.set_out_of_range_frequency(1);
282 ArithmeticDouble3TestMsg msg_in;
289 model.set_is_adaptive(
true);
290 run_test(model, msg_in);
291 run_test(model, msg_in,
false);
292 run_test(model, msg_in,
false);
293 run_test(model, msg_in,
false);
301 model.set_eof_frequency(0);
302 model.set_out_of_range_frequency(0);
304 model.add_value_bound(1);
305 model.add_frequency(2);
307 model.add_value_bound(2);
308 model.add_frequency(1);
310 model.add_value_bound(3);
311 model.add_frequency(3);
313 model.add_value_bound(4);
314 model.add_frequency(1);
316 model.add_value_bound(5);
317 model.add_frequency(1);
319 model.add_value_bound(6);
321 ArithmeticEnum2TestMsg msg_in;
323 msg_in.add_value(ENUM2_A);
324 msg_in.add_value(ENUM2_B);
325 msg_in.add_value(ENUM2_C);
326 msg_in.add_value(ENUM2_C);
327 msg_in.add_value(ENUM2_E);
328 msg_in.add_value(ENUM2_D);
329 msg_in.add_value(ENUM2_A);
330 msg_in.add_value(ENUM2_C);
332 run_test(model, msg_in);
337 srand(time(
nullptr));
338 for (
unsigned i = 0; i <= ArithmeticDouble2TestMsg::descriptor()
339 ->FindFieldByName(
"value")
341 .GetExtension(dccl::field)
348 dccl::int32 low = -(rand() % std::numeric_limits<dccl::int32>::max());
349 dccl::int32 high = rand() % std::numeric_limits<dccl::int32>::max();
351 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"low: " << low <<
", high: " << high
357 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"symbols: " << symbols << std::endl;
360 dccl::arith::Model::freq_type each_max_freq =
361 dccl::arith::Model::MAX_FREQUENCY / (symbols + 2);
363 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"each_max_freq: " << each_max_freq
366 model.set_eof_frequency(rand() % each_max_freq + 1);
367 model.set_out_of_range_frequency(rand() % each_max_freq + 1);
369 model.add_value_bound(low);
370 model.add_frequency(rand() % each_max_freq + 1);
371 for (
int j = 1; j < symbols; ++j)
375 dccl::int32 remaining_range = high - model.value_bound(j - 1);
376 model.add_value_bound(model.value_bound(j - 1) +
377 rand() % (remaining_range / symbols - j) + 1);
378 model.add_frequency(rand() % each_max_freq + 1);
381 model.add_value_bound(high);
383 ArithmeticDouble2TestMsg msg_in;
385 for (
unsigned j = 0; j < i; ++j) msg_in.add_value(model.value_bound(rand() % symbols));
387 run_test(model, msg_in);
389 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"end random test #" << i << std::endl;
397 model.set_name(
"model");
398 model.set_eof_frequency(10);
399 model.set_out_of_range_frequency(0);
400 model.add_value_bound(0);
401 model.add_frequency(10);
402 model.add_value_bound(1);
403 model.add_frequency(10);
404 model.add_value_bound(2);
406 run_scalar_type_test<ArithmeticInt64TestMsg>(model);
407 run_scalar_type_test<ArithmeticUInt32TestMsg>(model);
408 run_scalar_type_test<ArithmeticUInt64TestMsg>(model);
409 run_scalar_type_test<ArithmeticFloatTestMsg>(model);
410 run_scalar_type_test<ArithmeticBoolTestMsg>(model);
417 void* dl_handle = dlopen(DCCL_ARITHMETIC_NAME, RTLD_LAZY);
424 model.set_name(
"model");
425 model.set_eof_frequency(10);
426 model.set_out_of_range_frequency(0);
427 model.add_value_bound(1);
428 model.add_frequency(2);
429 model.add_value_bound(2);
430 model.add_frequency(3);
431 model.add_value_bound(3);
432 model.add_frequency(85);
433 model.add_value_bound(4);
434 dccl::arith::ModelManager::set_model(unload_codec, model);
436 ArithmeticEnumTestMsg msg;
437 msg.add_value(ENUM_A);
438 unload_codec.
load(msg.GetDescriptor());
441 unload_codec.
encode(&bytes, msg);
442 assert(!bytes.empty());
451 after_unload.
load(msg.GetDescriptor());
462 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"all tests passed" << std::endl;
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
void unload_library(void *dl_handle)
Remove codecs and/or unload messages present in the given shared library handle.
void encode(std::string *bytes, const google::protobuf::Message &msg, bool header_only=false, int user_id=-1)
Encodes a DCCL message.
void load_library(void *dl_handle)
Add codecs and/or load messages present in the given shared library handle.
std::size_t load()
All messages must be explicited loaded and validated (size checks, option extensions checks,...
Exception class for DCCL.
bool is(logger::Verbosity verbosity, logger::Group group=logger::GENERAL)
Indicates the verbosity of the Logger until the next std::flush or std::endl. The boolean return is u...
void connect(int verbosity_mask, Slot slot)
Connect the output of one or more given verbosities to a slot (function pointer or similar)
google::protobuf::int32 int32
a signed 32 bit integer
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...