Goby3  3.1.5a
2024.05.23
moos_protobuf_helpers.h
Go to the documentation of this file.
1 // Copyright 2009-2021:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 // File authors:
6 // Toby Schneider <toby@gobysoft.org>
7 // Russ Webber <russ@rw.id.au>
8 //
9 //
10 // This file is part of the Goby Underwater Autonomy Project Libraries
11 // ("The Goby Libraries").
12 //
13 // The Goby Libraries are free software: you can redistribute them and/or modify
14 // them under the terms of the GNU Lesser General Public License as published by
15 // the Free Software Foundation, either version 2.1 of the License, or
16 // (at your option) any later version.
17 //
18 // The Goby Libraries are distributed in the hope that they will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU Lesser General Public License for more details.
22 //
23 // You should have received a copy of the GNU Lesser General Public License
24 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
25 
26 #ifndef GOBY_MOOS_MOOS_PROTOBUF_HELPERS_H
27 #define GOBY_MOOS_MOOS_PROTOBUF_HELPERS_H
28 
29 #include <algorithm> // for max
30 #include <cstddef> // for size_t
31 #include <cstdint> // for int32_t, int64_t
32 #include <iomanip> // for _Setprecision
33 #include <limits> // for numeric_limits
34 #include <map> // for map, map<>::c...
35 #include <memory> // for allocator
36 #include <mutex> // for mutex, lock_g...
37 #include <regex> // for sregex_iterator
38 #include <sstream> // for basic_ostream
39 #include <stdexcept> // for runtime_error
40 #include <string> // for string, opera...
41 #include <utility> // for pair
42 #include <vector> // for vector
43 
44 #include <boost/algorithm/string/case_conv.hpp> // for to_lower_copy
45 #include <boost/algorithm/string/classification.hpp> // for is_any_ofF
46 #include <boost/algorithm/string/erase.hpp> // for ierase_first_...
47 #include <boost/algorithm/string/replace.hpp> // for replace_all
48 #include <boost/algorithm/string/split.hpp> // for split
49 #include <boost/algorithm/string/trim.hpp> // for trim_if
50 #include <boost/core/enable_if.hpp> // for enable_if_c<>...
51 #include <boost/format.hpp> // for basic_altstri...
52 #include <boost/lexical_cast.hpp> // for lexical_cast
53 #include <boost/lexical_cast/bad_lexical_cast.hpp> // for bad_lexical_cast
54 #include <google/protobuf/descriptor.h> // for FieldDescriptor
55 #include <google/protobuf/message.h> // for Reflection
56 #include <google/protobuf/text_format.h> // for TextFormat
57 
58 #include "dccl/dynamic_protobuf_manager.h" // for DynamicProtob...
59 #include "goby/moos/moos_string.h" // for val_from_string
60 #include "goby/moos/protobuf/goby_moos_app.pb.h" // for RepeatedPtrField
61 #include "goby/moos/protobuf/translator.pb.h" // for TranslatorEntry
62 #include "goby/moos/transitional/message_algorithms.h" // for DCCLAlgorithm...
63 #include "goby/moos/transitional/message_val.h" // for DCCLMessageVal
64 #include "goby/util/as.h" // for as
65 #include "goby/util/binary.h" // for hex_encode
66 #include "goby/util/debug_logger/flex_ostream.h" // for operator<<
67 #include "goby/util/debug_logger/flex_ostreambuf.h" // for DIE
68 
69 namespace goby
70 {
71 namespace moos
72 {
74 
75 const std::string MAGIC_PROTOBUF_HEADER = "@PB";
76 
77 inline std::map<int, std::string>
81 {
82  const google::protobuf::Descriptor* desc = in.GetDescriptor();
83 
84  // run algorithms
85  std::map<int, std::string> modified_values;
86 
87  for (const auto& algorithm : algorithms)
88  {
89  const google::protobuf::FieldDescriptor* primary_field_desc =
90  desc->FindFieldByNumber(algorithm.primary_field());
91 
92  if (!primary_field_desc || primary_field_desc->is_repeated())
93  continue;
94 
95  std::string primary_val;
96 
97  if (!modified_values.count(algorithm.output_virtual_field()))
98  {
99  google::protobuf::TextFormat::PrintFieldValueToString(in, primary_field_desc, -1,
100  &primary_val);
101  boost::trim_if(primary_val, boost::is_any_of("\""));
102  }
103  else
104  {
105  primary_val = modified_values[algorithm.output_virtual_field()];
106  }
107 
109  std::vector<goby::moos::transitional::DCCLMessageVal> ref;
110  for (int i = 0, m = algorithm.reference_field_size(); i < m; ++i)
111  {
112  const google::protobuf::FieldDescriptor* field_desc =
113  desc->FindFieldByNumber(algorithm.reference_field(i));
114 
115  if (field_desc && !field_desc->is_repeated())
116  {
117  std::string ref_value;
118  google::protobuf::TextFormat::PrintFieldValueToString(in, field_desc, -1,
119  &ref_value);
120  ref.emplace_back(ref_value);
121  }
122  else
123  {
124  throw(
125  std::runtime_error("Reference field given is invalid or repeated (must be "
126  "optional or required): " +
127  goby::util::as<std::string>(algorithm.reference_field(i))));
128  }
129  }
130 
132  val, ref);
133 
134  val = std::string(val);
135  modified_values[algorithm.output_virtual_field()] = std::string(val);
136  }
137 
138  return modified_values;
139 }
140 
141 inline std::string strip_name_from_enum(const std::string& enum_value,
142  const std::string& field_name)
143 {
144  return boost::ierase_first_copy(enum_value, field_name + "_");
145 }
146 
147 inline std::string add_name_to_enum(const std::string& enum_value, const std::string& field_name)
148 {
149  return boost::to_upper_copy(field_name) + "_" + enum_value;
150 }
151 
152 template <goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique technique>
154 {
155 };
156 
157 template <> class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>
158 {
159  public:
160  static void serialize(std::string* out, const google::protobuf::Message& in)
161  {
162  google::protobuf::TextFormat::Printer printer;
163  printer.SetSingleLineMode(true);
164  printer.PrintToString(in, out);
165  }
166 
167  static void parse(const std::string& in, google::protobuf::Message* out)
168  {
169  google::protobuf::TextFormat::Parser parser;
170  goby::util::FlexOStreamErrorCollector error_collector(in);
171  parser.RecordErrorsTo(&error_collector);
172  parser.ParseFromString(in, out);
173  }
174 };
175 
176 template <> class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>
177 {
178  public:
179  static void serialize(std::string* out, const google::protobuf::Message& in)
180  {
181  in.SerializeToString(out);
182  }
183 
184  static void parse(const std::string& in, google::protobuf::Message* out)
185  {
186  out->ParseFromString(in);
187  }
188 };
189 
190 template <> class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>
191 {
192  public:
193  static void serialize(std::string* out, const google::protobuf::Message& in)
194  {
195  std::string native_encoded;
198  serialize(&native_encoded, in);
199  goby::util::hex_encode(native_encoded, out);
200  }
201 
202  static void parse(const std::string& in, google::protobuf::Message* out)
203  {
204  std::string native_encoded;
205  goby::util::hex_decode(in, &native_encoded);
206  goby::moos::MOOSTranslation<goby::moos::protobuf::TranslatorEntry::
207  TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::parse(native_encoded,
208  out);
209  }
210 };
211 
215 {
216  public:
217  static void serialize(std::string* out, const google::protobuf::Message& msg)
218  {
219  std::string header =
220  goby::moos::MAGIC_PROTOBUF_HEADER + "[" + msg.GetDescriptor()->full_name() + "] ";
222  *out = header + *out;
223  }
224 
225  static void parse(const std::string& in, google::protobuf::Message* msg)
226  {
227  if (in.size() > goby::moos::MAGIC_PROTOBUF_HEADER.size() &&
228  in.substr(0, goby::moos::MAGIC_PROTOBUF_HEADER.size()) ==
230  {
231  size_t end_bracket_pos = in.find(']');
232 
233  if (end_bracket_pos == std::string::npos)
234  throw(std::runtime_error(
235  "Incorrectly formatted protobuf message passed to MOOSTranslation<" +
237  prefix_technique) +
238  ">::parse."));
239 
240  std::string name =
241  in.substr(goby::moos::MAGIC_PROTOBUF_HEADER.size() + 1,
242  end_bracket_pos - 1 - goby::moos::MAGIC_PROTOBUF_HEADER.size());
243  if (name != msg->GetDescriptor()->full_name())
244  throw(std::runtime_error(
245  "Wrong Protobuf type passed to MOOSTranslation<" +
247  prefix_technique) +
248  ">::parse. Expected: " + msg->GetDescriptor()->full_name() +
249  ", received: " + name));
250 
251  if (in.size() > end_bracket_pos + 2)
252  goby::moos::MOOSTranslation<base_technique>::parse(in.substr(end_bracket_pos + 2),
253  msg);
254  else
255  msg->Clear();
256  }
257  else
258  {
260  }
261  }
262 
263  static std::shared_ptr<google::protobuf::Message> dynamic_parse(const std::string& in)
264  {
265  if (in.size() > goby::moos::MAGIC_PROTOBUF_HEADER.size() &&
266  in.substr(0, goby::moos::MAGIC_PROTOBUF_HEADER.size()) ==
268  {
269  size_t end_bracket_pos = in.find(']');
270 
271  if (end_bracket_pos == std::string::npos)
272  throw(std::runtime_error(
273  "Incorrectly formatted protobuf message passed to MOOSTranslation<" +
275  prefix_technique) +
276  ">::dynamic_parse."));
277 
278  std::string name =
279  in.substr(goby::moos::MAGIC_PROTOBUF_HEADER.size() + 1,
280  end_bracket_pos - 1 - goby::moos::MAGIC_PROTOBUF_HEADER.size());
281 
282  try
283  {
284  // dccl::DynamicProtobufManager appears not to be thread safe
285  const std::lock_guard<std::mutex> lock(goby::moos::dynamic_parse_mutex);
286 
287  auto return_message = dccl::DynamicProtobufManager::new_protobuf_message<
288  std::shared_ptr<google::protobuf::Message>>(name);
289  if (in.size() > end_bracket_pos + 1)
291  in.substr(end_bracket_pos + 1), return_message.get());
292  return return_message;
293  }
294  catch (std::exception& e)
295  {
296  return std::shared_ptr<google::protobuf::Message>();
297  }
298  }
299  else
300  {
301  return std::shared_ptr<google::protobuf::Message>();
302  }
303  }
304 };
305 
306 template <>
307 class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>
308  : public MOOSPrefixTranslation<
309  protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT,
310  protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>
311 {
312 };
313 template <>
314 class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>
315  : public MOOSPrefixTranslation<
316  protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED,
317  protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>
318 {
319 };
320 template <>
321 class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>
322  : public MOOSPrefixTranslation<
323  protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX,
324  protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>
325 {
326 };
327 
328 template <>
329 class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS>
330 {
331  public:
332  static void serialize(std::string* out, const google::protobuf::Message& in,
337  bool use_short_enum = false)
338  {
339  std::stringstream out_ss;
340 
341  const google::protobuf::Descriptor* desc = in.GetDescriptor();
342  const google::protobuf::Reflection* refl = in.GetReflection();
343 
344  int included_fields = 0;
345  for (int i = 0, n = desc->field_count(); i < n; ++i)
346  {
347  const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
348 
349  // leave out unspecified or empty fields
350  if ((!field_desc->is_repeated() && !refl->HasField(in, field_desc)) ||
351  (field_desc->is_repeated() && refl->FieldSize(in, field_desc) == 0))
352  continue;
353 
354  if (included_fields)
355  out_ss << ",";
356  ++included_fields;
357 
358  const std::string& field_name = field_desc->name();
359 
360  switch (field_desc->cpp_type())
361  {
362  default:
363  out_ss << to_moos_comma_equals_string_field(in, field_desc, true,
364  use_short_enum);
365  break;
366 
367  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
368  if (field_desc->is_repeated())
369  {
370  for (int k = 0, o = field_desc->message_type()->field_count(); k < o; ++k)
371  {
372  if (k)
373  out_ss << ",";
374  out_ss << field_name << "_"
375  << field_desc->message_type()->field(k)->name() << "={";
376  for (int j = 0, m = refl->FieldSize(in, field_desc); j < m; ++j)
377  {
378  if (j)
379  out_ss << ",";
380  const google::protobuf::Message& embedded_msg =
381  refl->GetRepeatedMessage(in, field_desc, j);
382  out_ss << to_moos_comma_equals_string_field(
383  embedded_msg, embedded_msg.GetDescriptor()->field(k), false,
384  use_short_enum);
385  }
386  out_ss << "}";
387  }
388  }
389 
390  else
391  {
392  for (int k = 0, o = field_desc->message_type()->field_count(); k < o; ++k)
393  {
394  if (k)
395  out_ss << ",";
396  out_ss << field_name << "_"
397  << field_desc->message_type()->field(k)->name() << "=";
398  const google::protobuf::Message& embedded_msg =
399  refl->GetMessage(in, field_desc);
400  out_ss << to_moos_comma_equals_string_field(
401  embedded_msg, embedded_msg.GetDescriptor()->field(k), false,
402  use_short_enum);
403  }
404  }
405 
406  break;
407  }
408  }
409 
410  std::map<int, std::string> additional_values = run_serialize_algorithms(in, algorithms);
411  for (const auto& additional_value : additional_values)
412  {
413  out_ss << ",";
414 
415  std::string key;
416  int primary_field = 0;
417  for (const auto& algorithm : algorithms)
418  {
419  if (algorithm.output_virtual_field() == additional_value.first)
420  {
421  if (!key.empty())
422  key += "+";
423 
424  key += algorithm.name();
425  primary_field = algorithm.primary_field();
426  }
427  }
428  key += "(" + desc->FindFieldByNumber(primary_field)->name() + ")";
429 
430  out_ss << key << "=" << additional_value.second;
431  }
432 
433  *out = out_ss.str();
434  }
435 
436  static void parse(std::string in, google::protobuf::Message* out,
441  bool use_short_enum = false)
442  {
443  const google::protobuf::Descriptor* desc = out->GetDescriptor();
444  const google::protobuf::Reflection* refl = out->GetReflection();
445 
446  boost::to_lower(in);
447 
448  for (int i = 0, n = desc->field_count(); i < n; ++i)
449  {
450  const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
451 
452  switch (field_desc->cpp_type())
453  {
454  default:
455  {
456  std::string val;
457 
458  if (goby::moos::val_from_string(val, in, field_desc->name()))
459  {
460  // run algorithms
461  for (const auto& algorithm : algorithms)
462  {
464 
465  if (algorithm.primary_field() == field_desc->number())
467  ->run_algorithm(
468  algorithm.name(), extract_val,
469  std::vector<goby::moos::transitional::DCCLMessageVal>());
470 
471  val = std::string(extract_val);
472  }
473 
474  std::vector<std::string> vals;
475  boost::split(vals, val, boost::is_any_of(","));
476  from_moos_comma_equals_string_field(out, field_desc, vals, 0,
477  use_short_enum);
478  }
479  }
480  break;
481 
482  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
483  if (field_desc->is_repeated())
484  {
485  for (int k = 0, o = field_desc->message_type()->field_count(); k < o; ++k)
486  {
487  std::string val;
489  val, in,
490  field_desc->name() + "_" +
491  field_desc->message_type()->field(k)->name()))
492  {
493  std::vector<std::string> vals;
494  boost::split(vals, val, boost::is_any_of(","));
495 
496  for (int j = 0, m = vals.size(); j < m; ++j)
497  {
498  google::protobuf::Message* embedded_msg =
499  (refl->FieldSize(*out, field_desc) < j + 1)
500  ? refl->AddMessage(out, field_desc)
501  : refl->MutableRepeatedMessage(out, field_desc, j);
502  from_moos_comma_equals_string_field(
503  embedded_msg, embedded_msg->GetDescriptor()->field(k), vals,
504  j, use_short_enum);
505  }
506  }
507  }
508  }
509  else
510  {
511  for (int k = 0, o = field_desc->message_type()->field_count(); k < o; ++k)
512  {
513  std::string val;
515  val, in,
516  field_desc->name() + "_" +
517  field_desc->message_type()->field(k)->name()))
518  {
519  std::vector<std::string> vals;
520  boost::split(vals, val, boost::is_any_of(","));
521 
522  google::protobuf::Message* embedded_msg =
523  refl->MutableMessage(out, field_desc);
524  from_moos_comma_equals_string_field(
525  embedded_msg, embedded_msg->GetDescriptor()->field(k), vals, 0,
526  use_short_enum);
527  }
528  }
529  }
530  break;
531  }
532  }
533  }
534 
535  private:
536  static std::string
537  to_moos_comma_equals_string_field(const google::protobuf::Message& proto_msg,
538  const google::protobuf::FieldDescriptor* field_desc,
539  bool write_key = true, bool use_short_enum = false)
540  {
541  const google::protobuf::Reflection* refl = proto_msg.GetReflection();
542 
543  std::stringstream out;
544  const std::string& field_name = field_desc->name();
545 
546  if (field_desc->is_repeated())
547  {
548  if (write_key)
549  out << field_name << "={";
550 
551  for (int j = 0, m = refl->FieldSize(proto_msg, field_desc); j < m; ++j)
552  {
553  if (j)
554  out << ",";
555 
556  switch (field_desc->cpp_type())
557  {
558  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
559  out << goby::util::hex_encode(
560  refl->GetRepeatedMessage(proto_msg, field_desc, j).SerializeAsString());
561  break;
562 
563  case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
564  out << refl->GetRepeatedInt32(proto_msg, field_desc, j);
565  break;
566 
567  case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
568  out << refl->GetRepeatedInt64(proto_msg, field_desc, j);
569  break;
570 
571  case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
572  out << refl->GetRepeatedUInt32(proto_msg, field_desc, j);
573  break;
574 
575  case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
576  out << refl->GetRepeatedUInt64(proto_msg, field_desc, j);
577  break;
578 
579  case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
580  out << std::boolalpha << refl->GetRepeatedBool(proto_msg, field_desc, j);
581  break;
582 
583  case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
584  if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_STRING)
585  out << refl->GetRepeatedString(proto_msg, field_desc, j);
586  else if (field_desc->type() ==
587  google::protobuf::FieldDescriptor::TYPE_BYTES)
588  out << goby::util::hex_encode(
589  refl->GetRepeatedString(proto_msg, field_desc, j));
590  break;
591 
592  case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
593  out << std::setprecision(std::numeric_limits<float>::digits10)
594  << refl->GetRepeatedFloat(proto_msg, field_desc, j);
595  break;
596 
597  case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
598  out << std::setprecision(std::numeric_limits<double>::digits10)
599  << refl->GetRepeatedDouble(proto_msg, field_desc, j);
600  break;
601 
602  case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
603  out << ((use_short_enum)
605  refl->GetRepeatedEnum(proto_msg, field_desc, j)->name(),
606  field_name)
607  : refl->GetRepeatedEnum(proto_msg, field_desc, j)->name());
608 
609  break;
610  }
611  }
612  if (write_key)
613  out << "}";
614  }
615  else
616  {
617  if (write_key)
618  out << field_name << "=";
619  switch (field_desc->cpp_type())
620  {
621  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
622  out << goby::util::hex_encode(
623  refl->GetMessage(proto_msg, field_desc).SerializeAsString());
624  break;
625 
626  case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
627  out << refl->GetInt32(proto_msg, field_desc);
628  break;
629 
630  case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
631  out << refl->GetInt64(proto_msg, field_desc);
632  break;
633 
634  case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
635  out << refl->GetUInt32(proto_msg, field_desc);
636  break;
637 
638  case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
639  out << refl->GetUInt64(proto_msg, field_desc);
640  break;
641 
642  case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
643  out << std::boolalpha << refl->GetBool(proto_msg, field_desc);
644  break;
645 
646  case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
647  if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_STRING)
648  out << refl->GetString(proto_msg, field_desc);
649  else if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_BYTES)
650  out << goby::util::hex_encode(refl->GetString(proto_msg, field_desc));
651  break;
652 
653  case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
654  out << std::setprecision(std::numeric_limits<float>::digits10)
655  << refl->GetFloat(proto_msg, field_desc);
656  break;
657 
658  case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
659  out << std::setprecision(std::numeric_limits<double>::digits10)
660  << refl->GetDouble(proto_msg, field_desc);
661  break;
662 
663  case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
664  out << ((use_short_enum)
665  ? strip_name_from_enum(refl->GetEnum(proto_msg, field_desc)->name(),
666  field_name)
667  : refl->GetEnum(proto_msg, field_desc)->name());
668  break;
669  }
670  }
671  return out.str();
672  }
673  static void from_moos_comma_equals_string_field(
674  google::protobuf::Message* proto_msg, const google::protobuf::FieldDescriptor* field_desc,
675  const std::vector<std::string>& values, int value_key = 0, bool use_short_enum = false)
676  {
677  if (values.size() == 0)
678  return;
679 
680  const google::protobuf::Reflection* refl = proto_msg->GetReflection();
681  if (field_desc->is_repeated())
682  {
683  for (const auto& v : values)
684  {
685  switch (field_desc->cpp_type())
686  {
687  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
688  refl->AddMessage(proto_msg, field_desc)
690  break;
691 
692  case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
693  refl->AddInt32(proto_msg, field_desc,
694  goby::util::as<google::protobuf::int32>(v));
695  break;
696 
697  case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
698  refl->AddInt64(proto_msg, field_desc,
699  goby::util::as<google::protobuf::int64>(v));
700  break;
701 
702  case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
703  refl->AddUInt32(proto_msg, field_desc,
704  goby::util::as<google::protobuf::uint32>(v));
705  break;
706 
707  case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
708  refl->AddUInt64(proto_msg, field_desc,
709  goby::util::as<google::protobuf::uint64>(v));
710  break;
711 
712  case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
713  refl->AddBool(proto_msg, field_desc, goby::util::as<bool>(v));
714  break;
715 
716  case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
717  if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_STRING)
718  refl->AddString(proto_msg, field_desc, v);
719  else if (field_desc->type() ==
720  google::protobuf::FieldDescriptor::TYPE_BYTES)
721  refl->AddString(proto_msg, field_desc, goby::util::hex_decode(v));
722  break;
723 
724  case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
725  refl->AddFloat(proto_msg, field_desc, goby::util::as<float>(v));
726  break;
727 
728  case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
729  refl->AddDouble(proto_msg, field_desc, goby::util::as<double>(v));
730  break;
731 
732  case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
733  {
734  std::string enum_value =
735  ((use_short_enum) ? add_name_to_enum(v, field_desc->name()) : v);
736 
737  const google::protobuf::EnumValueDescriptor* enum_desc =
738  field_desc->enum_type()->FindValueByName(enum_value);
739 
740  // try upper case
741  if (!enum_desc)
742  enum_desc = field_desc->enum_type()->FindValueByName(
743  boost::algorithm::to_upper_copy(enum_value));
744  // try lower case
745  if (!enum_desc)
746  enum_desc = field_desc->enum_type()->FindValueByName(
747  boost::algorithm::to_lower_copy(enum_value));
748 
749  if (enum_desc)
750  refl->AddEnum(proto_msg, field_desc, enum_desc);
751  }
752  break;
753  }
754  }
755  }
756  else
757  {
758  const std::string& v = values[value_key];
759  switch (field_desc->cpp_type())
760  {
761  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
762  refl->MutableMessage(proto_msg, field_desc)
764  break;
765 
766  case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
767  refl->SetInt32(proto_msg, field_desc,
768  goby::util::as<google::protobuf::int32>(v));
769  break;
770 
771  case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
772  refl->SetInt64(proto_msg, field_desc,
773  goby::util::as<google::protobuf::int64>(v));
774  break;
775 
776  case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
777  refl->SetUInt32(proto_msg, field_desc,
778  goby::util::as<google::protobuf::uint32>(v));
779  break;
780 
781  case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
782  refl->SetUInt64(proto_msg, field_desc,
783  goby::util::as<google::protobuf::uint64>(v));
784  break;
785 
786  case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
787  refl->SetBool(proto_msg, field_desc, goby::util::as<bool>(v));
788  break;
789 
790  case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
791  if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_STRING)
792  refl->SetString(proto_msg, field_desc, v);
793  else if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_BYTES)
794  refl->SetString(proto_msg, field_desc, goby::util::hex_decode(v));
795  break;
796 
797  case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
798  refl->SetFloat(proto_msg, field_desc, goby::util::as<float>(v));
799  break;
800 
801  case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
802  refl->SetDouble(proto_msg, field_desc, goby::util::as<double>(v)); /* */
803  break;
804 
805  case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
806  {
807  std::string enum_value =
808  ((use_short_enum) ? add_name_to_enum(v, field_desc->name()) : v);
809 
810  const google::protobuf::EnumValueDescriptor* enum_desc =
811  field_desc->enum_type()->FindValueByName(enum_value);
812 
813  // try upper case
814  if (!enum_desc)
815  enum_desc = field_desc->enum_type()->FindValueByName(
816  boost::algorithm::to_upper_copy(enum_value));
817  // try lower case
818  if (!enum_desc)
819  enum_desc = field_desc->enum_type()->FindValueByName(
820  boost::algorithm::to_lower_copy(enum_value));
821 
822  if (enum_desc)
823  refl->SetEnum(proto_msg, field_desc, enum_desc);
824  }
825  break;
826  }
827  }
828  }
829 };
830 
831 template <> class MOOSTranslation<protobuf::TranslatorEntry::TECHNIQUE_FORMAT>
832 {
833  public:
834  struct RepeatedFieldKey
835  {
836  int field;
837  int index;
838  };
839 
840  static void serialize(std::string* out, const google::protobuf::Message& in,
843  const std::string& format, const std::string& repeated_delimiter,
844  bool use_short_enum = false)
845  {
846  std::string mutable_format = format;
847 
848  const google::protobuf::Descriptor* desc = in.GetDescriptor();
849  const google::protobuf::Reflection* refl = in.GetReflection();
850 
851  int max_field_number = 1;
852  for (int i = 1, n = desc->field_count(); i < n; ++i)
853  {
854  const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
855  if (field_desc->number() > max_field_number)
856  max_field_number = field_desc->number();
857  }
858 
859  // run algorithms
860  std::map<int, std::string> modified_values = run_serialize_algorithms(in, algorithms);
861 
862  for (const auto& modified_value : modified_values)
863  {
864  if (modified_value.first > max_field_number)
865  max_field_number = modified_value.first;
866  }
867 
868  std::string mutable_format_temp = mutable_format;
869 
870  std::regex moos_index_regex("%([0-9\\.]+:)+[0-9\\.]+%");
871  for (std::sregex_iterator
872  it(mutable_format.begin(), mutable_format.end(), moos_index_regex),
873  end;
874  it != end; ++it)
875  {
876  std::string match = (*it)[0];
877 
878  boost::trim_if(match, boost::is_any_of("%"));
879  std::vector<std::string> subfields;
880  boost::split(subfields, match, boost::is_any_of(":"));
881 
882  ++max_field_number;
883 
884  const google::protobuf::FieldDescriptor* field_desc = nullptr;
885  const google::protobuf::Reflection* sub_refl = refl;
886  const google::protobuf::Message* sub_message = &in;
887 
888  for (int i = 0, n = subfields.size() - 1; i < n; ++i)
889  {
890  std::vector<std::string> field_and_index;
891  boost::split(field_and_index, subfields[i], boost::is_any_of("."));
892 
893  field_desc = sub_message->GetDescriptor()->FindFieldByNumber(
894  goby::util::as<int>(field_and_index[0]));
895  if (!field_desc ||
896  field_desc->cpp_type() != google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
897  {
898  throw(std::runtime_error(
899  "Invalid ':' syntax given for format: " + match +
900  ". All field indices except the last must be embedded messages"));
901  }
902  if (field_desc->is_repeated() && field_and_index.size() != 2)
903  {
904  throw(std::runtime_error("Invalid '.' syntax given for format: " + match +
905  ". Repeated message, but no valid index given. E.g., "
906  "use '3.4' for index 4 of field 3."));
907  }
908 
909  sub_message =
910  (field_desc->is_repeated())
911  ? &sub_refl->GetRepeatedMessage(*sub_message, field_desc,
912  goby::util::as<int>(field_and_index[1]))
913  : &sub_refl->GetMessage(*sub_message, field_desc);
914  sub_refl = sub_message->GetReflection();
915  }
916 
917  serialize(&modified_values[max_field_number], *sub_message, algorithms,
918  "%" + subfields[subfields.size() - 1] + "%", repeated_delimiter,
919  use_short_enum);
920 
921  boost::replace_all(
922  mutable_format_temp, std::string("%" + match + "%"),
923  std::string("%" + goby::util::as<std::string>(max_field_number) + "%"));
924  }
925 
926  mutable_format = mutable_format_temp;
927 
928  std::map<int, RepeatedFieldKey> indexed_repeated_fields;
929 
930  std::regex repeated_field_regex("%[0-9]+\\.[0-9]+%");
931  for (std::sregex_iterator
932  it(mutable_format.begin(), mutable_format.end(), repeated_field_regex),
933  end;
934  it != end; ++it)
935  {
936  std::string match = (*it)[0];
937  boost::trim_if(match, boost::is_any_of("%"));
938 
939  ++max_field_number;
940 
941  boost::replace_all(
942  mutable_format_temp, std::string("%" + match + "%"),
943  std::string("%" + goby::util::as<std::string>(max_field_number) + "%"));
944 
945  RepeatedFieldKey key;
946 
947  std::vector<std::string> field_and_index;
948  boost::split(field_and_index, match, boost::is_any_of("."));
949 
950  key.field = goby::util::as<int>(field_and_index[0]);
951  key.index = goby::util::as<int>(field_and_index[1]);
952 
953  indexed_repeated_fields[max_field_number] = key;
954  }
955 
956  mutable_format = mutable_format_temp;
957 
958  boost::format out_format(mutable_format);
959  out_format.exceptions(boost::io::all_error_bits ^
960  (boost::io::too_many_args_bit | boost::io::too_few_args_bit));
961 
962  for (int i = 1; i <= max_field_number; ++i)
963  {
964  bool is_indexed_repeated_field = indexed_repeated_fields.count(i);
965 
966  const google::protobuf::FieldDescriptor* field_desc = desc->FindFieldByNumber(
967  is_indexed_repeated_field ? indexed_repeated_fields[i].field : i);
968  std::map<int, std::string>::const_iterator mod_it = modified_values.find(i);
969  if (field_desc)
970  {
971  if (field_desc->is_repeated())
972  {
973  int start = (is_indexed_repeated_field) ? indexed_repeated_fields[i].index : 0;
974  int end = (is_indexed_repeated_field) ? indexed_repeated_fields[i].index + 1
975  : refl->FieldSize(in, field_desc);
976 
977  std::stringstream out_repeated;
978  for (int j = start; j < end; ++j)
979  {
980  if (j && !is_indexed_repeated_field)
981  out_repeated << repeated_delimiter;
982  switch (field_desc->cpp_type())
983  {
984  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
985  out_repeated << goby::util::hex_encode(
986  refl->GetRepeatedMessage(in, field_desc, j)
987  .SerializeAsString());
988  break;
989 
990  case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
991  out_repeated << ((j < refl->FieldSize(in, field_desc))
992  ? refl->GetRepeatedInt32(in, field_desc, j)
993  : std::numeric_limits<std::int32_t>::max());
994 
995  break;
996 
997  case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
998  out_repeated << ((j < refl->FieldSize(in, field_desc))
999  ? refl->GetRepeatedInt64(in, field_desc, j)
1000  : std::numeric_limits<std::int64_t>::max());
1001  break;
1002 
1003  case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
1004  out_repeated << ((j < refl->FieldSize(in, field_desc))
1005  ? refl->GetRepeatedUInt32(in, field_desc, j)
1006  : std::numeric_limits<std::uint32_t>::max());
1007  break;
1008 
1009  case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
1010  out_repeated << ((j < refl->FieldSize(in, field_desc))
1011  ? refl->GetRepeatedUInt64(in, field_desc, j)
1012  : std::numeric_limits<std::uint64_t>::max());
1013  break;
1014 
1015  case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
1016  out_repeated << std::boolalpha
1017  << ((j < refl->FieldSize(in, field_desc))
1018  ? refl->GetRepeatedBool(in, field_desc, j)
1019  : field_desc->default_value_bool());
1020  break;
1021 
1022  case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
1023  if (field_desc->type() ==
1024  google::protobuf::FieldDescriptor::TYPE_STRING)
1025  out_repeated
1026  << ((j < refl->FieldSize(in, field_desc))
1027  ? refl->GetRepeatedString(in, field_desc, j)
1028  : field_desc->default_value_string());
1029  else if (field_desc->type() ==
1030  google::protobuf::FieldDescriptor::TYPE_BYTES)
1031  out_repeated << goby::util::hex_encode(
1032  ((j < refl->FieldSize(in, field_desc))
1033  ? refl->GetRepeatedString(in, field_desc, j)
1034  : field_desc->default_value_string()));
1035  break;
1036 
1037  case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
1038  out_repeated
1039  << std::setprecision(std::numeric_limits<float>::digits10)
1040  << ((j < refl->FieldSize(in, field_desc))
1041  ? refl->GetRepeatedFloat(in, field_desc, j)
1042  : std::numeric_limits<float>::quiet_NaN());
1043  break;
1044 
1045  case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
1046  out_repeated
1047  << std::setprecision(std::numeric_limits<double>::digits10)
1048  << ((j < refl->FieldSize(in, field_desc))
1049  ? refl->GetRepeatedDouble(in, field_desc, j)
1050  : std::numeric_limits<double>::quiet_NaN());
1051  break;
1052 
1053  case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
1054  {
1055  const google::protobuf::EnumValueDescriptor* enum_val =
1056  ((j < refl->FieldSize(in, field_desc))
1057  ? refl->GetRepeatedEnum(in, field_desc, j)
1058  : field_desc->default_value_enum());
1059  out_repeated
1060  << ((use_short_enum) ? strip_name_from_enum(enum_val->name(),
1061  field_desc->name())
1062  : enum_val->name());
1063  }
1064  break;
1065  }
1066  }
1067  out_format % out_repeated.str();
1068  }
1069  else
1070  {
1071  switch (field_desc->cpp_type())
1072  {
1073  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
1074  out_format % goby::util::hex_encode(
1075  refl->GetMessage(in, field_desc).SerializeAsString());
1076  break;
1077 
1078  case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
1079  out_format % refl->GetInt32(in, field_desc);
1080  break;
1081 
1082  case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
1083  out_format % refl->GetInt64(in, field_desc);
1084  break;
1085 
1086  case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
1087  out_format % refl->GetUInt32(in, field_desc);
1088  break;
1089 
1090  case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
1091  out_format % refl->GetUInt64(in, field_desc);
1092  break;
1093 
1094  case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
1095  out_format % goby::util::as<std::string>(refl->GetBool(in, field_desc));
1096  break;
1097 
1098  case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
1099  if (field_desc->type() ==
1100  google::protobuf::FieldDescriptor::TYPE_STRING)
1101  out_format % refl->GetString(in, field_desc);
1102  else if (field_desc->type() ==
1103  google::protobuf::FieldDescriptor::TYPE_BYTES)
1104  out_format %
1105  goby::util::hex_encode(refl->GetString(in, field_desc));
1106  break;
1107 
1108  case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
1109  out_format % boost::io::group(std::setprecision(
1110  std::numeric_limits<float>::digits10),
1111  refl->GetFloat(in, field_desc));
1112  break;
1113 
1114  case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
1115  out_format %
1117  std::setprecision(std::numeric_limits<double>::digits10),
1118  refl->GetDouble(in, field_desc));
1119  break;
1120 
1121  case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
1122 
1123  out_format %
1124  ((use_short_enum)
1125  ? strip_name_from_enum(refl->GetEnum(in, field_desc)->name(),
1126  field_desc->name())
1127  : refl->GetEnum(in, field_desc)->name());
1128  break;
1129  }
1130  }
1131  }
1132  else if (mod_it != modified_values.end())
1133  {
1134  out_format % mod_it->second;
1135  }
1136  else
1137  {
1138  out_format % "unknown";
1139  }
1140  }
1141 
1142  *out = out_format.str();
1143  }
1144 
1145  static void parse(const std::string& in, google::protobuf::Message* out, std::string format,
1146  const std::string& repeated_delimiter,
1151  bool use_short_enum = false)
1152  {
1153  const google::protobuf::Descriptor* desc = out->GetDescriptor();
1154  const google::protobuf::Reflection* refl = out->GetReflection();
1155  boost::to_lower(format);
1156  std::string str = in;
1157  std::string lower_str = boost::to_lower_copy(in);
1158 
1159  // goby::glog.is(DEBUG1) && goby::glog << "Format: " << format << std::endl;
1160  // goby::glog.is(DEBUG1) && goby::glog << "String: " << str << std::endl;
1161  // goby::glog.is(DEBUG1) && goby::glog << "Lower String: " << lower_str << std::endl;
1162 
1163  std::string::const_iterator i = format.begin();
1164 
1165  while (i != format.end())
1166  {
1167  if (*i == '%')
1168  {
1169  ++i; // now *i is the conversion specifier
1170  std::string specifier;
1171  while (*i != '%') specifier += *i++;
1172 
1173  ++i; // now *i is the next separator
1174  std::string extract = str.substr(0, lower_str.find(*i));
1175 
1176  if (specifier.find(':') != std::string::npos)
1177  {
1178  std::vector<std::string> subfields;
1179  boost::split(subfields, specifier, boost::is_any_of(":"));
1180  const google::protobuf::FieldDescriptor* field_desc = nullptr;
1181  const google::protobuf::Reflection* sub_refl = refl;
1182  google::protobuf::Message* sub_message = out;
1183 
1184  for (int i = 0, n = subfields.size() - 1; i < n; ++i)
1185  {
1186  std::vector<std::string> field_and_index;
1187  boost::split(field_and_index, subfields[i], boost::is_any_of("."));
1188 
1189  field_desc = sub_message->GetDescriptor()->FindFieldByNumber(
1190  goby::util::as<int>(field_and_index[0]));
1191  if (!field_desc || field_desc->cpp_type() !=
1192  google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
1193  {
1194  throw(std::runtime_error(
1195  "Invalid ':' syntax given for format: " + specifier +
1196  ". All field indices except the last must be singular embedded "
1197  "messages"));
1198  }
1199 
1200  int index = -1;
1201  if (field_desc->is_repeated())
1202  {
1203  if (field_and_index.size() != 2)
1204  throw(std::runtime_error(
1205  "Invalid '.' syntax given for format: " + specifier +
1206  ". Repeated message, but no valid index given. E.g., use '3.4' "
1207  "for index 4 of field 3."));
1208  index = goby::util::as<int>(field_and_index.at(1));
1209  while (sub_refl->FieldSize(*sub_message, field_desc) <= index)
1210  sub_refl->AddMessage(sub_message, field_desc);
1211  }
1212 
1213  sub_message =
1214  (field_desc->is_repeated())
1215  ? sub_refl->MutableRepeatedMessage(sub_message, field_desc, index)
1216  : sub_refl->MutableMessage(sub_message, field_desc);
1217  sub_refl = sub_message->GetReflection();
1218  }
1219 
1220  parse(extract, sub_message, "%" + subfields[subfields.size() - 1] + "%",
1221  repeated_delimiter, algorithms, use_short_enum);
1222  }
1223  else
1224  {
1225  try
1226  {
1227  std::vector<std::string> field_and_index;
1228  boost::split(field_and_index, specifier, boost::is_any_of("."));
1229 
1230  int field_index = boost::lexical_cast<int>(field_and_index[0]);
1231  bool is_indexed_repeated_field = field_and_index.size() == 2;
1232 
1233  int value_index = 0;
1234  if (is_indexed_repeated_field)
1235  value_index = boost::lexical_cast<int>(field_and_index[1]);
1236 
1237  const google::protobuf::FieldDescriptor* field_desc =
1238  desc->FindFieldByNumber(field_index);
1239 
1240  if (!field_desc)
1241  throw(std::runtime_error("Bad field: " + specifier +
1242  " not in message " + desc->full_name()));
1243 
1244  // run algorithms
1245  for (const auto& algorithm : algorithms)
1246  {
1247  goby::moos::transitional::DCCLMessageVal extract_val(extract);
1248 
1249  if (algorithm.primary_field() == field_index)
1251  ->run_algorithm(
1252  algorithm.name(), extract_val,
1253  std::vector<goby::moos::transitional::DCCLMessageVal>());
1254 
1255  extract = std::string(extract_val);
1256  }
1257 
1258  std::vector<std::string> parts;
1259  if (is_indexed_repeated_field || !field_desc->is_repeated())
1260  parts.push_back(extract);
1261  else
1262  boost::split(parts, extract, boost::is_any_of(repeated_delimiter));
1263 
1264  for (auto& part : parts)
1265  {
1266  switch (field_desc->cpp_type())
1267  {
1268  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
1269  if (is_indexed_repeated_field)
1270  {
1271  while (refl->FieldSize(*out, field_desc) <= value_index)
1272  refl->AddMessage(out, field_desc);
1273  }
1274  field_desc->is_repeated()
1275  ? (is_indexed_repeated_field
1276  ? refl->MutableRepeatedMessage(out, field_desc,
1277  value_index)
1279  : refl->AddMessage(out, field_desc)
1280  ->ParseFromString(
1281  goby::util::hex_decode(part)))
1282  : refl->MutableMessage(out, field_desc)
1284  break;
1285 
1286  case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
1287  if (is_indexed_repeated_field)
1288  {
1289  while (refl->FieldSize(*out, field_desc) <= value_index)
1290  refl->AddInt32(out, field_desc,
1291  field_desc->default_value_int32());
1292  }
1293  field_desc->is_repeated()
1294  ? (is_indexed_repeated_field
1295  ? refl->SetRepeatedInt32(
1296  out, field_desc, value_index,
1297  goby::util::as<google::protobuf::int32>(part))
1298  : refl->AddInt32(
1299  out, field_desc,
1300  goby::util::as<google::protobuf::int32>(part)))
1301  : refl->SetInt32(
1302  out, field_desc,
1303  goby::util::as<google::protobuf::int32>(part));
1304  break;
1305 
1306  case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
1307  if (is_indexed_repeated_field)
1308  {
1309  while (refl->FieldSize(*out, field_desc) <= value_index)
1310  refl->AddInt64(out, field_desc,
1311  field_desc->default_value_int64());
1312  }
1313  field_desc->is_repeated()
1314  ? (is_indexed_repeated_field
1315  ? refl->SetRepeatedInt64(
1316  out, field_desc, value_index,
1317  goby::util::as<google::protobuf::int64>(part))
1318  : refl->AddInt64(
1319  out, field_desc,
1320  goby::util::as<google::protobuf::int64>(part)))
1321  : refl->SetInt64(
1322  out, field_desc,
1323  goby::util::as<google::protobuf::int64>(part));
1324  break;
1325 
1326  case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
1327  if (is_indexed_repeated_field)
1328  {
1329  while (refl->FieldSize(*out, field_desc) <= value_index)
1330  refl->AddUInt32(out, field_desc,
1331  field_desc->default_value_uint32());
1332  }
1333  field_desc->is_repeated()
1334  ? (is_indexed_repeated_field
1335  ? refl->SetRepeatedUInt32(
1336  out, field_desc, value_index,
1337  goby::util::as<google::protobuf::uint32>(part))
1338  : refl->AddUInt32(
1339  out, field_desc,
1340  goby::util::as<google::protobuf::uint32>(
1341  part)))
1342  : refl->SetUInt32(
1343  out, field_desc,
1344  goby::util::as<google::protobuf::uint32>(part));
1345  break;
1346 
1347  case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
1348  if (is_indexed_repeated_field)
1349  {
1350  while (refl->FieldSize(*out, field_desc) <= value_index)
1351  refl->AddUInt64(out, field_desc,
1352  field_desc->default_value_uint64());
1353  }
1354  field_desc->is_repeated()
1355  ? (is_indexed_repeated_field
1356  ? refl->SetRepeatedUInt64(
1357  out, field_desc, value_index,
1358  goby::util::as<google::protobuf::uint64>(part))
1359  : refl->AddUInt64(
1360  out, field_desc,
1361  goby::util::as<google::protobuf::uint64>(
1362  part)))
1363  : refl->SetUInt64(
1364  out, field_desc,
1365  goby::util::as<google::protobuf::uint64>(part));
1366  break;
1367 
1368  case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
1369  if (is_indexed_repeated_field)
1370  {
1371  while (refl->FieldSize(*out, field_desc) <= value_index)
1372  refl->AddBool(out, field_desc,
1373  field_desc->default_value_bool());
1374  }
1375  field_desc->is_repeated()
1376  ? (is_indexed_repeated_field
1377  ? refl->SetRepeatedBool(out, field_desc, value_index,
1378  goby::util::as<bool>(part))
1379  : refl->AddBool(out, field_desc,
1380  goby::util::as<bool>(part)))
1381  : refl->SetBool(out, field_desc,
1382  goby::util::as<bool>(part));
1383  break;
1384 
1385  case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
1386  if (is_indexed_repeated_field)
1387  {
1388  while (refl->FieldSize(*out, field_desc) <= value_index)
1389  refl->AddString(out, field_desc,
1390  field_desc->default_value_string());
1391  }
1392  field_desc->is_repeated()
1393  ? (is_indexed_repeated_field
1394  ? refl->SetRepeatedString(out, field_desc,
1395  value_index, part)
1396  : refl->AddString(out, field_desc, part))
1397  : refl->SetString(out, field_desc, part);
1398  break;
1399 
1400  case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
1401  if (is_indexed_repeated_field)
1402  {
1403  while (refl->FieldSize(*out, field_desc) <= value_index)
1404  refl->AddFloat(out, field_desc,
1405  field_desc->default_value_float());
1406  }
1407  field_desc->is_repeated()
1408  ? (is_indexed_repeated_field
1409  ? refl->SetRepeatedFloat(out, field_desc,
1410  value_index,
1411  goby::util::as<float>(part))
1412  : refl->AddFloat(out, field_desc,
1413  goby::util::as<float>(part)))
1414  : refl->SetFloat(out, field_desc,
1415  goby::util::as<float>(part));
1416  break;
1417 
1418  case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
1419  if (is_indexed_repeated_field)
1420  {
1421  while (refl->FieldSize(*out, field_desc) <= value_index)
1422  refl->AddDouble(out, field_desc,
1423  field_desc->default_value_double());
1424  }
1425  field_desc->is_repeated()
1426  ? (is_indexed_repeated_field
1427  ? refl->SetRepeatedDouble(
1428  out, field_desc, value_index,
1429  goby::util::as<double>(part))
1430  : refl->AddDouble(out, field_desc,
1431  goby::util::as<double>(part)))
1432  : refl->SetDouble(out, field_desc,
1433  goby::util::as<double>(part));
1434  break;
1435 
1436  case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
1437  {
1438  if (is_indexed_repeated_field)
1439  {
1440  while (refl->FieldSize(*out, field_desc) <= value_index)
1441  refl->AddEnum(out, field_desc,
1442  field_desc->default_value_enum());
1443  }
1444  std::string enum_value =
1445  ((use_short_enum)
1446  ? add_name_to_enum(part, field_desc->name())
1447  : part);
1448 
1449  const google::protobuf::EnumValueDescriptor* enum_desc =
1450  refl->GetEnum(*out, field_desc)
1451  ->type()
1452  ->FindValueByName(enum_value);
1453 
1454  // try upper case
1455  if (!enum_desc)
1456  enum_desc =
1457  refl->GetEnum(*out, field_desc)
1458  ->type()
1459  ->FindValueByName(boost::to_upper_copy(enum_value));
1460  // try lower case
1461  if (!enum_desc)
1462  enum_desc =
1463  refl->GetEnum(*out, field_desc)
1464  ->type()
1465  ->FindValueByName(boost::to_lower_copy(enum_value));
1466  if (enum_desc)
1467  {
1468  field_desc->is_repeated()
1469  ? (is_indexed_repeated_field
1470  ? refl->SetRepeatedEnum(out, field_desc,
1471  value_index, enum_desc)
1472  : refl->AddEnum(out, field_desc, enum_desc))
1473  : refl->SetEnum(out, field_desc, enum_desc);
1474  }
1475  }
1476  break;
1477  }
1478  }
1479  }
1480  catch (boost::bad_lexical_cast&)
1481  {
1482  throw(std::runtime_error(
1483  "Bad specifier: " + specifier +
1484  ", must be an integer. For message: " + desc->full_name()));
1485  }
1486  }
1487 
1488  // goby::glog.is(DEBUG1) && goby::glog << "field: [" << field_index << "], parts[j]: [" << parts[j] << "]" << std::endl;
1489  }
1490  else
1491  {
1492  // if it's not a %, eat!
1493  std::string::size_type pos_to_remove = lower_str.find(*i) + 1;
1494  lower_str.erase(0, pos_to_remove);
1495  str.erase(0, pos_to_remove);
1496  ++i;
1497  }
1498  }
1499  }
1500 };
1501 } // namespace moos
1502 } // namespace goby
1503 
1505 namespace goby
1506 {
1507 namespace moos
1508 {
1511 
1513 {
1514  const std::lock_guard<std::mutex> lock(moos_technique_mutex);
1515  return moos_technique;
1516 }
1517 
1519 {
1520  const std::lock_guard<std::mutex> lock(moos_technique_mutex);
1521 
1522  if (cfg.has_moos_parser_technique())
1524  else if (cfg.has_use_binary_protobuf())
1526  cfg.use_binary_protobuf()
1529 }
1530 
1531 } // namespace moos
1532 } // namespace goby
1533 
1538 inline bool serialize_for_moos(std::string* out, const google::protobuf::Message& msg)
1539 {
1541  {
1543  goby::moos::MOOSTranslation<goby::moos::protobuf::TranslatorEntry::
1544  TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::serialize(out, msg);
1545  return true;
1547  goby::moos::MOOSTranslation<goby::moos::protobuf::TranslatorEntry::
1548  TECHNIQUE_PROTOBUF_NATIVE_HEX>::serialize(out, msg);
1549  return false;
1551  goby::moos::MOOSTranslation<goby::moos::protobuf::TranslatorEntry::
1552  TECHNIQUE_PROTOBUF_TEXT_FORMAT>::serialize(out, msg);
1553  return false;
1557  serialize(out, msg);
1558  return true;
1560  goby::moos::MOOSTranslation<goby::moos::protobuf::TranslatorEntry::
1561  TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::serialize(out,
1562  msg);
1563  return false;
1567  serialize(out, msg);
1568  return false;
1569  default:
1571  goby::glog
1572  << "Non-PROTOBUF techniques are not supported for 'moos_parser_technique': "
1575  << std::endl;
1576  return false;
1577  }
1578 }
1579 
1584 inline void parse_for_moos(const std::string& in, google::protobuf::Message* msg)
1585 {
1587  {
1589  goby::moos::MOOSTranslation<goby::moos::protobuf::TranslatorEntry::
1590  TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::parse(in, msg);
1591  break;
1595  msg);
1596  break;
1600  msg);
1601  break;
1602 
1604  goby::moos::MOOSTranslation<goby::moos::protobuf::TranslatorEntry::
1605  TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::parse(in,
1606  msg);
1607  break;
1609  goby::moos::MOOSTranslation<goby::moos::protobuf::TranslatorEntry::
1610  TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::parse(in, msg);
1611  break;
1613  goby::moos::MOOSTranslation<goby::moos::protobuf::TranslatorEntry::
1614  TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::parse(in,
1615  msg);
1616  break;
1617  default:
1619  goby::glog
1620  << "Non-PROTOBUF techniques are not supported for 'moos_parser_technique': "
1623  << std::endl;
1624  break;
1625  }
1626 }
1627 
1628 inline std::shared_ptr<google::protobuf::Message> dynamic_parse_for_moos(const std::string& in)
1629 {
1631  {
1635  dynamic_parse(in);
1636 
1640  dynamic_parse(in);
1641 
1645  dynamic_parse(in);
1646 
1647  default:
1649  goby::glog << "Non-PREFIX techniques are not supported when using "
1650  "dynamic_parse_for_moos for 'moos_parser_technique': "
1653  << std::endl;
1654  return std::shared_ptr<google::protobuf::Message>();
1655  }
1656 }
1657 
1658 #endif
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_FORMAT >::RepeatedFieldKey::field
int field
Definition: moos_protobuf_helpers.h:836
google::protobuf::Reflection::SetRepeatedUInt32
virtual void SetRepeatedUInt32(Message *message, const FieldDescriptor *field, int index, uint32 value) const =0
goby::moos::set_moos_technique
void set_moos_technique(const goby::moos::protobuf::GobyMOOSAppConfig &cfg)
Definition: moos_protobuf_helpers.h:1518
google::protobuf::RepeatedPtrField
Definition: message_lite.h:52
google::protobuf::Reflection::SetUInt32
virtual void SetUInt32(Message *message, const FieldDescriptor *field, uint32 value) const =0
google::protobuf::Reflection::GetRepeatedFloat
virtual float GetRepeatedFloat(const Message &message, const FieldDescriptor *field, int index) const =0
goby::moos::moos_technique
goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique moos_technique
goby::moos::moos_technique_mutex
std::mutex moos_technique_mutex
google::protobuf::Reflection::SetRepeatedInt32
virtual void SetRepeatedInt32(Message *message, const FieldDescriptor *field, int index, int32 value) const =0
goby::moos::run_serialize_algorithms
std::map< int, std::string > run_serialize_algorithms(const google::protobuf::Message &in, const google::protobuf::RepeatedPtrField< protobuf::TranslatorEntry::PublishSerializer::Algorithm > &algorithms)
Definition: moos_protobuf_helpers.h:78
goby::moos::protobuf::TranslatorEntry_ParserSerializerTechnique
TranslatorEntry_ParserSerializerTechnique
Definition: translator.pb.h:111
google::protobuf::Reflection::AddInt32
virtual void AddInt32(Message *message, const FieldDescriptor *field, int32 value) const =0
message_val.h
google::protobuf::Reflection::GetRepeatedDouble
virtual double GetRepeatedDouble(const Message &message, const FieldDescriptor *field, int index) const =0
goby::util::FlexOstream::is
bool is(goby::util::logger::Verbosity verbosity)
google::protobuf::Reflection::GetBool
virtual bool GetBool(const Message &message, const FieldDescriptor *field) const =0
goby::moos::MOOSPrefixTranslation
Definition: moos_protobuf_helpers.h:214
goby
The global namespace for the Goby project.
Definition: acomms_constants.h:33
goby::moos::protobuf::GobyMOOSAppConfig::moos_parser_technique
::goby::moos::protobuf::TranslatorEntry_ParserSerializerTechnique moos_parser_technique() const
Definition: goby_moos_app.pb.h:1442
google::protobuf::Reflection::AddFloat
virtual void AddFloat(Message *message, const FieldDescriptor *field, float value) const =0
google::protobuf::Reflection::SetRepeatedDouble
virtual void SetRepeatedDouble(Message *message, const FieldDescriptor *field, int index, double value) const =0
as.h
google::protobuf::Reflection::SetRepeatedUInt64
virtual void SetRepeatedUInt64(Message *message, const FieldDescriptor *field, int index, uint64 value) const =0
goby::moos::protobuf::GobyMOOSAppConfig
Definition: goby_moos_app.pb.h:316
goby::moos::protobuf::GobyMOOSAppConfig::use_binary_protobuf
bool use_binary_protobuf() const
Definition: goby_moos_app.pb.h:1418
goby::moos::strip_name_from_enum
std::string strip_name_from_enum(const std::string &enum_value, const std::string &field_name)
Definition: moos_protobuf_helpers.h:141
goby::util::logger::mutex
std::recursive_mutex mutex
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_FORMAT >::serialize
static void serialize(std::string *out, const google::protobuf::Message &in, const google::protobuf::RepeatedPtrField< protobuf::TranslatorEntry::PublishSerializer::Algorithm > &algorithms, const std::string &format, const std::string &repeated_delimiter, bool use_short_enum=false)
Definition: moos_protobuf_helpers.h:840
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS >::parse
static void parse(std::string in, google::protobuf::Message *out, const google::protobuf::RepeatedPtrField< protobuf::TranslatorEntry::CreateParser::Algorithm > &algorithms=google::protobuf::RepeatedPtrField< protobuf::TranslatorEntry::CreateParser::Algorithm >(), bool use_short_enum=false)
Definition: moos_protobuf_helpers.h:436
google::protobuf::Reflection::SetRepeatedBool
virtual void SetRepeatedBool(Message *message, const FieldDescriptor *field, int index, bool value) const =0
goby::util::e
constexpr T e
Definition: constants.h:35
google::protobuf::Reflection::GetDouble
virtual double GetDouble(const Message &message, const FieldDescriptor *field) const =0
google::protobuf::Reflection::GetRepeatedString
virtual string GetRepeatedString(const Message &message, const FieldDescriptor *field, int index) const =0
google::protobuf::Message::GetReflection
virtual const Reflection * GetReflection() const final
Definition: message.h:345
serialize_for_moos
bool serialize_for_moos(std::string *out, const google::protobuf::Message &msg)
Converts the Google Protocol Buffers message msg into a suitable (human readable) string out for send...
Definition: moos_protobuf_helpers.h:1538
google::protobuf::Reflection::GetMessage
virtual const Message & GetMessage(const Message &message, const FieldDescriptor *field, MessageFactory *factory=NULL) const =0
group
goby::util::logger::GroupSetter group(std::string n)
Definition: logger_manipulators.h:134
google::protobuf::Reflection
Definition: message.h:412
goby::moos::transitional::DCCLAlgorithmPerformer::getInstance
static DCCLAlgorithmPerformer * getInstance()
google::protobuf::Reflection::GetRepeatedMessage
virtual const Message & GetRepeatedMessage(const Message &message, const FieldDescriptor *field, int index) const =0
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED >::parse
static void parse(const std::string &in, google::protobuf::Message *out)
Definition: moos_protobuf_helpers.h:184
goby::moos::transitional::DCCLAlgorithmPerformer::run_algorithm
void run_algorithm(const std::string &algorithm, DCCLMessageVal &in, const std::vector< DCCLMessageVal > &ref)
flex_ostreambuf.h
goby::time::str
std::string str(TimeType value=SystemClock::now< TimeType >())
Returns the provided time (or current time if omitted) as a human-readable string.
Definition: convert.h:191
google::protobuf::Reflection::SetRepeatedString
virtual void SetRepeatedString(Message *message, const FieldDescriptor *field, int index, const string &value) const =0
google::protobuf::Reflection::AddEnum
virtual void AddEnum(Message *message, const FieldDescriptor *field, const EnumValueDescriptor *value) const =0
google::protobuf::Reflection::SetRepeatedEnum
virtual void SetRepeatedEnum(Message *message, const FieldDescriptor *field, int index, const EnumValueDescriptor *value) const =0
google::protobuf::Reflection::GetInt32
virtual int32 GetInt32(const Message &message, const FieldDescriptor *field) const =0
goby::moos::add_name_to_enum
std::string add_name_to_enum(const std::string &enum_value, const std::string &field_name)
Definition: moos_protobuf_helpers.h:147
google::protobuf::Reflection::AddMessage
virtual Message * AddMessage(Message *message, const FieldDescriptor *field, MessageFactory *factory=NULL) const =0
google::protobuf::Reflection::HasField
virtual bool HasField(const Message &message, const FieldDescriptor *field) const =0
goby::util::logger_lock::lock
@ lock
Definition: flex_ostreambuf.h:62
google::protobuf::Reflection::SetDouble
virtual void SetDouble(Message *message, const FieldDescriptor *field, double value) const =0
google::protobuf::Reflection::FieldSize
virtual int FieldSize(const Message &message, const FieldDescriptor *field) const =0
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS >::serialize
static void serialize(std::string *out, const google::protobuf::Message &in, const google::protobuf::RepeatedPtrField< protobuf::TranslatorEntry::PublishSerializer::Algorithm > &algorithms=google::protobuf::RepeatedPtrField< protobuf::TranslatorEntry::PublishSerializer::Algorithm >(), bool use_short_enum=false)
Definition: moos_protobuf_helpers.h:332
goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED
static const ParserSerializerTechnique TECHNIQUE_PROTOBUF_NATIVE_ENCODED
Definition: translator.pb.h:1088
google::protobuf::Reflection::SetFloat
virtual void SetFloat(Message *message, const FieldDescriptor *field, float value) const =0
google::protobuf::Reflection::GetRepeatedUInt32
virtual uint32 GetRepeatedUInt32(const Message &message, const FieldDescriptor *field, int index) const =0
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_FORMAT >::RepeatedFieldKey::index
int index
Definition: moos_protobuf_helpers.h:837
google::protobuf::Reflection::GetRepeatedEnum
virtual const EnumValueDescriptor * GetRepeatedEnum(const Message &message, const FieldDescriptor *field, int index) const =0
moos_string.h
goby::moos::val_from_string
bool val_from_string(std::string &out, const std::string &str, const std::string &key)
Definition: moos_string.h:60
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX >::parse
static void parse(const std::string &in, google::protobuf::Message *out)
Definition: moos_protobuf_helpers.h:202
goby::field
extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FieldOptions, ::google::protobuf::internal::MessageTypeTraits< ::goby::GobyFieldOptions >, 11, false > field
Definition: option_extensions.pb.h:1323
parse_for_moos
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...
Definition: moos_protobuf_helpers.h:1584
goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED
static const ParserSerializerTechnique TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED
Definition: translator.pb.h:1100
message.h
goby::moos::MOOSPrefixTranslation::parse
static void parse(const std::string &in, google::protobuf::Message *msg)
Definition: moos_protobuf_helpers.h:225
goby_moos_app.pb.h
google::protobuf::Reflection::AddBool
virtual void AddBool(Message *message, const FieldDescriptor *field, bool value) const =0
httplib::detail::to_lower
std::string to_lower(const char *beg, const char *end)
Definition: httplib.h:5045
google::protobuf::Reflection::GetInt64
virtual int64 GetInt64(const Message &message, const FieldDescriptor *field) const =0
goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT
static const ParserSerializerTechnique TECHNIQUE_PROTOBUF_TEXT_FORMAT
Definition: translator.pb.h:1086
google::protobuf::Reflection::MutableMessage
virtual Message * MutableMessage(Message *message, const FieldDescriptor *field, MessageFactory *factory=NULL) const =0
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_FORMAT >::parse
static void parse(const std::string &in, google::protobuf::Message *out, std::string format, const std::string &repeated_delimiter, const google::protobuf::RepeatedPtrField< protobuf::TranslatorEntry::CreateParser::Algorithm > &algorithms=google::protobuf::RepeatedPtrField< protobuf::TranslatorEntry::CreateParser::Algorithm >(), bool use_short_enum=false)
Definition: moos_protobuf_helpers.h:1145
google::protobuf::Reflection::AddUInt64
virtual void AddUInt64(Message *message, const FieldDescriptor *field, uint64 value) const =0
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT >::parse
static void parse(const std::string &in, google::protobuf::Message *out)
Definition: moos_protobuf_helpers.h:167
goby::util::logger::DIE
@ DIE
Definition: flex_ostreambuf.h:80
google::protobuf::Reflection::GetRepeatedInt32
virtual int32 GetRepeatedInt32(const Message &message, const FieldDescriptor *field, int index) const =0
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT >::serialize
static void serialize(std::string *out, const google::protobuf::Message &in)
Definition: moos_protobuf_helpers.h:160
goby::moos::dynamic_parse_mutex
std::mutex dynamic_parse_mutex
google::protobuf::Reflection::GetRepeatedBool
virtual bool GetRepeatedBool(const Message &message, const FieldDescriptor *field, int index) const =0
google::protobuf::Reflection::AddDouble
virtual void AddDouble(Message *message, const FieldDescriptor *field, double value) const =0
goby::util::FlexOStreamErrorCollector
Definition: flex_ostream.h:216
goby::moos::transitional::DCCLMessageVal
defines a DCCL value
Definition: message_val.h:41
goby::moos::MAGIC_PROTOBUF_HEADER
const std::string MAGIC_PROTOBUF_HEADER
Definition: moos_protobuf_helpers.h:75
flex_ostream.h
goby::msg
extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MessageOptions, ::google::protobuf::internal::MessageTypeTraits< ::goby::GobyMessageOptions >, 11, false > msg
Definition: option_extensions.pb.h:1327
google::protobuf::Reflection::SetUInt64
virtual void SetUInt64(Message *message, const FieldDescriptor *field, uint64 value) const =0
google::protobuf::Reflection::AddInt64
virtual void AddInt64(Message *message, const FieldDescriptor *field, int64 value) const =0
google::protobuf::Reflection::AddString
virtual void AddString(Message *message, const FieldDescriptor *field, const string &value) const =0
google::protobuf::Reflection::MutableRepeatedMessage
virtual Message * MutableRepeatedMessage(Message *message, const FieldDescriptor *field, int index) const =0
translator.pb.h
goby::moos::get_moos_technique
goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique get_moos_technique()
Definition: moos_protobuf_helpers.h:1512
goby::util::hex_decode
void hex_decode(const std::string &in, std::string *out)
Decodes a (little-endian) hexadecimal string to a byte string. Index 0 and 1 (first byte) of in are w...
Definition: binary.h:47
google::protobuf::Message
Definition: message.h:189
google::protobuf::Reflection::GetUInt32
virtual uint32 GetUInt32(const Message &message, const FieldDescriptor *field) const =0
google::protobuf::Message::GetDescriptor
const Descriptor * GetDescriptor() const
Definition: message.h:336
binary.h
google::protobuf::MessageLite::SerializeToString
bool SerializeToString(string *output) const
goby::moos::MOOSPrefixTranslation::dynamic_parse
static std::shared_ptr< google::protobuf::Message > dynamic_parse(const std::string &in)
Definition: moos_protobuf_helpers.h:263
goby::moos::MOOSPrefixTranslation::serialize
static void serialize(std::string *out, const google::protobuf::Message &msg)
Definition: moos_protobuf_helpers.h:217
dynamic_parse_for_moos
std::shared_ptr< google::protobuf::Message > dynamic_parse_for_moos(const std::string &in)
Definition: moos_protobuf_helpers.h:1628
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED >::serialize
static void serialize(std::string *out, const google::protobuf::Message &in)
Definition: moos_protobuf_helpers.h:179
google::protobuf::Reflection::SetInt32
virtual void SetInt32(Message *message, const FieldDescriptor *field, int32 value) const =0
google::protobuf::Reflection::SetRepeatedInt64
virtual void SetRepeatedInt64(Message *message, const FieldDescriptor *field, int index, int64 value) const =0
google::protobuf::Reflection::SetString
virtual void SetString(Message *message, const FieldDescriptor *field, const string &value) const =0
goby::moos::protobuf::GobyMOOSAppConfig::has_moos_parser_technique
bool has_moos_parser_technique() const
Definition: goby_moos_app.pb.h:1429
goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX
static const ParserSerializerTechnique TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX
Definition: translator.pb.h:1098
goby::moos::MOOSTranslation
Definition: moos_protobuf_helpers.h:153
google::protobuf::Reflection::GetRepeatedUInt64
virtual uint64 GetRepeatedUInt64(const Message &message, const FieldDescriptor *field, int index) const =0
google::protobuf::Reflection::AddUInt32
virtual void AddUInt32(Message *message, const FieldDescriptor *field, uint32 value) const =0
goby::moos::protobuf::TranslatorEntry_CreateParser_Algorithm
Definition: translator.pb.h:324
goby::util::hex_encode
void hex_encode(const std::string &in, std::string *out, bool upper_case=false)
Encodes a (little-endian) hexadecimal string from a byte string. Index 0 of in is written to index 0 ...
Definition: binary.h:94
google::protobuf::Reflection::SetBool
virtual void SetBool(Message *message, const FieldDescriptor *field, bool value) const =0
google::protobuf::Reflection::SetEnum
virtual void SetEnum(Message *message, const FieldDescriptor *field, const EnumValueDescriptor *value) const =0
google::protobuf::Reflection::GetEnum
virtual const EnumValueDescriptor * GetEnum(const Message &message, const FieldDescriptor *field) const =0
httplib::detail::split
void split(const char *b, const char *e, char d, std::function< void(const char *, const char *)> fn)
Definition: httplib.h:2494
goby::glog
util::FlexOstream glog
Access the Goby logger through this object.
google::protobuf::MessageLite::SerializeAsString
string SerializeAsString() const
goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX
static const ParserSerializerTechnique TECHNIQUE_PROTOBUF_NATIVE_HEX
Definition: translator.pb.h:1096
message_algorithms.h
google::protobuf::Reflection::GetUInt64
virtual uint64 GetUInt64(const Message &message, const FieldDescriptor *field) const =0
google::protobuf::Reflection::GetString
virtual string GetString(const Message &message, const FieldDescriptor *field) const =0
google::protobuf::Reflection::SetInt64
virtual void SetInt64(Message *message, const FieldDescriptor *field, int64 value) const =0
google::protobuf::Reflection::SetRepeatedFloat
virtual void SetRepeatedFloat(Message *message, const FieldDescriptor *field, int index, float value) const =0
goby::moos::protobuf::TranslatorEntry_PublishSerializer_Algorithm
Definition: translator.pb.h:645
google::protobuf::Reflection::GetFloat
virtual float GetFloat(const Message &message, const FieldDescriptor *field) const =0
google::protobuf::Reflection::GetRepeatedInt64
virtual int64 GetRepeatedInt64(const Message &message, const FieldDescriptor *field, int index) const =0
goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name
static const ::std::string & ParserSerializerTechnique_Name(ParserSerializerTechnique value)
Definition: translator.pb.h:1115
goby::moos::MOOSTranslation< protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX >::serialize
static void serialize(std::string *out, const google::protobuf::Message &in)
Definition: moos_protobuf_helpers.h:193
google::protobuf::MessageLite::ParseFromString
bool ParseFromString(const string &data)
goby::moos::protobuf::GobyMOOSAppConfig::has_use_binary_protobuf
bool has_use_binary_protobuf() const
Definition: goby_moos_app.pb.h:1405
goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT
static const ParserSerializerTechnique TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT
Definition: translator.pb.h:1094