36#if CRYPTOPP_PATH_USES_PLUS_SIGN
37#include <crypto++/aes.h>
38#include <crypto++/filters.h>
39#include <crypto++/modes.h>
40#include <crypto++/sha.h>
42#include <cryptopp/aes.h>
43#include <cryptopp/filters.h>
44#include <cryptopp/modes.h>
45#include <cryptopp/sha.h>
49#include "codecs3/field_codec_var_bytes.h"
50#include "codecs4/field_codec_crc.h"
51#include "codecs4/field_codec_hash.h"
52#include "codecs4/field_codec_var_bytes.h"
53#include "codecs5/field_codec_hash.h"
54#include "codecs5/field_codec_var_bytes.h"
55#include "field_codec_id.h"
57#include "codecs2/default_field_codec_impl.h"
58#include "codecs3/default_field_codec_impl.h"
59#include "codecs4/default_field_codec_impl.h"
60#include "codecs5/default_field_codec_impl.h"
65using namespace dccl::logger;
67using google::protobuf::Descriptor;
68using google::protobuf::FieldDescriptor;
69using google::protobuf::Reflection;
76 : id_codec_(std::move(dccl_id_codec_name))
81 if (!library_path.empty())
89 for (
auto& dl_handle : dl_handles_)
91 unload_library(dl_handle);
96void dccl::Codec::set_default_codecs()
98 using google::protobuf::FieldDescriptor;
143void dccl::Codec::encode_internal(
const google::protobuf::Message& msg,
bool header_only,
146 const Descriptor* desc = msg.GetDescriptor();
148 dlog.
is(DEBUG1, ENCODE) && dlog <<
"Began encoding message of type: " << desc->full_name()
153 int32 dccl_id = id_internal(desc, user_id);
154 size_t head_byte_size = 0;
156 if (!msg.IsInitialized() && !header_only)
158 std::stringstream ss;
160 ss <<
"Message is not properly initialized. All `required` fields must be set. Fields "
162 << get_all_error_fields_in_message(msg);
167 if (!id2desc_.count(dccl_id))
168 throw(
Exception(
"Message id " + std::to_string(dccl_id) +
169 " has not been loaded. Call load() before encoding this type."),
172 std::shared_ptr<FieldCodecBase> codec = manager_.find(desc);
173 std::shared_ptr<internal::FromProtoCppTypeBase> helper = manager_.type_helper().find(desc);
178 if (!desc->options().GetExtension(dccl::msg).omit_id())
179 id_codec()->field_encode(&head_bits,
static_cast<uint32>(dccl_id),
nullptr);
182 manager_.codec_data().message_data_);
183 msg_stack.push(msg.GetDescriptor());
184 codec->base_encode(&head_bits, msg, HEAD, strict_);
187 head_byte_size = ceil_bits2bytes(head_bits.size());
188 head_bits.resize(head_byte_size * BITS_IN_BYTE);
192 dlog.
is(DEBUG2, ENCODE) &&
193 dlog <<
"as requested, skipping encoding and encrypting body." << std::endl;
197 codec->base_encode(&body_bits, msg, BODY, strict_);
201 const auto& msg_opt = desc->options().GetExtension(dccl::msg);
202 if (msg_opt.has_dynamic_conditions() &&
203 msg_opt.dynamic_conditions().has_max_bytes())
206 dc.set_descriptor(desc);
207 dc.regenerate(&msg, &msg);
208 const unsigned actual_size =
209 ceil_bits2bytes(head_bits.size()) + ceil_bits2bytes(body_bits.size());
210 const uint32_t allowed_max = dc.max_bytes();
211 if (actual_size > allowed_max)
213 "Encoded message size (" + std::to_string(actual_size) +
214 "B) exceeds dynamic max_bytes limit (" +
215 std::to_string(allowed_max) +
216 "B). Adjust message contents or increase the dynamic max_bytes limit.",
222 throw(
Exception(
"Failed to find (dccl.msg).codec `" +
223 desc->options().GetExtension(dccl::msg).codec() +
"`"),
229 dlog.
is(DEBUG1, ENCODE) &&
230 dlog <<
"Message " << desc->full_name()
231 <<
" failed to encode because a field was out of bounds and strict == true: "
232 << e.what() << std::endl;
235 catch (std::exception& e)
237 std::stringstream ss;
239 ss <<
"Message " << desc->full_name() <<
" failed to encode. Reason: " << e.what();
241 dlog.
is(DEBUG1, ENCODE) && dlog << ss.str() << std::endl;
247 bool header_only ,
int user_id )
249 const Descriptor* desc = msg.GetDescriptor();
252 encode_internal(msg, header_only, head_bits, body_bits, user_id);
254 size_t head_byte_size = ceil_bits2bytes(head_bits.size());
255 if (max_len < head_byte_size)
257 throw std::length_error(
"max_len must be >= head_byte_size");
261 dlog.
is(DEBUG2, ENCODE) && dlog <<
"Head bytes (bits): " << head_byte_size <<
"("
262 << head_bits.size() <<
")" << std::endl;
263 dlog.
is(DEBUG3, ENCODE) && dlog <<
"Unencrypted Head (bin): " << head_bits << std::endl;
264 dlog.
is(DEBUG3, ENCODE) && dlog <<
"Unencrypted Head (hex): "
265 <<
hex_encode(bytes, bytes + head_byte_size) << std::endl;
267 size_t body_byte_size = 0;
270 body_byte_size = ceil_bits2bytes(body_bits.size());
271 if (max_len < (head_byte_size + body_byte_size))
273 throw std::length_error(
"max_len must be >= (head_byte_size + body_byte_size)");
275 body_bits.
to_byte_string(bytes + head_byte_size, max_len - head_byte_size);
277 dlog.
is(DEBUG3, ENCODE) && dlog <<
"Unencrypted Body (bin): " << body_bits << std::endl;
278 dlog.
is(DEBUG3, ENCODE) &&
279 dlog <<
"Unencrypted Body (hex): "
280 <<
hex_encode(bytes + head_byte_size, bytes + head_byte_size + body_byte_size)
282 dlog.
is(DEBUG2, ENCODE) && dlog <<
"Body bytes (bits): " << body_byte_size <<
"("
283 << body_bits.size() <<
")" << std::endl;
285 int32 dccl_id = id_internal(desc, user_id);
286 if (!crypto_key_.empty() && !skip_crypto_ids_.count(dccl_id))
288 std::string head_bytes(bytes, bytes + head_byte_size);
289 std::string body_bytes(bytes + head_byte_size, bytes + head_byte_size + body_byte_size);
290 encrypt(&body_bytes, head_bytes);
291 std::memcpy(bytes + head_byte_size, body_bytes.data(), body_bytes.size());
294 dlog.
is(logger::DEBUG3, logger::ENCODE) &&
295 dlog <<
"Encrypted Body (hex): "
296 <<
hex_encode(bytes + head_byte_size, bytes + head_byte_size + body_byte_size)
300 dlog.
is(DEBUG1, ENCODE) && dlog <<
"Successfully encoded message of type: " << desc->full_name()
303 return head_byte_size + body_byte_size;
307 bool header_only ,
int user_id )
309 const Descriptor* desc = msg.GetDescriptor();
312 encode_internal(msg, header_only, head_bits, body_bits, user_id);
316 dlog.
is(DEBUG2, ENCODE) && dlog <<
"Head bytes (bits): " << head_bytes.size() <<
"("
317 << head_bits.size() <<
")" << std::endl;
318 dlog.
is(DEBUG3, ENCODE) && dlog <<
"Unencrypted Head (bin): " << head_bits << std::endl;
319 dlog.
is(DEBUG3, ENCODE) && dlog <<
"Unencrypted Head (hex): " <<
hex_encode(head_bytes)
322 std::string body_bytes;
327 dlog.
is(DEBUG3, ENCODE) && dlog <<
"Unencrypted Body (bin): " << body_bits << std::endl;
328 dlog.
is(DEBUG3, ENCODE) && dlog <<
"Unencrypted Body (hex): " <<
hex_encode(body_bytes)
330 dlog.
is(DEBUG2, ENCODE) && dlog <<
"Body bytes (bits): " << body_bytes.size() <<
"("
331 << body_bits.size() <<
")" << std::endl;
333 int32 dccl_id = id_internal(desc, user_id);
334 if (!crypto_key_.empty() && !skip_crypto_ids_.count(dccl_id))
335 encrypt(&body_bytes, head_bytes);
337 dlog.
is(logger::DEBUG3, logger::ENCODE) &&
338 dlog <<
"Encrypted Body (hex): " <<
hex_encode(body_bytes) << std::endl;
341 dlog.
is(DEBUG1, ENCODE) && dlog <<
"Successfully encoded message of type: " << desc->full_name()
343 *bytes += head_bytes + body_bytes;
354 const auto& msg_opt = desc->options().GetExtension(dccl::msg);
355 if (user_id < 0 && !msg_opt.has_id() && !msg_opt.omit_id())
357 Exception(
"Missing message option `(dccl.msg).id`. Specify a unique id (e.g. 3) in "
358 "the body of your .proto message using \"option (dccl.msg).id = 3\"",
360 if (!msg_opt.has_max_bytes())
361 throw(
Exception(
"Missing message option `(dccl.msg).max_bytes`. Specify a maximum "
362 "(encoded) message size in bytes (e.g. 32) in the body of your .proto "
363 "message using \"option (dccl.msg).max_bytes = 32\"",
366 if (!msg_opt.has_codec_version())
368 "No (dccl.msg).codec_version set for DCCL Message '" +
369 std::string(desc->full_name()) +
370 "'. For new messages, set 'option (dccl.msg).codec_version = 4' in the "
371 "message definition for " +
372 std::string(desc->full_name()) +
" to use the default DCCL4 codecs.",
375 std::shared_ptr<FieldCodecBase> codec = manager_.find(desc);
377 int32 dccl_id = id_internal(desc, user_id);
379 unsigned head_size_bits, body_size_bits;
380 codec->base_max_size(&head_size_bits, desc, HEAD);
381 codec->base_max_size(&body_size_bits, desc, BODY);
383 unsigned id_bits = 0;
384 if (!msg_opt.omit_id())
385 id_codec()->field_size(&id_bits,
static_cast<uint32>(dccl_id),
nullptr);
386 head_size_bits += id_bits;
388 const unsigned byte_size =
389 ceil_bits2bytes(head_size_bits) + ceil_bits2bytes(body_size_bits);
391 auto actual_max = byte_size;
392 auto allowed_max = msg_opt.max_bytes();
393 if (actual_max > allowed_max)
394 throw(
Exception(
"Actual maximum size of message (" + std::to_string(actual_max) +
395 "B) exceeds allowed maximum (" + std::to_string(allowed_max) +
397 "bounds, remove fields, improve codecs, or increase the allowed "
398 "value in (dccl.msg).max_bytes",
401 codec->base_validate(desc, HEAD);
402 codec->base_validate(desc, BODY);
404 if (id2desc_.count(dccl_id) && desc != id2desc_.find(dccl_id)->second)
406 std::stringstream ss;
407 ss <<
"`dccl id` " << dccl_id <<
" is already in use by Message "
408 << id2desc_.find(dccl_id)->second->full_name() <<
": "
409 << id2desc_.find(dccl_id)->second;
415 id2desc_.emplace(dccl_id, desc);
418 dlog.
is(DEBUG1) && dlog <<
"Successfully validated message of type: " << desc->full_name()
421 std::size_t hash_value = 0;
422 codec->base_hash(&hash_value, desc, HEAD);
423 codec->base_hash(&hash_value, desc, BODY);
424 manager_.set_hash(desc, hash_value);
437 dlog.
is(DEBUG1) && dlog <<
"Message " << desc->full_name() <<
": " << desc
438 <<
" failed validation. Reason: " << e.what() <<
"\n"
439 <<
"If possible, information about the Message are printed above. "
448 unsigned int erased = 0;
449 for (
auto it = id2desc_.begin(); it != id2desc_.end();)
451 if (it->second == desc)
454 id2desc_.erase(it++);
463 dlog.
is(DEBUG1) && dlog <<
"Message " << desc->full_name()
464 <<
": is not loaded. Ignoring unload request." << std::endl;
470 if (id2desc_.count(dccl_id))
472 id2desc_.erase(dccl_id);
476 dlog.
is(DEBUG1) && dlog <<
"Message with id " << dccl_id
477 <<
": is not loaded. Ignoring unload request." << std::endl;
484 const Descriptor* desc = msg.GetDescriptor();
486 std::shared_ptr<FieldCodecBase> codec = manager_.find(desc);
488 int32 dccl_id = id_internal(desc, user_id);
489 unsigned head_size_bits;
490 codec->base_size(&head_size_bits, msg, HEAD);
492 unsigned id_bits = 0;
493 if (!desc->options().GetExtension(dccl::msg).omit_id())
494 id_codec()->field_size(&id_bits,
static_cast<uint32>(dccl_id),
nullptr);
495 head_size_bits += id_bits;
497 unsigned body_size_bits;
498 codec->base_size(&body_size_bits, msg, BODY);
500 const unsigned head_size_bytes = ceil_bits2bytes(head_size_bits);
501 const unsigned body_size_bytes = ceil_bits2bytes(body_size_bits);
502 return head_size_bytes + body_size_bytes;
507 std::shared_ptr<FieldCodecBase> codec = manager_.find(desc);
509 unsigned head_size_bits;
510 codec->base_max_size(&head_size_bits, desc, HEAD);
512 int32 dccl_id = id_internal_const(desc, user_id);
514 unsigned id_bits = 0;
515 if (!desc->options().GetExtension(dccl::msg).omit_id())
516 id_codec()->field_size(&id_bits,
static_cast<uint32>(dccl_id),
nullptr);
517 head_size_bits += id_bits;
519 unsigned body_size_bits;
520 codec->base_max_size(&body_size_bits, desc, BODY);
522 const unsigned head_size_bytes = ceil_bits2bytes(head_size_bits);
523 const unsigned body_size_bytes = ceil_bits2bytes(body_size_bits);
524 return head_size_bytes + body_size_bytes;
529 std::shared_ptr<FieldCodecBase> codec = manager_.find(desc);
531 unsigned head_size_bits;
532 codec->base_min_size(&head_size_bits, desc, HEAD);
534 int32 dccl_id = id_internal_const(desc, user_id);
536 unsigned id_bits = 0;
537 if (!desc->options().GetExtension(dccl::msg).omit_id())
538 id_codec()->field_size(&id_bits,
static_cast<uint32>(dccl_id),
nullptr);
539 head_size_bits += id_bits;
541 unsigned body_size_bits;
542 codec->base_min_size(&body_size_bits, desc, BODY);
544 const unsigned head_size_bytes = ceil_bits2bytes(head_size_bits);
545 const unsigned body_size_bytes = ceil_bits2bytes(body_size_bits);
546 return head_size_bytes + body_size_bytes;
552 bool is_dlog =
false;
553 if (!param_os || param_os == &dlog)
555 std::stringstream ss;
556 std::ostream* os = (is_dlog) ? &ss : param_os;
558 if (!is_dlog || dlog.
check(INFO))
562 bool omit_id = desc->options().GetExtension(dccl::msg).omit_id();
564 std::shared_ptr<FieldCodecBase> codec = manager_.find(desc);
566 unsigned config_head_bit_size, body_bit_size;
567 codec->base_max_size(&config_head_bit_size, desc, HEAD);
568 codec->base_max_size(&body_bit_size, desc, BODY);
570 int32 dccl_id = id_internal_const(desc, user_id);
571 unsigned id_bit_size = 0;
573 id_codec()->field_size(&id_bit_size,
static_cast<uint32>(dccl_id),
nullptr);
575 const unsigned bit_size = id_bit_size + config_head_bit_size + body_bit_size;
577 const unsigned byte_size = ceil_bits2bytes(config_head_bit_size + id_bit_size) +
578 ceil_bits2bytes(body_bit_size);
580 const unsigned allowed_byte_size = desc->options().GetExtension(dccl::msg).max_bytes();
581 const unsigned allowed_bit_size = allowed_byte_size * BITS_IN_BYTE;
584 if (manager_.has_hash(desc))
585 hash = hash_as_string(manager_.hash(desc));
587 std::string message_name;
589 message_name += std::to_string(dccl_id) +
": ";
590 message_name += std::string(desc->full_name()) +
" {" + hash +
"}";
591 std::string guard = build_guard_for_console_output(message_name,
'=');
592 std::string bits_dccl_head_str =
"dccl.id head";
593 std::string bits_user_head_str =
"user head";
594 std::string bits_body_str =
"body";
595 std::string bits_padding_str =
"padding to full byte";
597 const int bits_width = 40;
598 const int spaces = 8;
599 std::string indent = std::string(spaces,
' ');
601 *os << guard <<
" " << message_name <<
" " << guard <<
"\n"
602 <<
"Actual maximum size of message: " << byte_size <<
" bytes / "
603 << byte_size * BITS_IN_BYTE <<
" bits\n"
604 << indent << bits_dccl_head_str << std::setfill(
'.')
605 << std::setw(bits_width - bits_dccl_head_str.size()) << id_bit_size <<
"\n"
606 << indent << bits_user_head_str << std::setfill(
'.')
607 << std::setw(bits_width - bits_user_head_str.size()) << config_head_bit_size <<
"\n"
608 << indent << bits_body_str << std::setfill(
'.')
609 << std::setw(bits_width - bits_body_str.size()) << body_bit_size <<
"\n"
610 << indent << bits_padding_str << std::setfill(
'.')
611 << std::setw(bits_width - bits_padding_str.size())
612 << byte_size * BITS_IN_BYTE - bit_size <<
"\n"
613 <<
"Allowed maximum size of message: " << allowed_byte_size <<
" bytes / "
614 << allowed_bit_size <<
" bits\n";
616 std::string header_str =
"Header";
617 std::string header_guard = build_guard_for_console_output(header_str,
'-');
619 *os << header_guard <<
" " << header_str <<
" " << header_guard <<
"\n";
620 *os << bits_dccl_head_str << std::setfill(
'.')
621 << std::setw(bits_width - bits_dccl_head_str.size() + spaces) << id_bit_size <<
" {"
622 << (omit_id ? std::string(
"omit_id: true") : id_codec()->name()) <<
"}\n";
623 codec->base_info(os, desc, HEAD);
626 std::string body_str =
"Body";
627 std::string body_guard = build_guard_for_console_output(body_str,
'-');
629 *os << body_guard <<
" " << body_str <<
" " << body_guard <<
"\n";
630 codec->base_info(os, desc, BODY);
637 dlog.
is(INFO) && dlog << ss.str() << std::endl;
642 dlog <<
"Message " << desc->full_name()
643 <<
" cannot provide information due to invalid configuration. Reason: "
644 << e.what() << std::endl;
649void dccl::Codec::encrypt(std::string* s,
const std::string& nonce )
652 using namespace CryptoPP;
656 StringSource unused(nonce,
true,
new HashFilter(hash,
new StringSink(iv)));
658 CTR_Mode<AES>::Encryption encryptor;
659 encryptor.SetKeyWithIV((
byte*)crypto_key_.c_str(), crypto_key_.size(), (
byte*)iv.c_str());
662 StreamTransformationFilter in(encryptor,
new StringSink(cipher));
663 in.Put((
byte*)s->c_str(), s->size());
669void dccl::Codec::decrypt(std::string* s,
const std::string& nonce)
672 using namespace CryptoPP;
676 StringSource unused(nonce,
true,
new HashFilter(hash,
new StringSink(iv)));
678 CTR_Mode<AES>::Decryption decryptor;
679 decryptor.SetKeyWithIV((
byte*)crypto_key_.c_str(), crypto_key_.size(), (
byte*)iv.c_str());
681 std::string recovered;
683 StreamTransformationFilter out(decryptor,
new StringSink(recovered));
684 out.Put((
byte*)s->c_str(), s->size());
692 void* handle = dlopen(library_path.c_str(), RTLD_LAZY);
694 dl_handles_.push_back(handle);
695 load_library(handle);
701 throw(
Exception(
"Null shared library handle passed to load_library"));
705 dccl_load_ptr = (void (*)(
dccl::Codec*))dlsym(dl_handle,
"dccl3_load");
707 (*dccl_load_ptr)(
this);
713 throw(
Exception(
"Null shared library handle passed to unload_library"));
717 dccl_unload_ptr = (void (*)(
dccl::Codec*))dlsym(dl_handle,
"dccl3_unload");
719 (*dccl_unload_ptr)(
this);
723 const std::string& passphrase,
724 const std::set<int32>& do_not_encrypt_ids )
726 if (!crypto_key_.empty())
728 skip_crypto_ids_.clear();
731 using namespace CryptoPP;
734 StringSource unused(passphrase,
true,
new HashFilter(hash,
new StringSink(crypto_key_)));
736 dlog.
is(DEBUG1) && dlog <<
"Cryptography enabled with given passphrase" << std::endl;
738 dlog.
is(DEBUG1) && dlog <<
"Cryptography disabled because DCCL was compiled without support of "
739 "Crypto++. Install Crypto++ and recompile to enable cryptography."
743 skip_crypto_ids_ = do_not_encrypt_ids;
748 bool is_dlog =
false;
749 if (!param_os || param_os == &dlog)
751 std::stringstream ss;
752 std::ostream* os = (is_dlog) ? &ss : param_os;
753 if (!is_dlog || dlog.
check(INFO))
755 std::string codec_str =
"Dynamic Compact Control Language (DCCL) Codec";
756 std::string codec_guard = build_guard_for_console_output(codec_str,
'|');
758 *os << codec_guard <<
" " << codec_str <<
" " << codec_guard <<
"\n";
759 *os << id2desc_.size() <<
" messages loaded.\n";
760 *os <<
"Field sizes are in bits unless otherwise noted." <<
"\n";
762 for (
auto it : id2desc_) info(it.second, os, it.first);
766 dlog.
is(INFO) && dlog << ss.str() << std::endl;
775 id_codec_ = id_codec_name;
780std::string dccl::Codec::build_guard_for_console_output(std::string& base,
char guard_char)
const
783 return (base.size() < console_width_)
784 ? std::string((console_width_ - base.size()) / 2, guard_char)
788std::string dccl::Codec::get_all_error_fields_in_message(
const google::protobuf::Message& message,
796 std::stringstream output_stream;
798 const google::protobuf::Descriptor* descriptor = message.GetDescriptor();
799 const google::protobuf::Reflection* reflection = message.GetReflection();
800 const uint8_t depth_spacing = 4;
803 const int32_t field_count = descriptor->field_count();
805 for (int32_t index = 0; index < field_count; ++index)
807 if (descriptor->field(index)->is_required())
809 if (!reflection->HasField(message, descriptor->field(index)))
811 output_stream << std::string(depth * depth_spacing,
' ')
812 << descriptor->field(index)->number() <<
": "
813 << descriptor->field(index)->name() <<
"\n";
819 std::vector<const google::protobuf::FieldDescriptor*> fields;
820 reflection->ListFields(message, &fields);
822 for (
const google::protobuf::FieldDescriptor* field : fields)
824 if (field->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
826 output_stream << std::string(depth * depth_spacing,
' ') << field->number() <<
": "
827 << field->name() <<
"\n";
829 if (field->is_repeated())
831 int32_t size = reflection->FieldSize(message, field);
833 for (int32_t index = 0; index < size; ++index)
835 const google::protobuf::Message& sub_message =
836 reflection->GetRepeatedMessage(message, field, index);
838 output_stream << std::string((depth + 1) * depth_spacing,
' ') <<
"[" << index
841 output_stream << get_all_error_fields_in_message(sub_message, depth + 2);
846 const google::protobuf::Message& sub_message =
847 reflection->GetMessage(message, field);
848 output_stream << get_all_error_fields_in_message(sub_message, depth + 1);
853 return output_stream.str();
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
std::string to_byte_string()
Returns the value of the Bitset to a byte string, where each character represents 8 bits of the Bitse...
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
void info(std::ostream *os=nullptr, int user_id=-1) const
Writes a human readable summary (including field sizes) of the provided DCCL type to the stream provi...
void info_all(std::ostream *os=nullptr) const
Writes a human readable summary (including field sizes) of all the loaded (validated) DCCL types.
void set_id_codec(const std::string &id_codec_name)
Set a different ID codec name (note that is calls unload_all() so all messages must be reloaded)
unsigned min_size()
Provides the encoded minimum size (in bytes) of msg.
Codec(std::string dccl_id_codec_name=default_id_codec_name(), const std::string &library_path="")
Instantiate a Codec, optionally with a non-default identifier field codec (loaded via a shared librar...
int32 id() const
Gives the DCCL id (defined by the custom message option extension "(dccl.msg).id" in the ....
void unload_library(void *dl_handle)
Remove codecs and/or unload messages present in the given shared library handle.
unsigned max_size()
Provides the encoded maximum size (in bytes) of msg.
void encode(std::string *bytes, const google::protobuf::Message &msg, bool header_only=false, int user_id=-1)
Encodes a DCCL message.
void unload()
Unload a given message.
void set_crypto_passphrase(const std::string &passphrase, const std::set< int32 > &do_not_encrypt_ids=std::set< int32 >())
Set a passphrase to be used when encoded messages to encrypt them and to decrypt messages after decod...
virtual ~Codec()
Destructor.
void load_library(void *dl_handle)
Add codecs and/or load messages present in the given shared library handle.
unsigned size(const google::protobuf::Message &msg, int user_id=-1)
Provides the encoded size (in bytes) of msg. This is useful if you need to know the size of a message...
std::size_t load()
All messages must be explicited loaded and validated (size checks, option extensions checks,...
Provides the default 1 byte or 2 byte DCCL ID codec.
Exception class for DCCL.
std::enable_if< std::is_base_of< google::protobuf::Message, typenameCodec::wire_type >::value &&!std::is_same< google::protobuf::Message, typenameCodec::wire_type >::value, void >::type add(const std::string &name)
Add a new field codec (used for codecs operating on statically generated Protobuf messages,...
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...
bool check(logger::Verbosity verbosity)
Same as is() but doesn't set the verbosity or lock the mutex.
Dynamic Compact Control Language namespace.
google::protobuf::int32 int32
a signed 32 bit integer
google::protobuf::uint32 uint32
an unsigned 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...