29#include "../../binary.h"
30#include "../../codec.h"
35int main(
int argc,
char* argv[])
38 for (
int i = 1; i < argc; ++i)
40 if (argv[i] && argv[i][0] ==
'-' && argv[i][1] ==
'v' && argv[i][2] ==
'\0')
44 dccl::dlog.
connect(verbose ? dccl::logger::ALL :
dccl::logger::WARN_PLUS, &std::cerr);
52 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"=== Testing CRC-16 ===" << std::endl;
53 codec.load<TestCRC16>();
54 if (dccl::dlog.is(dccl::logger::INFO))
56 codec.info<TestCRC16>(&dccl::dlog);
59 TestCRC16 msg_in, msg_out;
64 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Message in:\n"
65 << msg_in.DebugString() << std::endl;
66 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Encoding..." << std::endl;
68 codec.encode(&bytes, msg_in);
69 dccl::dlog.
is(dccl::logger::INFO) &&
72 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Decoding..." << std::endl;
75 codec.decode(bytes, &msg_out);
77 catch (
const std::exception& e)
79 std::cerr <<
"UNEXPECTED exception during decode: " << e.what() << std::endl;
82 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Message out:\n"
83 << msg_out.DebugString() << std::endl;
85 assert(msg_out.x() == msg_in.x());
86 assert(msg_out.y() == msg_in.y());
87 assert(msg_out.crc() != 0);
90 assert(msg_out.crc() == msg_out.crc());
93 std::string corrupt_bytes = bytes;
94 corrupt_bytes[corrupt_bytes.size() - 1] ^= 0xFF;
97 TestCRC16 corrupt_out;
98 codec.decode(corrupt_bytes, &corrupt_out);
99 std::cerr <<
"ERROR: Corrupt message did not throw exception!" << std::endl;
102 catch (
const std::exception& e)
104 dccl::dlog.
is(dccl::logger::INFO) &&
105 dccl::dlog <<
"Caught expected exception for corrupt CRC-16: " << e.what()
109 codec.unload<TestCRC16>();
110 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"CRC-16 tests passed!" << std::endl;
117 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"\n=== Testing CRC-32 ===" << std::endl;
118 codec.load<TestCRC32>();
119 if (dccl::dlog.is(dccl::logger::INFO))
121 codec.info<TestCRC32>(&dccl::dlog);
124 TestCRC32 msg_in, msg_out;
129 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Message in:\n"
130 << msg_in.DebugString() << std::endl;
131 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Encoding..." << std::endl;
133 codec.encode(&bytes, msg_in);
134 dccl::dlog.
is(dccl::logger::INFO) &&
137 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Decoding..." << std::endl;
138 codec.decode(bytes, &msg_out);
139 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Message out:\n"
140 << msg_out.DebugString() << std::endl;
142 assert(msg_out.x() == msg_in.x());
143 assert(msg_out.y() == msg_in.y());
144 assert(msg_out.crc() != 0);
147 std::string corrupt_bytes = bytes;
148 corrupt_bytes[corrupt_bytes.size() - 1] ^= 0xFF;
151 TestCRC32 corrupt_out;
152 codec.decode(corrupt_bytes, &corrupt_out);
153 std::cerr <<
"ERROR: Corrupt message did not throw exception!" << std::endl;
156 catch (
const std::exception& e)
158 dccl::dlog.
is(dccl::logger::INFO) &&
159 dccl::dlog <<
"Caught expected exception for corrupt CRC-32: " << e.what()
163 codec.unload<TestCRC32>();
164 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"CRC-32 tests passed!" << std::endl;
171 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"\n=== Testing CRC-16 determinism ==="
173 codec.load<TestCRC16>();
180 std::string bytes1, bytes2;
181 codec.encode(&bytes1, msg);
182 codec.encode(&bytes2, msg);
183 assert(bytes1 == bytes2);
184 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"CRC is deterministic." << std::endl;
192 codec.encode(&bytes3, msg2);
193 assert(bytes3 != bytes1);
194 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"CRC differs for different data."
197 codec.unload<TestCRC16>();
198 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Determinism tests passed!" << std::endl;
205 dccl::dlog.
is(dccl::logger::INFO) &&
206 dccl::dlog <<
"\n=== Testing CRC-32 over all field types ===" << std::endl;
207 codec.load<TestCRCAllFields>();
210 for (
int all_set = 1; all_set >= 0; --all_set)
212 TestCRCAllFields msg_in, msg_out;
214 msg_in.mutable_em()->set_a(7);
219 msg_in.set_s(
"hello");
222 msg_in.mutable_em()->set_b(
"world");
223 msg_in.mutable_em_opt()->set_a(-7);
229 codec.encode(&bytes, msg_in);
230 dccl::dlog.
is(dccl::logger::INFO) &&
232 codec.decode(bytes, &msg_out);
233 assert(msg_out.crc() != 0);
235 assert(msg_out.DebugString() == msg_in.DebugString());
239 codec.encode(&head, msg_in,
true);
240 for (std::string::size_type i = head.size(); i < bytes.size(); ++i)
242 std::string corrupt_bytes = bytes;
243 corrupt_bytes[i] ^= 0x01;
244 if (corrupt_bytes == bytes)
249 TestCRCAllFields corrupt_out;
250 codec.decode(corrupt_bytes, &corrupt_out);
251 std::cerr <<
"ERROR: corrupt message (byte " << i <<
") did not throw!"
255 catch (
const std::exception& e)
257 dccl::dlog.
is(dccl::logger::INFO) &&
258 dccl::dlog <<
"Caught expected exception: " << e.what() << std::endl;
263 codec.unload<TestCRCAllFields>();
264 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"All field type tests passed!"
272 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"\n=== Testing CRC-32 over a oneof ==="
274 codec.load<TestCRCOneof>();
276 TestCRCOneof msg_in, msg_out;
281 codec.encode(&bytes, msg_in);
282 codec.decode(bytes, &msg_out);
283 assert(msg_out.y() == msg_in.y());
284 assert(!msg_out.has_x());
286 codec.unload<TestCRCOneof>();
287 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"Oneof tests passed!" << std::endl;
294 dccl::dlog.
is(dccl::logger::INFO) &&
295 dccl::dlog <<
"\n=== Testing CRC in an embedded message ===" << std::endl;
298 codec.load<TestCRCBadNested>();
299 std::cerr <<
"ERROR: CRC in an embedded message loaded!" << std::endl;
302 catch (
const std::exception& e)
304 dccl::dlog.
is(dccl::logger::INFO) &&
305 dccl::dlog <<
"Caught expected exception: " << e.what() << std::endl;
309 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"\nAll CRC tests passed!" << std::endl;
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode 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)
Dynamic Compact Control Language namespace.
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...