23 #ifndef MOOSPROTOBUFHELPERS20110216H 24 #define MOOSPROTOBUFHELPERS20110216H 28 #include <boost/format.hpp> 29 #include <boost/regex.hpp> 31 #include <google/protobuf/io/printer.h> 32 #include <google/protobuf/io/tokenizer.h> 34 #include "goby/common/logger.h" 35 #include "goby/moos/moos_string.h" 36 #include "goby/util/as.h" 37 #include "goby/util/binary.h" 38 #include "goby/util/dynamic_protobuf_manager.h" 39 #include "goby/util/primitive_types.h" 41 #include "goby/moos/transitional/message_algorithms.h" 42 #include "goby/moos/transitional/message_val.h" 44 #include "goby/moos/protobuf/translator.pb.h" 50 const std::string MAGIC_PROTOBUF_HEADER =
"@PB";
52 inline std::map<int, std::string>
54 const google::protobuf::RepeatedPtrField<
55 protobuf::TranslatorEntry::PublishSerializer::Algorithm>& algorithms)
57 const google::protobuf::Descriptor* desc = in.GetDescriptor();
60 typedef google::protobuf::RepeatedPtrField<
61 protobuf::TranslatorEntry::PublishSerializer::Algorithm>::const_iterator const_iterator;
63 std::map<int, std::string> modified_values;
65 for (const_iterator it = algorithms.begin(), n = algorithms.end(); it != n; ++it)
67 const google::protobuf::FieldDescriptor* primary_field_desc =
68 desc->FindFieldByNumber(it->primary_field());
70 if (!primary_field_desc || primary_field_desc->is_repeated())
73 std::string primary_val;
75 if (!modified_values.count(it->output_virtual_field()))
77 google::protobuf::TextFormat::PrintFieldValueToString(in, primary_field_desc, -1,
79 boost::trim_if(primary_val, boost::is_any_of(
"\""));
83 primary_val = modified_values[it->output_virtual_field()];
87 std::vector<goby::transitional::DCCLMessageVal> ref;
88 for (
int i = 0, m = it->reference_field_size(); i < m; ++i)
90 const google::protobuf::FieldDescriptor* field_desc =
91 desc->FindFieldByNumber(it->reference_field(i));
93 if (field_desc && !field_desc->is_repeated())
95 std::string ref_value;
96 google::protobuf::TextFormat::PrintFieldValueToString(in, field_desc, -1,
98 ref.push_back(ref_value);
102 throw(std::runtime_error(
"Reference field given is invalid or repeated (must be " 103 "optional or required): " +
104 goby::util::as<std::string>(it->reference_field(i))));
108 transitional::DCCLAlgorithmPerformer::getInstance()->run_algorithm(it->name(), val, ref);
110 val = std::string(val);
111 modified_values[it->output_virtual_field()] = std::string(val);
114 return modified_values;
117 inline std::string strip_name_from_enum(
const std::string& enum_value,
118 const std::string& field_name)
120 return boost::ierase_first_copy(enum_value, field_name +
"_");
123 inline std::string add_name_to_enum(
const std::string& enum_value,
const std::string& field_name)
125 return boost::to_upper_copy(field_name) +
"_" + enum_value;
128 template <goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique technique>
133 template <>
class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>
138 google::protobuf::TextFormat::Printer printer;
139 printer.SetSingleLineMode(
true);
140 printer.PrintToString(in, out);
145 google::protobuf::TextFormat::Parser parser;
147 parser.RecordErrorsTo(&error_collector);
148 parser.ParseFromString(in, out);
152 template <>
class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>
157 in.SerializeToString(out);
162 out->ParseFromString(in);
166 template <>
class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>
171 std::string native_encoded;
173 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::
174 serialize(&native_encoded, in);
175 goby::util::hex_encode(native_encoded, out);
180 std::string native_encoded;
181 goby::util::hex_decode(in, &native_encoded);
183 TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::parse(native_encoded,
188 template <goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique prefix_technique,
189 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique base_technique>
196 goby::moos::MAGIC_PROTOBUF_HEADER +
"[" + msg.GetDescriptor()->full_name() +
"] ";
198 *out = header + *out;
203 if (in.size() > goby::moos::MAGIC_PROTOBUF_HEADER.size() &&
204 in.substr(0, goby::moos::MAGIC_PROTOBUF_HEADER.size()) ==
205 goby::moos::MAGIC_PROTOBUF_HEADER)
207 size_t end_bracket_pos = in.find(
']');
209 if (end_bracket_pos == std::string::npos)
210 throw(std::runtime_error(
211 "Incorrectly formatted protobuf message passed to MOOSTranslation<" +
212 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(
217 in.substr(goby::moos::MAGIC_PROTOBUF_HEADER.size() + 1,
218 end_bracket_pos - 1 - goby::moos::MAGIC_PROTOBUF_HEADER.size());
219 if (name != msg->GetDescriptor()->full_name())
220 throw(std::runtime_error(
221 "Wrong Protobuf type passed to MOOSTranslation<" +
222 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(
224 ">::parse. Expected: " + msg->GetDescriptor()->full_name() +
225 ", received: " + name));
227 if (in.size() > end_bracket_pos + 2)
239 static boost::shared_ptr<google::protobuf::Message> dynamic_parse(
const std::string& in)
241 if (in.size() > goby::moos::MAGIC_PROTOBUF_HEADER.size() &&
242 in.substr(0, goby::moos::MAGIC_PROTOBUF_HEADER.size()) ==
243 goby::moos::MAGIC_PROTOBUF_HEADER)
245 size_t end_bracket_pos = in.find(
']');
247 if (end_bracket_pos == std::string::npos)
248 throw(std::runtime_error(
249 "Incorrectly formatted protobuf message passed to MOOSTranslation<" +
250 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(
252 ">::dynamic_parse."));
255 in.substr(goby::moos::MAGIC_PROTOBUF_HEADER.size() + 1,
256 end_bracket_pos - 1 - goby::moos::MAGIC_PROTOBUF_HEADER.size());
260 boost::shared_ptr<google::protobuf::Message> return_message =
261 goby::util::DynamicProtobufManager::new_protobuf_message(name);
262 if (in.size() > end_bracket_pos + 1)
264 in.substr(end_bracket_pos + 1), return_message.get());
265 return return_message;
267 catch (std::exception& e)
269 return boost::shared_ptr<google::protobuf::Message>();
274 return boost::shared_ptr<google::protobuf::Message>();
280 class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>
282 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT,
283 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>
287 class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>
289 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED,
290 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>
294 class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>
296 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX,
297 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>
302 class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS>
306 const google::protobuf::RepeatedPtrField<
308 google::protobuf::RepeatedPtrField<
310 bool use_short_enum =
false)
312 std::stringstream out_ss;
314 const google::protobuf::Descriptor* desc = in.GetDescriptor();
315 const google::protobuf::Reflection* refl = in.GetReflection();
317 int included_fields = 0;
318 for (
int i = 0, n = desc->field_count(); i < n; ++i)
320 const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
323 if ((!field_desc->is_repeated() && !refl->HasField(in, field_desc)) ||
324 (field_desc->is_repeated() && refl->FieldSize(in, field_desc) == 0))
331 const std::string& field_name = field_desc->name();
333 switch (field_desc->cpp_type())
336 out_ss << to_moos_comma_equals_string_field(in, field_desc,
true,
340 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
341 if (field_desc->is_repeated())
343 for (
int k = 0, o = field_desc->message_type()->field_count(); k < o; ++k)
347 out_ss << field_name <<
"_" 348 << field_desc->message_type()->field(k)->name() <<
"={";
349 for (
int j = 0, m = refl->FieldSize(in, field_desc); j < m; ++j)
354 refl->GetRepeatedMessage(in, field_desc, j);
355 out_ss << to_moos_comma_equals_string_field(
356 embedded_msg, embedded_msg.GetDescriptor()->field(k),
false,
365 for (
int k = 0, o = field_desc->message_type()->field_count(); k < o; ++k)
369 out_ss << field_name <<
"_" 370 << field_desc->message_type()->field(k)->name() <<
"=";
372 refl->GetMessage(in, field_desc);
373 out_ss << to_moos_comma_equals_string_field(
374 embedded_msg, embedded_msg.GetDescriptor()->field(k),
false,
383 std::map<int, std::string> additional_values = run_serialize_algorithms(in, algorithms);
384 for (std::map<int, std::string>::const_iterator it = additional_values.begin(),
385 n = additional_values.end();
392 typedef google::protobuf::RepeatedPtrField<
397 for (const_iterator alg_it = algorithms.begin(), alg_n = algorithms.end();
398 alg_it != alg_n; ++alg_it)
400 if (alg_it->output_virtual_field() == it->first)
405 key += alg_it->name();
406 primary_field = alg_it->primary_field();
409 key +=
"(" + desc->FindFieldByNumber(primary_field)->name() +
")";
411 out_ss << key <<
"=" << it->second;
418 const google::protobuf::RepeatedPtrField<
420 google::protobuf::RepeatedPtrField<
422 bool use_short_enum =
false)
424 const google::protobuf::Descriptor* desc = out->GetDescriptor();
425 const google::protobuf::Reflection* refl = out->GetReflection();
429 for (
int i = 0, n = desc->field_count(); i < n; ++i)
431 const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
433 switch (field_desc->cpp_type())
439 if (goby::moos::val_from_string(val, in, field_desc->name()))
442 typedef google::protobuf::RepeatedPtrField<
446 for (const_iterator it = algorithms.begin(), n = algorithms.end(); it != n;
451 if (it->primary_field() == field_desc->number())
452 transitional::DCCLAlgorithmPerformer::getInstance()->run_algorithm(
453 it->name(), extract_val,
454 std::vector<goby::transitional::DCCLMessageVal>());
456 val = std::string(extract_val);
459 std::vector<std::string> vals;
460 boost::split(vals, val, boost::is_any_of(
","));
461 from_moos_comma_equals_string_field(out, field_desc, vals, 0,
467 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
468 if (field_desc->is_repeated())
470 for (
int k = 0, o = field_desc->message_type()->field_count(); k < o; ++k)
473 if (goby::moos::val_from_string(
475 field_desc->name() +
"_" +
476 field_desc->message_type()->field(k)->name()))
478 std::vector<std::string> vals;
479 boost::split(vals, val, boost::is_any_of(
","));
481 for (
int j = 0, m = vals.size(); j < m; ++j)
484 (refl->FieldSize(*out, field_desc) < j + 1)
485 ? refl->AddMessage(out, field_desc)
486 : refl->MutableRepeatedMessage(out, field_desc, j);
487 from_moos_comma_equals_string_field(
488 embedded_msg, embedded_msg->GetDescriptor()->field(k), vals,
496 for (
int k = 0, o = field_desc->message_type()->field_count(); k < o; ++k)
499 if (goby::moos::val_from_string(
501 field_desc->name() +
"_" +
502 field_desc->message_type()->field(k)->name()))
504 std::vector<std::string> vals;
505 boost::split(vals, val, boost::is_any_of(
","));
508 refl->MutableMessage(out, field_desc);
509 from_moos_comma_equals_string_field(
510 embedded_msg, embedded_msg->GetDescriptor()->field(k), vals, 0,
523 const google::protobuf::FieldDescriptor* field_desc,
524 bool write_key =
true,
bool use_short_enum =
false)
526 const google::protobuf::Reflection* refl = proto_msg.GetReflection();
528 std::stringstream out;
529 const std::string& field_name = field_desc->name();
531 if (field_desc->is_repeated())
534 out << field_name <<
"={";
536 for (
int j = 0, m = refl->FieldSize(proto_msg, field_desc); j < m; ++j)
541 switch (field_desc->cpp_type())
543 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
544 out << goby::util::hex_encode(
545 refl->GetRepeatedMessage(proto_msg, field_desc, j).SerializeAsString());
548 case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
549 out << refl->GetRepeatedInt32(proto_msg, field_desc, j);
552 case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
553 out << refl->GetRepeatedInt64(proto_msg, field_desc, j);
556 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
557 out << refl->GetRepeatedUInt32(proto_msg, field_desc, j);
560 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
561 out << refl->GetRepeatedUInt64(proto_msg, field_desc, j);
564 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
565 out << std::boolalpha << refl->GetRepeatedBool(proto_msg, field_desc, j);
568 case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
569 if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_STRING)
570 out << refl->GetRepeatedString(proto_msg, field_desc, j);
571 else if (field_desc->type() ==
572 google::protobuf::FieldDescriptor::TYPE_BYTES)
573 out << goby::util::hex_encode(
574 refl->GetRepeatedString(proto_msg, field_desc, j));
577 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
578 out << std::setprecision(std::numeric_limits<float>::digits10)
579 << refl->GetRepeatedFloat(proto_msg, field_desc, j);
582 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
583 out << std::setprecision(std::numeric_limits<double>::digits10)
584 << refl->GetRepeatedDouble(proto_msg, field_desc, j);
587 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
588 out << ((use_short_enum)
589 ? strip_name_from_enum(
590 refl->GetRepeatedEnum(proto_msg, field_desc, j)->name(),
592 : refl->GetRepeatedEnum(proto_msg, field_desc, j)->name());
603 out << field_name <<
"=";
604 switch (field_desc->cpp_type())
606 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
607 out << goby::util::hex_encode(
608 refl->GetMessage(proto_msg, field_desc).SerializeAsString());
611 case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
612 out << refl->GetInt32(proto_msg, field_desc);
615 case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
616 out << refl->GetInt64(proto_msg, field_desc);
619 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
620 out << refl->GetUInt32(proto_msg, field_desc);
623 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
624 out << refl->GetUInt64(proto_msg, field_desc);
627 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
628 out << std::boolalpha << refl->GetBool(proto_msg, field_desc);
631 case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
632 if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_STRING)
633 out << refl->GetString(proto_msg, field_desc);
634 else if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_BYTES)
635 out << goby::util::hex_encode(refl->GetString(proto_msg, field_desc));
638 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
639 out << std::setprecision(std::numeric_limits<float>::digits10)
640 << refl->GetFloat(proto_msg, field_desc);
643 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
644 out << std::setprecision(std::numeric_limits<double>::digits10)
645 << refl->GetDouble(proto_msg, field_desc);
648 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
649 out << ((use_short_enum)
650 ? strip_name_from_enum(refl->GetEnum(proto_msg, field_desc)->name(),
652 : refl->GetEnum(proto_msg, field_desc)->name());
658 static void from_moos_comma_equals_string_field(
660 const std::vector<std::string>& values,
int value_key = 0,
bool use_short_enum =
false)
662 if (values.size() == 0)
665 const google::protobuf::Reflection* refl = proto_msg->GetReflection();
666 if (field_desc->is_repeated())
668 for (
int j = 0, m = values.size(); j < m; ++j)
670 const std::string& v = values[j];
672 switch (field_desc->cpp_type())
674 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
675 refl->AddMessage(proto_msg, field_desc)
676 ->ParseFromString(goby::util::hex_decode(v));
679 case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
680 refl->AddInt32(proto_msg, field_desc,
681 goby::util::as<google::protobuf::int32>(v));
684 case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
685 refl->AddInt64(proto_msg, field_desc,
686 goby::util::as<google::protobuf::int64>(v));
689 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
690 refl->AddUInt32(proto_msg, field_desc,
691 goby::util::as<google::protobuf::uint32>(v));
694 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
695 refl->AddUInt64(proto_msg, field_desc,
696 goby::util::as<google::protobuf::uint64>(v));
699 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
700 refl->AddBool(proto_msg, field_desc, goby::util::as<bool>(v));
703 case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
704 if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_STRING)
705 refl->AddString(proto_msg, field_desc, v);
706 else if (field_desc->type() ==
707 google::protobuf::FieldDescriptor::TYPE_BYTES)
708 refl->AddString(proto_msg, field_desc, goby::util::hex_decode(v));
711 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
712 refl->AddFloat(proto_msg, field_desc, goby::util::as<float>(v));
715 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
716 refl->AddDouble(proto_msg, field_desc, goby::util::as<double>(v));
719 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
721 std::string enum_value =
722 ((use_short_enum) ? add_name_to_enum(v, field_desc->name()) : v);
724 const google::protobuf::EnumValueDescriptor* enum_desc =
725 field_desc->enum_type()->FindValueByName(enum_value);
729 enum_desc = field_desc->enum_type()->FindValueByName(
730 boost::algorithm::to_upper_copy(enum_value));
733 enum_desc = field_desc->enum_type()->FindValueByName(
734 boost::algorithm::to_lower_copy(enum_value));
737 refl->AddEnum(proto_msg, field_desc, enum_desc);
745 const std::string& v = values[value_key];
746 switch (field_desc->cpp_type())
748 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
749 refl->MutableMessage(proto_msg, field_desc)
750 ->ParseFromString(goby::util::hex_decode(v));
753 case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
754 refl->SetInt32(proto_msg, field_desc,
755 goby::util::as<google::protobuf::int32>(v));
758 case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
759 refl->SetInt64(proto_msg, field_desc,
760 goby::util::as<google::protobuf::int64>(v));
763 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
764 refl->SetUInt32(proto_msg, field_desc,
765 goby::util::as<google::protobuf::uint32>(v));
768 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
769 refl->SetUInt64(proto_msg, field_desc,
770 goby::util::as<google::protobuf::uint64>(v));
773 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
774 refl->SetBool(proto_msg, field_desc, goby::util::as<bool>(v));
777 case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
778 if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_STRING)
779 refl->SetString(proto_msg, field_desc, v);
780 else if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_BYTES)
781 refl->SetString(proto_msg, field_desc, goby::util::hex_decode(v));
784 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
785 refl->SetFloat(proto_msg, field_desc, goby::util::as<float>(v));
788 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
789 refl->SetDouble(proto_msg, field_desc, goby::util::as<double>(v));
792 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
794 std::string enum_value =
795 ((use_short_enum) ? add_name_to_enum(v, field_desc->name()) : v);
797 const google::protobuf::EnumValueDescriptor* enum_desc =
798 field_desc->enum_type()->FindValueByName(enum_value);
802 enum_desc = field_desc->enum_type()->FindValueByName(
803 boost::algorithm::to_upper_copy(enum_value));
806 enum_desc = field_desc->enum_type()->FindValueByName(
807 boost::algorithm::to_lower_copy(enum_value));
810 refl->SetEnum(proto_msg, field_desc, enum_desc);
821 struct RepeatedFieldKey
828 const google::protobuf::RepeatedPtrField<
830 const std::string& format,
const std::string& repeated_delimiter,
831 bool use_short_enum =
false)
833 std::string mutable_format = format;
835 const google::protobuf::Descriptor* desc = in.GetDescriptor();
836 const google::protobuf::Reflection* refl = in.GetReflection();
838 int max_field_number = 1;
839 for (
int i = 1, n = desc->field_count(); i < n; ++i)
841 const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
842 if (field_desc->number() > max_field_number)
843 max_field_number = field_desc->number();
847 std::map<int, std::string> modified_values = run_serialize_algorithms(in, algorithms);
849 for (std::map<int, std::string>::const_iterator it = modified_values.begin(),
850 n = modified_values.end();
853 if (it->first > max_field_number)
854 max_field_number = it->first;
857 std::string mutable_format_temp = mutable_format;
858 for (boost::sregex_iterator it(mutable_format.begin(), mutable_format.end(),
859 boost::regex(
"%([0-9\\.]+:)+[0-9\\.]+%")),
863 std::string match = (*it)[0];
865 boost::trim_if(match, boost::is_any_of(
"%"));
866 std::vector<std::string> subfields;
867 boost::split(subfields, match, boost::is_any_of(
":"));
871 const google::protobuf::FieldDescriptor* field_desc = 0;
872 const google::protobuf::Reflection* sub_refl = refl;
875 for (
int i = 0, n = subfields.size() - 1; i < n; ++i)
877 std::vector<std::string> field_and_index;
878 boost::split(field_and_index, subfields[i], boost::is_any_of(
"."));
880 field_desc = sub_message->GetDescriptor()->FindFieldByNumber(
881 goby::util::as<int>(field_and_index[0]));
883 field_desc->cpp_type() != google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
885 throw(std::runtime_error(
886 "Invalid ':' syntax given for format: " + match +
887 ". All field indices except the last must be embedded messages"));
889 if (field_desc->is_repeated() && field_and_index.size() != 2)
891 throw(std::runtime_error(
"Invalid '.' syntax given for format: " + match +
892 ". Repeated message, but no valid index given. E.g., " 893 "use '3.4' for index 4 of field 3."));
897 (field_desc->is_repeated())
898 ? &sub_refl->GetRepeatedMessage(*sub_message, field_desc,
899 goby::util::as<int>(field_and_index[1]))
900 : &sub_refl->GetMessage(*sub_message, field_desc);
901 sub_refl = sub_message->GetReflection();
904 serialize(&modified_values[max_field_number], *sub_message, algorithms,
905 "%" + subfields[subfields.size() - 1] +
"%", repeated_delimiter,
909 mutable_format_temp, std::string(
"%" + match +
"%"),
910 std::string(
"%" + goby::util::as<std::string>(max_field_number) +
"%"));
913 mutable_format = mutable_format_temp;
915 std::map<int, RepeatedFieldKey> indexed_repeated_fields;
917 for (boost::sregex_iterator it(mutable_format.begin(), mutable_format.end(),
918 boost::regex(
"%[0-9]+\\.[0-9]+%")),
922 std::string match = (*it)[0];
923 boost::trim_if(match, boost::is_any_of(
"%"));
928 mutable_format_temp, std::string(
"%" + match +
"%"),
929 std::string(
"%" + goby::util::as<std::string>(max_field_number) +
"%"));
931 RepeatedFieldKey key;
933 std::vector<std::string> field_and_index;
934 boost::split(field_and_index, match, boost::is_any_of(
"."));
936 key.field = goby::util::as<int>(field_and_index[0]);
937 key.index = goby::util::as<int>(field_and_index[1]);
939 indexed_repeated_fields[max_field_number] = key;
942 mutable_format = mutable_format_temp;
944 boost::format out_format(mutable_format);
945 out_format.exceptions(boost::io::all_error_bits ^
946 (boost::io::too_many_args_bit | boost::io::too_few_args_bit));
948 for (
int i = 1; i <= max_field_number; ++i)
950 bool is_indexed_repeated_field = indexed_repeated_fields.count(i);
952 const google::protobuf::FieldDescriptor* field_desc = desc->FindFieldByNumber(
953 is_indexed_repeated_field ? indexed_repeated_fields[i].field : i);
954 std::map<int, std::string>::const_iterator mod_it = modified_values.find(i);
957 if (field_desc->is_repeated())
959 int start = (is_indexed_repeated_field) ? indexed_repeated_fields[i].index : 0;
960 int end = (is_indexed_repeated_field) ? indexed_repeated_fields[i].index + 1
961 : refl->FieldSize(in, field_desc);
963 std::stringstream out_repeated;
964 for (
int j = start; j < end; ++j)
966 if (j && !is_indexed_repeated_field)
967 out_repeated << repeated_delimiter;
968 switch (field_desc->cpp_type())
970 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
971 out_repeated << goby::util::hex_encode(
972 refl->GetRepeatedMessage(in, field_desc, j)
973 .SerializeAsString());
976 case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
977 out_repeated << ((j < refl->FieldSize(in, field_desc))
978 ? refl->GetRepeatedInt32(in, field_desc, j)
979 : std::numeric_limits<int32>::max());
983 case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
984 out_repeated << ((j < refl->FieldSize(in, field_desc))
985 ? refl->GetRepeatedInt64(in, field_desc, j)
986 : std::numeric_limits<int64>::max());
989 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
990 out_repeated << ((j < refl->FieldSize(in, field_desc))
991 ? refl->GetRepeatedUInt32(in, field_desc, j)
992 : std::numeric_limits<uint32>::max());
995 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
996 out_repeated << ((j < refl->FieldSize(in, field_desc))
997 ? refl->GetRepeatedUInt64(in, field_desc, j)
998 : std::numeric_limits<uint64>::max());
1001 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
1002 out_repeated << std::boolalpha
1003 << ((j < refl->FieldSize(in, field_desc))
1004 ? refl->GetRepeatedBool(in, field_desc, j)
1005 : field_desc->default_value_bool());
1008 case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
1009 if (field_desc->type() ==
1010 google::protobuf::FieldDescriptor::TYPE_STRING)
1012 << ((j < refl->FieldSize(in, field_desc))
1013 ? refl->GetRepeatedString(in, field_desc, j)
1014 : field_desc->default_value_string());
1015 else if (field_desc->type() ==
1016 google::protobuf::FieldDescriptor::TYPE_BYTES)
1017 out_repeated << goby::util::hex_encode(
1018 ((j < refl->FieldSize(in, field_desc))
1019 ? refl->GetRepeatedString(in, field_desc, j)
1020 : field_desc->default_value_string()));
1023 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
1025 << std::setprecision(std::numeric_limits<float>::digits10)
1026 << ((j < refl->FieldSize(in, field_desc))
1027 ? refl->GetRepeatedFloat(in, field_desc, j)
1028 : std::numeric_limits<float>::quiet_NaN());
1031 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
1033 << std::setprecision(std::numeric_limits<double>::digits10)
1034 << ((j < refl->FieldSize(in, field_desc))
1035 ? refl->GetRepeatedDouble(in, field_desc, j)
1036 : std::numeric_limits<double>::quiet_NaN());
1039 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
1041 const google::protobuf::EnumValueDescriptor* enum_val =
1042 ((j < refl->FieldSize(in, field_desc))
1043 ? refl->GetRepeatedEnum(in, field_desc, j)
1044 : field_desc->default_value_enum());
1046 << ((use_short_enum) ? strip_name_from_enum(enum_val->name(),
1048 : enum_val->name());
1053 out_format % out_repeated.str();
1057 switch (field_desc->cpp_type())
1059 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
1060 out_format % goby::util::hex_encode(
1061 refl->GetMessage(in, field_desc).SerializeAsString());
1064 case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
1065 out_format % refl->GetInt32(in, field_desc);
1068 case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
1069 out_format % refl->GetInt64(in, field_desc);
1072 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
1073 out_format % refl->GetUInt32(in, field_desc);
1076 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
1077 out_format % refl->GetUInt64(in, field_desc);
1080 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
1081 out_format % goby::util::as<std::string>(refl->GetBool(in, field_desc));
1084 case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
1085 if (field_desc->type() ==
1086 google::protobuf::FieldDescriptor::TYPE_STRING)
1087 out_format % refl->GetString(in, field_desc);
1088 else if (field_desc->type() ==
1089 google::protobuf::FieldDescriptor::TYPE_BYTES)
1091 goby::util::hex_encode(refl->GetString(in, field_desc));
1094 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
1095 out_format % boost::io::group(std::setprecision(
1096 std::numeric_limits<float>::digits10),
1097 refl->GetFloat(in, field_desc));
1100 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
1103 std::setprecision(std::numeric_limits<double>::digits10),
1104 refl->GetDouble(in, field_desc));
1107 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
1111 ? strip_name_from_enum(refl->GetEnum(in, field_desc)->name(),
1113 : refl->GetEnum(in, field_desc)->name());
1118 else if (mod_it != modified_values.end())
1120 out_format % mod_it->second;
1124 out_format %
"unknown";
1128 *out = out_format.str();
1132 const std::string& repeated_delimiter,
1133 const google::protobuf::RepeatedPtrField<
1135 google::protobuf::RepeatedPtrField<
1137 bool use_short_enum =
false)
1139 const google::protobuf::Descriptor* desc = out->GetDescriptor();
1140 const google::protobuf::Reflection* refl = out->GetReflection();
1141 boost::to_lower(format);
1142 std::string str = in;
1143 std::string lower_str = boost::to_lower_copy(in);
1149 std::string::const_iterator i = format.begin();
1151 while (i != format.end())
1156 std::string specifier;
1157 while (*i !=
'%') specifier += *i++;
1160 std::string extract = str.substr(0, lower_str.find(*i));
1162 if (specifier.find(
":") != std::string::npos)
1164 std::vector<std::string> subfields;
1165 boost::split(subfields, specifier, boost::is_any_of(
":"));
1166 const google::protobuf::FieldDescriptor* field_desc = 0;
1167 const google::protobuf::Reflection* sub_refl = refl;
1170 for (
int i = 0, n = subfields.size() - 1; i < n; ++i)
1172 std::vector<std::string> field_and_index;
1173 boost::split(field_and_index, subfields[i], boost::is_any_of(
"."));
1175 field_desc = sub_message->GetDescriptor()->FindFieldByNumber(
1176 goby::util::as<int>(field_and_index[0]));
1177 if (!field_desc || field_desc->cpp_type() !=
1178 google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
1180 throw(std::runtime_error(
1181 "Invalid ':' syntax given for format: " + specifier +
1182 ". All field indices except the last must be singular embedded " 1187 if (field_desc->is_repeated())
1189 if (field_and_index.size() != 2)
1190 throw(std::runtime_error(
1191 "Invalid '.' syntax given for format: " + specifier +
1192 ". Repeated message, but no valid index given. E.g., use '3.4' " 1193 "for index 4 of field 3."));
1194 index = goby::util::as<int>(field_and_index.at(1));
1195 while (sub_refl->FieldSize(*sub_message, field_desc) <= index)
1196 sub_refl->AddMessage(sub_message, field_desc);
1200 (field_desc->is_repeated())
1201 ? sub_refl->MutableRepeatedMessage(sub_message, field_desc, index)
1202 : sub_refl->MutableMessage(sub_message, field_desc);
1203 sub_refl = sub_message->GetReflection();
1206 parse(extract, sub_message,
"%" + subfields[subfields.size() - 1] +
"%",
1207 repeated_delimiter, algorithms, use_short_enum);
1213 std::vector<std::string> field_and_index;
1214 boost::split(field_and_index, specifier, boost::is_any_of(
"."));
1216 int field_index = boost::lexical_cast<
int>(field_and_index[0]);
1217 bool is_indexed_repeated_field = field_and_index.size() == 2;
1219 int value_index = 0;
1220 if (is_indexed_repeated_field)
1221 value_index = boost::lexical_cast<
int>(field_and_index[1]);
1223 const google::protobuf::FieldDescriptor* field_desc =
1224 desc->FindFieldByNumber(field_index);
1227 throw(std::runtime_error(
"Bad field: " + specifier +
1228 " not in message " + desc->full_name()));
1231 typedef google::protobuf::RepeatedPtrField<
1235 for (const_iterator it = algorithms.begin(), n = algorithms.end(); it != n;
1240 if (it->primary_field() == field_index)
1241 transitional::DCCLAlgorithmPerformer::getInstance()->run_algorithm(
1242 it->name(), extract_val,
1243 std::vector<goby::transitional::DCCLMessageVal>());
1245 extract = std::string(extract_val);
1248 std::vector<std::string> parts;
1249 if (is_indexed_repeated_field || !field_desc->is_repeated())
1250 parts.push_back(extract);
1252 boost::split(parts, extract, boost::is_any_of(repeated_delimiter));
1254 for (
int j = 0, m = parts.size(); j < m; ++j)
1256 switch (field_desc->cpp_type())
1258 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
1259 if (is_indexed_repeated_field)
1261 while (refl->FieldSize(*out, field_desc) <= value_index)
1262 refl->AddMessage(out, field_desc);
1264 field_desc->is_repeated()
1265 ? (is_indexed_repeated_field
1266 ? refl->MutableRepeatedMessage(out, field_desc,
1269 goby::util::hex_decode(parts[j]))
1270 : refl->AddMessage(out, field_desc)
1272 goby::util::hex_decode(parts[j])))
1273 : refl->MutableMessage(out, field_desc)
1274 ->ParseFromString(goby::util::hex_decode(parts[j]));
1277 case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
1278 if (is_indexed_repeated_field)
1280 while (refl->FieldSize(*out, field_desc) <= value_index)
1281 refl->AddInt32(out, field_desc,
1282 field_desc->default_value_int32());
1284 field_desc->is_repeated()
1285 ? (is_indexed_repeated_field
1286 ? refl->SetRepeatedInt32(
1287 out, field_desc, value_index,
1288 goby::util::as<google::protobuf::int32>(
1292 goby::util::as<google::protobuf::int32>(
1296 goby::util::as<google::protobuf::int32>(parts[j]));
1299 case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
1300 if (is_indexed_repeated_field)
1302 while (refl->FieldSize(*out, field_desc) <= value_index)
1303 refl->AddInt64(out, field_desc,
1304 field_desc->default_value_int64());
1306 field_desc->is_repeated()
1307 ? (is_indexed_repeated_field
1308 ? refl->SetRepeatedInt64(
1309 out, field_desc, value_index,
1310 goby::util::as<google::protobuf::int64>(
1314 goby::util::as<google::protobuf::int64>(
1318 goby::util::as<google::protobuf::int64>(parts[j]));
1321 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
1322 if (is_indexed_repeated_field)
1324 while (refl->FieldSize(*out, field_desc) <= value_index)
1325 refl->AddUInt32(out, field_desc,
1326 field_desc->default_value_uint32());
1328 field_desc->is_repeated()
1329 ? (is_indexed_repeated_field
1330 ? refl->SetRepeatedUInt32(
1331 out, field_desc, value_index,
1332 goby::util::as<google::protobuf::uint32>(
1336 goby::util::as<google::protobuf::uint32>(
1340 goby::util::as<google::protobuf::uint32>(parts[j]));
1343 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
1344 if (is_indexed_repeated_field)
1346 while (refl->FieldSize(*out, field_desc) <= value_index)
1347 refl->AddUInt64(out, field_desc,
1348 field_desc->default_value_uint64());
1350 field_desc->is_repeated()
1351 ? (is_indexed_repeated_field
1352 ? refl->SetRepeatedUInt64(
1353 out, field_desc, value_index,
1354 goby::util::as<google::protobuf::uint64>(
1358 goby::util::as<google::protobuf::uint64>(
1362 goby::util::as<google::protobuf::uint64>(parts[j]));
1365 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
1366 if (is_indexed_repeated_field)
1368 while (refl->FieldSize(*out, field_desc) <= value_index)
1369 refl->AddBool(out, field_desc,
1370 field_desc->default_value_bool());
1372 field_desc->is_repeated()
1373 ? (is_indexed_repeated_field
1374 ? refl->SetRepeatedBool(
1375 out, field_desc, value_index,
1376 goby::util::as<bool>(parts[j]))
1377 : refl->AddBool(out, field_desc,
1378 goby::util::as<bool>(parts[j])))
1379 : refl->SetBool(out, field_desc,
1380 goby::util::as<bool>(parts[j]));
1383 case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
1384 if (is_indexed_repeated_field)
1386 while (refl->FieldSize(*out, field_desc) <= value_index)
1387 refl->AddString(out, field_desc,
1388 field_desc->default_value_string());
1390 field_desc->is_repeated()
1391 ? (is_indexed_repeated_field
1392 ? refl->SetRepeatedString(out, field_desc,
1393 value_index, parts[j])
1394 : refl->AddString(out, field_desc, parts[j]))
1395 : refl->SetString(out, field_desc, parts[j]);
1398 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
1399 if (is_indexed_repeated_field)
1401 while (refl->FieldSize(*out, field_desc) <= value_index)
1402 refl->AddFloat(out, field_desc,
1403 field_desc->default_value_float());
1405 field_desc->is_repeated()
1406 ? (is_indexed_repeated_field
1407 ? refl->SetRepeatedFloat(
1408 out, field_desc, value_index,
1409 goby::util::as<float>(parts[j]))
1410 : refl->AddFloat(out, field_desc,
1411 goby::util::as<float>(parts[j])))
1412 : refl->SetFloat(out, field_desc,
1413 goby::util::as<float>(parts[j]));
1416 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
1417 if (is_indexed_repeated_field)
1419 while (refl->FieldSize(*out, field_desc) <= value_index)
1420 refl->AddDouble(out, field_desc,
1421 field_desc->default_value_double());
1423 field_desc->is_repeated()
1424 ? (is_indexed_repeated_field
1425 ? refl->SetRepeatedDouble(
1426 out, field_desc, value_index,
1427 goby::util::as<double>(parts[j]))
1428 : refl->AddDouble(out, field_desc,
1429 goby::util::as<double>(parts[j])))
1430 : refl->SetDouble(out, field_desc,
1431 goby::util::as<double>(parts[j]));
1434 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
1436 if (is_indexed_repeated_field)
1438 while (refl->FieldSize(*out, field_desc) <= value_index)
1439 refl->AddEnum(out, field_desc,
1440 field_desc->default_value_enum());
1442 std::string enum_value =
1444 ? add_name_to_enum(parts[j], field_desc->name())
1447 const google::protobuf::EnumValueDescriptor* enum_desc =
1448 refl->GetEnum(*out, field_desc)
1450 ->FindValueByName(enum_value);
1455 refl->GetEnum(*out, field_desc)
1457 ->FindValueByName(boost::to_upper_copy(enum_value));
1461 refl->GetEnum(*out, field_desc)
1463 ->FindValueByName(boost::to_lower_copy(enum_value));
1466 field_desc->is_repeated()
1467 ? (is_indexed_repeated_field
1468 ? refl->SetRepeatedEnum(out, field_desc,
1469 value_index, enum_desc)
1470 : refl->AddEnum(out, field_desc, enum_desc))
1471 : refl->SetEnum(out, field_desc, enum_desc);
1478 catch (boost::bad_lexical_cast&)
1480 throw(std::runtime_error(
1481 "Bad specifier: " + specifier +
1482 ", must be an integer. For message: " + desc->full_name()));
1491 std::string::size_type pos_to_remove = lower_str.find(*i) + 1;
1492 lower_str.erase(0, pos_to_remove);
1493 str.erase(0, pos_to_remove);
1512 extern goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique moos_technique;
1518 switch (goby::moos::moos_technique)
1520 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED:
1522 TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::serialize(out, msg);
1524 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX:
1526 TECHNIQUE_PROTOBUF_NATIVE_HEX>::serialize(out, msg);
1528 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT:
1530 TECHNIQUE_PROTOBUF_TEXT_FORMAT>::serialize(out, msg);
1532 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED:
1534 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::
1535 serialize(out, msg);
1537 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX:
1539 TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::serialize(out,
1542 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT:
1544 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::
1545 serialize(out, msg);
1550 <<
"Non-PROTOBUF techniques are not supported for 'moos_parser_technique': " 1551 << goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(
1552 goby::moos::moos_technique)
1564 switch (goby::moos::moos_technique)
1566 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED:
1568 TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::parse(in, msg);
1570 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX:
1572 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>::parse(in,
1575 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT:
1577 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>::parse(in,
1581 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED:
1583 TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::parse(in,
1586 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX:
1588 TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::parse(in, msg);
1590 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT:
1592 TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::parse(in,
1598 <<
"Non-PROTOBUF techniques are not supported for 'moos_parser_technique': " 1599 << goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(
1600 goby::moos::moos_technique)
1606 inline boost::shared_ptr<google::protobuf::Message> dynamic_parse_for_moos(
const std::string& in)
1608 switch (goby::moos::moos_technique)
1610 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED:
1612 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::
1615 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX:
1617 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::
1620 case goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT:
1622 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::
1627 goby::glog <<
"Non-PREFIX techniques are not supported when using " 1628 "dynamic_parse_for_moos for 'moos_parser_technique': " 1629 << goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(
1630 goby::moos::moos_technique)
1632 return boost::shared_ptr<google::protobuf::Message>();
void parse_for_moos(const std::string &in, google::protobuf::Message *msg)
Parses the string in to Google Protocol Buffers message msg. All errors are written to the goby::util...
common::FlexOstream glog
Access the Goby logger through this object.
The global namespace for the Goby project.