26 #include "dccl/codec.h" 
   29 #if CRYPTOPP_PATH_USES_PLUS_SIGN 
   30 #include <crypto++/filters.h> 
   31 #include <crypto++/sha.h> 
   32 #include <crypto++/modes.h> 
   33 #include <crypto++/aes.h> 
   35 #include <cryptopp/filters.h> 
   36 #include <cryptopp/sha.h> 
   37 #include <cryptopp/modes.h> 
   38 #include <cryptopp/aes.h> 
   39 #endif // CRYPTOPP_PATH_USES_PLUS_SIGN 
   40 #endif // HAS_CRYPTOPP 
   42 #include "dccl/codecs2/field_codec_default.h" 
   43 #include "dccl/codecs3/field_codec_default.h" 
   44 #include "dccl/codecs3/field_codec_var_bytes.h" 
   45 #include "dccl/codecs3/field_codec_presence.h" 
   46 #include "dccl/field_codec_id.h" 
   48 #include "dccl/option_extensions.pb.h" 
   55 using namespace dccl::logger;
 
   57 using google::protobuf::FieldDescriptor;
 
   58 using google::protobuf::Descriptor;
 
   59 using google::protobuf::Reflection;
 
   61 const unsigned full_width = 60;
 
   69     : strict_(false), id_codec_(dccl_id_codec)
 
   72     FieldCodecManager::add<DefaultIdentifierCodec>(default_id_codec_name());
 
   74     if(!library_path.empty())
 
   82     for(std::vector<void *>::iterator it = dl_handles_.begin(),
 
   83             n = dl_handles_.end(); it != n; ++it)
 
   91 void dccl::Codec::set_default_codecs()
 
   94     static bool defaults_loaded = 
false;
 
   98         using google::protobuf::FieldDescriptor;
 
  101         FieldCodecManager::add<v2::DefaultNumericFieldCodec<double> >(default_codec_name());
 
  102         FieldCodecManager::add<v2::DefaultNumericFieldCodec<float> >(default_codec_name());
 
  103         FieldCodecManager::add<v2::DefaultBoolCodec>(default_codec_name());
 
  104         FieldCodecManager::add<v2::DefaultNumericFieldCodec<int32> >(default_codec_name());
 
  105         FieldCodecManager::add<v2::DefaultNumericFieldCodec<int64> >(default_codec_name());
 
  106         FieldCodecManager::add<v2::DefaultNumericFieldCodec<uint32> >(default_codec_name());
 
  107         FieldCodecManager::add<v2::DefaultNumericFieldCodec<uint64> >(default_codec_name());
 
  108         FieldCodecManager::add<v2::DefaultStringCodec, FieldDescriptor::TYPE_STRING>(default_codec_name());
 
  109         FieldCodecManager::add<v2::DefaultBytesCodec, FieldDescriptor::TYPE_BYTES>(default_codec_name());
 
  110         FieldCodecManager::add<v2::DefaultEnumCodec >(default_codec_name());
 
  111         FieldCodecManager::add<v2::DefaultMessageCodec, FieldDescriptor::TYPE_MESSAGE>(default_codec_name());
 
  113         FieldCodecManager::add<v2::TimeCodec<uint64> >(
"dccl.time2");
 
  114         FieldCodecManager::add<v2::TimeCodec<int64> >(
"dccl.time2");
 
  115         FieldCodecManager::add<v2::TimeCodec<double> >(
"dccl.time2");
 
  117         FieldCodecManager::add<v2::StaticCodec<std::string> >(
"dccl.static2");
 
  118         FieldCodecManager::add<v2::StaticCodec<double> >(
"dccl.static2");
 
  119         FieldCodecManager::add<v2::StaticCodec<float> >(
"dccl.static2");
 
  120         FieldCodecManager::add<v2::StaticCodec<int32> >(
"dccl.static2");
 
  121         FieldCodecManager::add<v2::StaticCodec<int64> >(
"dccl.static2");
 
  122         FieldCodecManager::add<v2::StaticCodec<uint32> >(
"dccl.static2");
 
  123         FieldCodecManager::add<v2::StaticCodec<uint64> >(
"dccl.static2");
 
  126         FieldCodecManager::add<v3::DefaultNumericFieldCodec<double> >(default_codec_name(3));
 
  127         FieldCodecManager::add<v3::DefaultNumericFieldCodec<float> >(default_codec_name(3));
 
  128         FieldCodecManager::add<v3::DefaultBoolCodec>(default_codec_name(3));
 
  129         FieldCodecManager::add<v3::DefaultNumericFieldCodec<int32> >(default_codec_name(3));
 
  130         FieldCodecManager::add<v3::DefaultNumericFieldCodec<int64> >(default_codec_name(3));
 
  131         FieldCodecManager::add<v3::DefaultNumericFieldCodec<uint32> >(default_codec_name(3));
 
  132         FieldCodecManager::add<v3::DefaultNumericFieldCodec<uint64> >(default_codec_name(3));
 
  133         FieldCodecManager::add<v3::DefaultStringCodec, FieldDescriptor::TYPE_STRING>(default_codec_name(3));
 
  134         FieldCodecManager::add<v3::DefaultBytesCodec, FieldDescriptor::TYPE_BYTES>(default_codec_name(3));
 
  135         FieldCodecManager::add<v3::DefaultEnumCodec >(default_codec_name(3));
 
  136         FieldCodecManager::add<v3::DefaultMessageCodec, FieldDescriptor::TYPE_MESSAGE>(default_codec_name(3));
 
  139         FieldCodecManager::add<v3::PresenceBitCodec<v3::DefaultNumericFieldCodec<double> > >(
"dccl.presence");
 
  140         FieldCodecManager::add<v3::PresenceBitCodec<v3::DefaultNumericFieldCodec<float> > >(
"dccl.presence");
 
  141         FieldCodecManager::add<v3::PresenceBitCodec<v3::DefaultNumericFieldCodec<int32> > >(
"dccl.presence");
 
  142         FieldCodecManager::add<v3::PresenceBitCodec<v3::DefaultNumericFieldCodec<int64> > >(
"dccl.presence");
 
  143         FieldCodecManager::add<v3::PresenceBitCodec<v3::DefaultNumericFieldCodec<uint32> > >(
"dccl.presence");
 
  144         FieldCodecManager::add<v3::PresenceBitCodec<v3::DefaultNumericFieldCodec<uint64> > >(
"dccl.presence");
 
  145         FieldCodecManager::add<v3::PresenceBitCodec<v3::DefaultEnumCodec > >(
"dccl.presence");
 
  148         FieldCodecManager::add<v3::VarBytesCodec, FieldDescriptor::TYPE_BYTES>(
"dccl.var_bytes");
 
  151         FieldCodecManager::add<v2::TimeCodec<uint64> >(
"_time");
 
  152         FieldCodecManager::add<v2::TimeCodec<int64> >(
"_time");
 
  153         FieldCodecManager::add<v2::TimeCodec<double> >(
"_time");
 
  155         FieldCodecManager::add<v2::StaticCodec<std::string> >(
"_static");
 
  156         FieldCodecManager::add<v2::StaticCodec<double> >(
"_static");
 
  157         FieldCodecManager::add<v2::StaticCodec<float> >(
"_static");
 
  158         FieldCodecManager::add<v2::StaticCodec<int32> >(
"_static");
 
  159         FieldCodecManager::add<v2::StaticCodec<int64> >(
"_static");
 
  160         FieldCodecManager::add<v2::StaticCodec<uint32> >(
"_static");
 
  161         FieldCodecManager::add<v2::StaticCodec<uint64> >(
"_static");
 
  164         defaults_loaded = 
true;
 
  170     const Descriptor* desc = msg.GetDescriptor();
 
  172     dlog.
is(DEBUG1, ENCODE) && dlog << 
"Began encoding message of type: " << desc->full_name() << std::endl;
 
  176         unsigned dccl_id = (user_id < 0) ? 
id(desc) : user_id;
 
  177         size_t head_byte_size = 0;
 
  179         if(!msg.IsInitialized() && !header_only)
 
  180             throw(
Exception(
"Message is not properly initialized. All `required` fields must be set."));
 
  182         if(!id2desc_.count(dccl_id))
 
  183             throw(
Exception(
"Message id " + boost::lexical_cast<std::string>(dccl_id) + 
" has not been loaded. Call load() before encoding this type."));
 
  188         boost::shared_ptr<internal::FromProtoCppTypeBase> helper = internal::TypeHelper::find(desc);
 
  193             id_codec()->field_encode(&head_bits, dccl_id, 0);
 
  196             msg_stack.push(msg.GetDescriptor());
 
  197             codec->base_encode(&head_bits, msg, HEAD, strict_);
 
  200             head_byte_size = ceil_bits2bytes(head_bits.size());
 
  201             head_bits.resize(head_byte_size * BITS_IN_BYTE);
 
  205                 dlog.
is(DEBUG2, ENCODE) && dlog << 
"as requested, skipping encoding and encrypting body." << std::endl;
 
  209                 codec->base_encode(&body_bits, msg, BODY, strict_);
 
  214             throw(
Exception(
"Failed to find (dccl.msg).codec `" + desc->options().GetExtension(dccl::msg).codec() + 
"`"));
 
  220         dlog.
is(DEBUG1, ENCODE) && dlog << 
"Message " << desc->full_name() << 
" failed to encode because a field was out of bounds and strict == true: " << e.what() << std::endl;
 
  223     catch(std::exception& e)
 
  225         std::stringstream ss;
 
  227         ss << 
"Message " << desc->full_name() << 
" failed to encode. Reason: " << e.what();
 
  229         dlog.
is(DEBUG1, ENCODE) && dlog << ss.str() << std::endl;
 
  236     const Descriptor* desc = msg.GetDescriptor();
 
  239     encode_internal(msg, header_only, head_bits, body_bits, user_id);
 
  241     size_t head_byte_size = ceil_bits2bytes(head_bits.size());
 
  242     if (max_len < head_byte_size)
 
  244         throw std::length_error(
"max_len must be >= head_byte_size");
 
  248     dlog.
is(DEBUG2, ENCODE) && dlog << 
"Head bytes (bits): " << head_byte_size << 
"(" << head_bits.size() << 
")" << std::endl;
 
  249     dlog.
is(DEBUG3, ENCODE) && dlog << 
"Unencrypted Head (bin): " << head_bits << std::endl;
 
  250     dlog.
is(DEBUG3, ENCODE) && dlog << 
"Unencrypted Head (hex): " << 
hex_encode(bytes, bytes+head_byte_size) << std::endl;
 
  252     size_t body_byte_size = 0;
 
  255         body_byte_size = ceil_bits2bytes(body_bits.size());
 
  256         if (max_len < (head_byte_size + body_byte_size))
 
  258             throw std::length_error(
"max_len must be >= (head_byte_size + body_byte_size)");
 
  260         body_bits.
to_byte_string(bytes+head_byte_size, max_len-head_byte_size);
 
  262         dlog.
is(DEBUG3, ENCODE) && dlog << 
"Unencrypted Body (bin): " << body_bits << std::endl;
 
  263         dlog.
is(DEBUG3, ENCODE) && dlog << 
"Unencrypted Body (hex): " << 
hex_encode(bytes+head_byte_size, bytes+head_byte_size+body_byte_size) << std::endl;
 
  264         dlog.
is(DEBUG2, ENCODE) && dlog << 
"Body bytes (bits): " <<  body_byte_size << 
"(" << body_bits.size() << 
")" <<  std::endl;
 
  266         unsigned dccl_id = (user_id < 0) ? 
id(desc) : user_id;
 
  267         if(!crypto_key_.empty() && !skip_crypto_ids_.count(dccl_id)) {
 
  268             std::string head_bytes(bytes, bytes+head_byte_size);
 
  269             std::string body_bytes(bytes+head_byte_size, bytes+head_byte_size+body_byte_size);
 
  270             encrypt(&body_bytes, head_bytes);
 
  271             std::memcpy(bytes+head_byte_size, body_bytes.data(), body_bytes.size());
 
  274         dlog.
is(logger::DEBUG3, logger::ENCODE) && dlog << 
"Encrypted Body (hex): " << 
hex_encode(bytes+head_byte_size, bytes+head_byte_size+body_byte_size) << std::endl;
 
  277     dlog.
is(DEBUG1, ENCODE) && dlog << 
"Successfully encoded message of type: " << desc->full_name() << std::endl;
 
  279     return head_byte_size + body_byte_size;
 
  285     const Descriptor* desc = msg.GetDescriptor();
 
  288     encode_internal(msg, header_only, head_bits, body_bits, user_id);
 
  292     dlog.
is(DEBUG2, ENCODE) && dlog << 
"Head bytes (bits): " << head_bytes.size() << 
"(" << head_bits.size() << 
")" << std::endl;
 
  293     dlog.
is(DEBUG3, ENCODE) && dlog << 
"Unencrypted Head (bin): " << head_bits << std::endl;
 
  294     dlog.
is(DEBUG3, ENCODE) && dlog << 
"Unencrypted Head (hex): " << 
hex_encode(head_bytes) << std::endl;
 
  296     std::string body_bytes;
 
  301         dlog.
is(DEBUG3, ENCODE) && dlog << 
"Unencrypted Body (bin): " << body_bits << std::endl;
 
  302         dlog.
is(DEBUG3, ENCODE) && dlog << 
"Unencrypted Body (hex): " << 
hex_encode(body_bytes) << std::endl;
 
  303         dlog.
is(DEBUG2, ENCODE) && dlog << 
"Body bytes (bits): " <<  body_bytes.size() << 
"(" << body_bits.size() << 
")" <<  std::endl;
 
  305         unsigned dccl_id = (user_id < 0) ? 
id(desc) : user_id;
 
  306         if(!crypto_key_.empty() && !skip_crypto_ids_.count(dccl_id))
 
  307             encrypt(&body_bytes, head_bytes);
 
  309         dlog.
is(logger::DEBUG3, logger::ENCODE) && dlog << 
"Encrypted Body (hex): " << 
hex_encode(body_bytes) << std::endl;
 
  312     dlog.
is(DEBUG1, ENCODE) && dlog << 
"Successfully encoded message of type: " << desc->full_name() << std::endl;
 
  313     *bytes += head_bytes + body_bytes;
 
  318     return id(bytes.begin(), bytes.end());
 
  325     unsigned last_size = size(*msg);
 
  326     bytes->erase(0, last_size);
 
  331     decode(bytes.begin(), bytes.end(), msg, header_only);
 
  340         if(user_id <0 && !desc->options().GetExtension(dccl::msg).has_id())
 
  341             throw(
Exception(
"Missing message option `(dccl.msg).id`. Specify a unique id (e.g. 3) in the body of your .proto message using \"option (dccl.msg).id = 3\""));
 
  342         if(!desc->options().GetExtension(dccl::msg).has_max_bytes())
 
  343             throw(
Exception(
"Missing message option `(dccl.msg).max_bytes`. Specify a maximum (encoded) message size in bytes (e.g. 32) in the body of your .proto message using \"option (dccl.msg).max_bytes = 32\""));
 
  345         if(!desc->options().GetExtension(dccl::msg).has_codec_version())
 
  346             dlog.
is(WARN) && dlog << 
"** NOTE: No (dccl.msg).codec_version set for DCCL Message '" << desc->full_name() <<  
"'. Unless you need backwards compatibility with Goby 2.0 (DCCL2), we highly recommend setting 'option (dccl.msg).codec_version = 3' in the message definition for " << desc->full_name() << 
" to use the default DCCL3 codecs. If you need compatibility with Goby 2.0, ignore this warning, or set 'option (dccl.msg).codec_version = 2' to remove this warning. **" << std::endl;
 
  350         unsigned dccl_id = (user_id < 0) ? 
id(desc) : user_id;
 
  351         unsigned head_size_bits, body_size_bits;
 
  352         codec->base_max_size(&head_size_bits, desc, HEAD);
 
  353         codec->base_max_size(&body_size_bits, desc, BODY);
 
  355         unsigned id_bits = 0;
 
  356         id_codec()->field_size(&id_bits, dccl_id, 0);
 
  357         head_size_bits += id_bits;
 
  359         const unsigned byte_size = ceil_bits2bytes(head_size_bits) + ceil_bits2bytes(body_size_bits);
 
  361         if(byte_size > desc->options().GetExtension(dccl::msg).max_bytes())
 
  362             throw(
Exception(
"Actual maximum size of message exceeds allowed maximum (dccl.max_bytes). Tighten bounds, remove fields, improve codecs, or increase the allowed dccl.max_bytes"));
 
  364         codec->base_validate(desc, HEAD);
 
  365         codec->base_validate(desc, BODY);
 
  367         if(id2desc_.count(dccl_id) && desc != id2desc_.find(dccl_id)->second)
 
  368             throw(
Exception(
"`dccl id` " + boost::lexical_cast<std::string>(dccl_id) + 
" is already in use by Message " + id2desc_.find(dccl_id)->second->full_name() + 
": " + boost::lexical_cast<std::string>(id2desc_.find(dccl_id)->second)));
 
  370             id2desc_.insert(std::make_pair(dccl_id, desc));
 
  372         dlog.
is(DEBUG1) && dlog << 
"Successfully validated message of type: " << desc->full_name() << std::endl;
 
  384         dlog.
is(DEBUG1) && dlog << 
"Message " << desc->full_name() << 
": " << desc << 
" failed validation. Reason: " 
  386                                 << 
"If possible, information about the Message are printed above. " << std::endl;
 
  395     unsigned int erased = 0;
 
  396     for (std::map<int32, const google::protobuf::Descriptor*>::iterator it = id2desc_.begin(); it != id2desc_.end();)
 
  398         if (it->second == desc)
 
  401             id2desc_.erase(it++);
 
  410         dlog.
is(DEBUG1) && dlog << 
"Message " << desc->full_name() << 
": is not loaded. Ignoring unload request." << std::endl;
 
  417     if(id2desc_.count(dccl_id))
 
  419         id2desc_.erase(dccl_id);
 
  423         dlog.
is(DEBUG1) && dlog << 
"Message with id " << dccl_id << 
": is not loaded. Ignoring unload request." << std::endl;
 
  431     const Descriptor* desc = msg.GetDescriptor();
 
  435     unsigned dccl_id = (user_id < 0) ? 
id(desc) : user_id;
 
  436     unsigned head_size_bits;
 
  437     codec->base_size(&head_size_bits, msg, HEAD);
 
  439     unsigned id_bits = 0;
 
  440     id_codec()->field_size(&id_bits, dccl_id, 0);
 
  441     head_size_bits += id_bits;
 
  443     unsigned body_size_bits;
 
  444     codec->base_size(&body_size_bits, msg, BODY);
 
  446     const unsigned head_size_bytes = ceil_bits2bytes(head_size_bits);
 
  447     const unsigned body_size_bytes = ceil_bits2bytes(body_size_bits);
 
  448     return head_size_bytes + body_size_bytes;
 
  456     unsigned head_size_bits;
 
  457     codec->base_max_size(&head_size_bits, desc, HEAD);
 
  459     unsigned id_bits = 0;
 
  460     id_codec()->field_max_size(&id_bits, 0);
 
  461     head_size_bits += id_bits;
 
  463     unsigned body_size_bits;
 
  464     codec->base_max_size(&body_size_bits, desc, BODY);
 
  466     const unsigned head_size_bytes = ceil_bits2bytes(head_size_bits);
 
  467     const unsigned body_size_bytes = ceil_bits2bytes(body_size_bits);
 
  468     return head_size_bytes + body_size_bytes;
 
  475     unsigned head_size_bits;
 
  476     codec->base_min_size(&head_size_bits, desc, HEAD);
 
  478     unsigned id_bits = 0;
 
  479     id_codec()->field_min_size(&id_bits, 0);
 
  480     head_size_bits += id_bits;
 
  482     unsigned body_size_bits;
 
  483     codec->base_min_size(&body_size_bits, desc, BODY);
 
  485     const unsigned head_size_bytes = ceil_bits2bytes(head_size_bits);
 
  486     const unsigned body_size_bytes = ceil_bits2bytes(body_size_bits);
 
  487     return head_size_bytes + body_size_bytes;
 
  492 void dccl::Codec::info(
const google::protobuf::Descriptor* desc, std::ostream* param_os , 
int user_id )
 const 
  494     std::ostream* os = (param_os) ? param_os : &dlog;
 
  496     if(param_os || dlog.
is(INFO))
 
  502             unsigned config_head_bit_size, body_bit_size;
 
  503             codec->base_max_size(&config_head_bit_size, desc, HEAD);
 
  504             codec->base_max_size(&body_bit_size, desc, BODY);
 
  506             unsigned dccl_id = (user_id < 0) ? 
id(desc) : user_id;
 
  507             unsigned id_bit_size = 0;
 
  508             id_codec()->field_size(&id_bit_size, dccl_id, 0);
 
  510             const unsigned bit_size = id_bit_size + config_head_bit_size + body_bit_size;
 
  513             const unsigned byte_size = ceil_bits2bytes(config_head_bit_size + id_bit_size) + ceil_bits2bytes(body_bit_size);
 
  515             const unsigned allowed_byte_size = desc->options().GetExtension(dccl::msg).max_bytes();
 
  516             const unsigned allowed_bit_size = allowed_byte_size * BITS_IN_BYTE;
 
  518             std::string message_name = boost::lexical_cast<std::string>(dccl_id) + 
": " + desc->full_name();
 
  519             std::string guard = std::string((full_width-message_name.size())/2, 
'=');
 
  521             std::string bits_dccl_head_str = 
"dccl.id head";
 
  522             std::string bits_user_head_str = 
"user head";
 
  523             std::string bits_body_str = 
"body";
 
  524             std::string bits_padding_str = 
"padding to full byte";
 
  526             const int bits_width = 40;
 
  527             const int spaces = 8;
 
  528             std::string indent = std::string(spaces,
' ');
 
  530             *os << guard << 
" " << message_name << 
" " << guard << 
"\n" 
  531                 << 
"Actual maximum size of message: " << byte_size << 
" bytes / " 
  532                 << byte_size*BITS_IN_BYTE  << 
" bits\n" 
  533                 << indent << bits_dccl_head_str << std::setfill(
'.') << std::setw(bits_width-bits_dccl_head_str.size()) << id_bit_size << 
"\n" 
  534                 << indent << bits_user_head_str << std::setfill(
'.') << std::setw(bits_width-bits_user_head_str.size()) << config_head_bit_size << 
"\n" 
  535                 << indent << bits_body_str << std::setfill(
'.') << std::setw(bits_width-bits_body_str.size()) << body_bit_size << 
"\n" 
  536                 << indent << bits_padding_str << std::setfill(
'.') << std::setw(bits_width-bits_padding_str.size()) << byte_size * BITS_IN_BYTE - bit_size << 
"\n" 
  537                 << 
"Allowed maximum size of message: " << allowed_byte_size << 
" bytes / " 
  538                 << allowed_bit_size << 
" bits\n";
 
  540             std::string header_str = 
"Header";
 
  541             std::string header_guard = std::string((full_width-header_str.size())/2, 
'-');
 
  542             *os << header_guard << 
" " << header_str << 
" " << header_guard << std::endl;
 
  543             *os << bits_dccl_head_str << std::setfill(
'.') << std::setw(bits_width-bits_dccl_head_str.size()+spaces) << id_bit_size << 
" {" << id_codec()->name() <<  
"}\n";
 
  544             codec->base_info(os, desc, HEAD);
 
  547             std::string body_str = 
"Body";
 
  548             std::string body_guard = std::string((full_width-body_str.size())/2, 
'-');
 
  549             *os << body_guard << 
" " << body_str << 
" " << body_guard << std::endl;
 
  550             codec->base_info(os, desc, BODY);
 
  557             dlog.
is(DEBUG1) && dlog << 
"Message " << desc->full_name() << 
" cannot provide information due to invalid configuration. Reason: " << e.what() << std::endl;
 
  567 void dccl::Codec::encrypt(std::string* s, 
const std::string& nonce )
 
  569 #if DCCL_HAS_CRYPTOPP 
  570     using namespace CryptoPP;
 
  574     StringSource unused(nonce, 
true, 
new HashFilter(hash, 
new StringSink(iv)));
 
  576     CTR_Mode<AES>::Encryption encryptor;
 
  577     encryptor.SetKeyWithIV((
byte*)crypto_key_.c_str(), crypto_key_.size(), (
byte*)iv.c_str());
 
  580     StreamTransformationFilter in(encryptor, 
new StringSink(cipher));
 
  581     in.Put((
byte*)s->c_str(), s->size());
 
  587 void dccl::Codec::decrypt(std::string* s, 
const std::string& nonce)
 
  589 #if DCCL_HAS_CRYPTOPP 
  590     using namespace CryptoPP;
 
  594     StringSource unused(nonce, 
true, 
new HashFilter(hash, 
new StringSink(iv)));
 
  596     CTR_Mode<AES>::Decryption decryptor;
 
  597     decryptor.SetKeyWithIV((
byte*)crypto_key_.c_str(), crypto_key_.size(), (
byte*)iv.c_str());
 
  599     std::string recovered;
 
  601     StreamTransformationFilter out(decryptor, 
new StringSink(recovered));
 
  602     out.Put((
byte*)s->c_str(), s->size());
 
  610     void* handle = dlopen(library_path.c_str(), RTLD_LAZY);
 
  612         dl_handles_.push_back(handle);
 
  613     load_library(handle);
 
  619         throw(
Exception(
"Null shared library handle passed to load_library"));
 
  623     dccl_load_ptr = (void (*)(
dccl::Codec*)) dlsym(dl_handle, 
"dccl3_load");
 
  625         (*dccl_load_ptr)(
this);
 
  631         throw(
Exception(
"Null shared library handle passed to unload_library"));
 
  635     dccl_unload_ptr = (void (*)(
dccl::Codec*)) dlsym(dl_handle, 
"dccl3_unload");
 
  637         (*dccl_unload_ptr)(
this);
 
  643     if(!crypto_key_.empty())
 
  645     skip_crypto_ids_.clear();
 
  647 #if DCCL_HAS_CRYPTOPP 
  648     using namespace CryptoPP;
 
  651     StringSource unused(passphrase, 
true, 
new HashFilter(hash, 
new StringSink(crypto_key_)));
 
  653     dlog.
is(DEBUG1) && dlog << 
"Cryptography enabled with given passphrase" << std::endl;
 
  655     dlog.
is(DEBUG1) && dlog << 
"Cryptography disabled because DCCL was compiled without support of Crypto++. Install Crypto++ and recompile to enable cryptography." << std::endl;
 
  658     skip_crypto_ids_ = do_not_encrypt_ids_;
 
  663     std::ostream* os = (param_os) ? param_os : &dlog;
 
  665     if(param_os || dlog.
is(INFO))
 
  667         std::string codec_str = 
"Dynamic Compact Control Language (DCCL) Codec";
 
  668         std::string codec_guard = std::string((full_width-codec_str.size())/2, 
'|');
 
  669         *os << codec_guard << 
" " << codec_str << 
" " << codec_guard << std::endl;
 
  671         *os << id2desc_.size() << 
" messages loaded.\n";
 
  672         *os << 
"Field sizes are in bits unless otherwise noted." << std::endl;
 
  674         for(std::map<int32, const google::protobuf::Descriptor*>::const_iterator it = id2desc_.begin(), n = id2desc_.end(); it != n; ++it)
 
  675             info(it->second, os, it->first);
 
  687     id_codec_ = id_codec_name;