DCCL v4
quick-runtime.cpp
1 // Copyright 2018-2023:
2 // GobySoft, LLC (2013-)
3 // Community contributors (see AUTHORS file)
4 // File authors:
5 // Toby Schneider <toby@gobysoft.org>
6 //
7 //
8 // This file is part of the Dynamic Compact Control Language Library
9 // ("DCCL").
10 //
11 // DCCL is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU Lesser General Public License as published by
13 // the Free Software Foundation, either version 2.1 of the License, or
14 // (at your option) any later version.
15 //
16 // DCCL is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public License
22 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
23 #include "dccl.h"
24 #include <iostream>
25 #include <memory>
26 
27 // Advanced version of quick.cpp that loads the .proto at runtime, instead of compile time
28 // compile with g++ dccl-runtime.cpp -std=c++11 -lprotobuf -ldccl -o dccl-runtime && ./dccl-runtime
29 
30 // sets Reflection fields based on type of value
31 void _set_field_value(const google::protobuf::Reflection* refl,
32  const google::protobuf::FieldDescriptor* field_desc,
33  std::unique_ptr<google::protobuf::Message>& msg, double val)
34 {
35  refl->SetDouble(msg.get(), field_desc, val);
36 }
37 
38 void _set_field_value(const google::protobuf::Reflection* refl,
39  const google::protobuf::FieldDescriptor* field_desc,
40  std::unique_ptr<google::protobuf::Message>& msg, bool val)
41 {
42  refl->SetBool(msg.get(), field_desc, val);
43 }
44 
45 void _set_field_value(const google::protobuf::Reflection* refl,
46  const google::protobuf::FieldDescriptor* field_desc,
47  std::unique_ptr<google::protobuf::Message>& msg, int val)
48 {
49  if (field_desc->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_ENUM)
50  {
51  auto enum_desc = field_desc->enum_type();
52  auto enum_val_desc = enum_desc->FindValueByNumber(val);
53  if (enum_val_desc)
54  refl->SetEnum(msg.get(), field_desc, enum_val_desc);
55  }
56 }
57 
58 // Look up a field by name and set its value
59 template <typename FieldType>
60 void set_field(std::unique_ptr<google::protobuf::Message>& msg, const char* field_name,
61  FieldType val)
62 {
63  // use protobuf Reflection to fill in message
64  const google::protobuf::Reflection* refl = msg->GetReflection();
65  const google::protobuf::Descriptor* desc = msg->GetDescriptor();
66  const google::protobuf::FieldDescriptor* field_desc = desc->FindFieldByName(field_name);
67  if (field_desc)
68  _set_field_value(refl, field_desc, msg, val);
69  else
70  std::cerr << "Invalid field name: " << field_name << std::endl;
71 }
72 
73 int main()
74 {
75  // Allows runtime compilation of .proto files
77  // uncomment for debugging
78  // dccl::dlog.connect(dccl::logger::DEBUG1_PLUS, &std::cerr);
79 
80  // Add any -I for protoc
82  "/home/toby/share/examples/quickstart_navreport");
83 
84  // FileDescriptor = type introspection on .proto
85  const google::protobuf::FileDescriptor* nav_report_file_desc =
87 
88  if (!nav_report_file_desc)
89  {
90  std::cerr << "Failed to read in navreport.proto" << std::endl;
91  exit(EXIT_FAILURE);
92  }
93 
94  std::string encoded_bytes;
95  dccl::Codec codec;
96 
97  // Descriptor = type introspection on the Message
98  // we know there's only one Message in this .proto (index 0)
99  const google::protobuf::Descriptor* nav_report_desc = nav_report_file_desc->message_type(0);
100  codec.load(nav_report_desc);
101 
102  // SENDER
103  {
105  std::unique_ptr<google::protobuf::Message>>(nav_report_desc);
106 
107  set_field(r_out, "x", 450.0);
108  set_field(r_out, "y", 550.0);
109  set_field(r_out, "z", -100.0);
110  const int AUV = 1;
111  set_field(r_out, "veh_class", AUV);
112  set_field(r_out, "battery_ok", true);
113 
114  codec.encode(&encoded_bytes, *r_out);
115  }
116  // send encoded_bytes across your link
117 
118  // RECEIVER
119  {
120  auto r_in = codec.decode<std::unique_ptr<google::protobuf::Message>>(encoded_bytes);
121  std::cout << r_in->ShortDebugString() << std::endl;
122  }
123 }
dccl::Codec
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
Definition: codec.h:62
dccl::DynamicProtobufManager::load_from_proto_file
static const google::protobuf::FileDescriptor * load_from_proto_file(const std::string &protofile_absolute_path)
Load a message from a .proto file on the disk. enable_compilation() must be called first.
Definition: dynamic_protobuf_manager.cpp:112
dccl::DynamicProtobufManager::enable_compilation
static void enable_compilation()
Enable on the fly compilation of .proto files on the local disk. Must be called before load_from_prot...
Definition: dynamic_protobuf_manager.h:123
dccl::DynamicProtobufManager::add_include_path
static void add_include_path(const std::string &path)
Add a path for searching for import messages when loading .proto files using load_from_proto_file()
Definition: dynamic_protobuf_manager.cpp:86
dccl::DynamicProtobufManager::new_protobuf_message
static GoogleProtobufMessagePointer new_protobuf_message(const std::string &protobuf_type_name, bool user_pool_first=false)
Create a new (empty) Google Protobuf message of a given type by name.
Definition: dynamic_protobuf_manager.h:76