Goby v2
dynamic_protobuf.cpp
1 // Copyright 2009-2018 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 //
5 //
6 // This file is part of the Goby Underwater Autonomy Project Binaries
7 // ("The Goby Binaries").
8 //
9 // The Goby Binaries are free software: you can redistribute them and/or modify
10 // them under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // The Goby Binaries are distributed in the hope that they will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
21 
22 #include "goby/util/dynamic_protobuf_manager.h"
23 #include <cassert>
24 #include <dlfcn.h>
25 #include <google/protobuf/descriptor.pb.h>
26 #include <google/protobuf/text_format.h>
27 #include <iostream>
28 
29 #include "test_a.pb.h"
30 
31 using namespace goby::util;
32 
33 int main()
34 {
35  void* dl_handle = dlopen("libtest_dyn_protobuf" SHARED_LIBRARY_SUFFIX, RTLD_LAZY);
36 
37  if (!dl_handle)
38  {
39  std::cerr << "Failed to open libtest_dyn_protobuf" SHARED_LIBRARY_SUFFIX << std::endl;
40  exit(1);
41  }
42 
43  boost::shared_ptr<google::protobuf::SimpleDescriptorDatabase> simple_database(
44  new google::protobuf::SimpleDescriptorDatabase);
45  goby::util::DynamicProtobufManager::add_database(simple_database);
46 
47  {
48  // testing compiled in
49  boost::shared_ptr<google::protobuf::Message> adyn_msg =
50  goby::util::DynamicProtobufManager::new_protobuf_message("A");
51 
52  std::cout << adyn_msg->GetDescriptor()->DebugString() << std::endl;
53 
54  // testing dlopen'd
55  boost::shared_ptr<google::protobuf::Message> bdyn_msg =
56  goby::util::DynamicProtobufManager::new_protobuf_message("B");
57 
58  std::cout << bdyn_msg->GetDescriptor()->DebugString() << std::endl;
59 
60  // test non-existent
61  try
62  {
63  boost::shared_ptr<google::protobuf::Message> cdyn_msg =
64  goby::util::DynamicProtobufManager::new_protobuf_message("C");
65  // should throw
66  assert(false);
67  }
68  catch (std::exception& e)
69  {
70  // expected
71  }
72 
73  // test dynamically loaded
74  google::protobuf::FileDescriptorProto d_proto;
75  std::string d_proto_str = "name: \"goby/test/util/dynamic_protobuf/test_d.proto\" "
76  "message_type { name: \"D\" field { name: \"d1\" "
77  "number: 1 label: LABEL_REQUIRED type: TYPE_DOUBLE } } ";
78 
79  google::protobuf::TextFormat::ParseFromString(d_proto_str, &d_proto);
80  goby::util::DynamicProtobufManager::add_protobuf_file(d_proto);
81 
82  boost::shared_ptr<google::protobuf::Message> ddyn_msg =
83  goby::util::DynamicProtobufManager::new_protobuf_message("D");
84 
85  std::cout << ddyn_msg->GetDescriptor()->DebugString() << std::endl;
86 
87  // test dynamically via separate database
88  google::protobuf::FileDescriptorProto e_proto;
89  std::string e_proto_str = "name: \"goby/test/util/dynamic_protobuf/test_e.proto\" "
90  "message_type { name: \"E\" field { name: \"e1\" "
91  "number: 1 label: LABEL_REQUIRED type: TYPE_DOUBLE } } ";
92 
93  google::protobuf::TextFormat::ParseFromString(e_proto_str, &e_proto);
94 
95  simple_database->Add(e_proto);
96 
97  boost::shared_ptr<google::protobuf::Message> edyn_msg =
98  goby::util::DynamicProtobufManager::new_protobuf_message("E");
99  std::cout << edyn_msg->GetDescriptor()->DebugString() << std::endl;
100 
101  std::cout << "all tests passed" << std::endl;
102  }
103 
104  goby::util::DynamicProtobufManager::protobuf_shutdown();
105 
106  dlclose(dl_handle);
107  return 0;
108 }