utilities.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement
4  *
5  * Copyright (c) 2020,
6  * TU Dortmund - Institute of Control Theory and Systems Engineering.
7  * All rights reserved.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it 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 this program. If not, see <https://www.gnu.org/licenses/>.
21  *
22  * Authors: Christoph Rösmann
23  *********************************************************************/
24 
26 #include <corbo-core/console.h>
27 
28 #include <vector>
29 
30 #ifdef WIN32
31 // WinUser.h defines GetMessage which is also used by protobuf
32 #undef GetMessage
33 #endif
34 
35 namespace corbo {
36 
37 #ifdef MESSAGE_SUPPORT
38 bool util::get_oneof_field_type(const google::protobuf::Message& message, const std::string& oneof_name, std::string& item_name,
39  bool include_namespace)
40 {
41  item_name.clear();
42  const google::protobuf::OneofDescriptor* oneof = nullptr;
43  if (oneof_name.empty())
44  {
45  // check if we have only a single oneof
46  if (message.GetDescriptor()->oneof_decl_count() == 1)
47  {
48  oneof = message.GetDescriptor()->oneof_decl(0);
49  }
50  else
51  {
52  PRINT_ERROR_NAMED("Multiple oneofs found in the message but no oneof_name provided, I don't know which one to choose.");
53  return false;
54  }
55  }
56  else
57  {
58  oneof = message.GetDescriptor()->FindOneofByName(oneof_name);
59  }
60  if (oneof)
61  {
62  const google::protobuf::FieldDescriptor* oneof_field = message.GetReflection()->GetOneofFieldDescriptor(message, oneof);
63  if (oneof_field && oneof_field->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
64  {
65  // ok, we have found the field
66  item_name = message.GetReflection()->GetMessage(message, oneof_field).GetTypeName();
67  if (!include_namespace)
68  {
69  std::size_t found = item_name.find_last_of(".");
70  item_name = item_name.substr(found + 1);
71  }
72  return true;
73  }
74  }
75  if (item_name.empty()) PRINT_ERROR_NAMED("no item found for oneof-name " + oneof_name + ".");
76  return false;
77 }
78 
79 bool util::get_oneof_field_type_expand_isolated(const google::protobuf::Message& top_message, const google::protobuf::OneofDescriptor* top_oneof,
80  std::string& item_name, bool include_namespace, int max_depth)
81 {
82  const google::protobuf::FieldDescriptor* top_oneof_field = top_message.GetReflection()->GetOneofFieldDescriptor(top_message, top_oneof);
83  if (top_oneof_field && top_oneof_field->cpp_type() != google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) return false;
84 
85  const google::protobuf::Message& message = top_message.GetReflection()->GetMessage(top_message, top_oneof_field);
86 
87  int num_oneofs = message.GetDescriptor()->oneof_decl_count();
88 
89  if (num_oneofs == 1 && max_depth > 0)
90  {
91  get_oneof_field_type_expand_isolated(message, message.GetDescriptor()->oneof_decl(0), item_name, include_namespace, max_depth - 1);
92  }
93  else
94  {
95  // ok, we have found the field
96  item_name = message.GetTypeName();
97  if (!include_namespace)
98  {
99  std::size_t found = item_name.find_last_of(".");
100  item_name = item_name.substr(found + 1);
101  }
102  }
103  return true;
104 }
105 
106 bool util::get_oneof_field_type_expand_isolated(const google::protobuf::Message& message, const std::string& top_oneof_name, std::string& item_name,
107  bool include_namespace, int max_depth)
108 {
109  const google::protobuf::OneofDescriptor* top_oneof = nullptr;
110  if (top_oneof_name.empty())
111  {
112  // check if we have only a single oneof
113  if (message.GetDescriptor()->oneof_decl_count() == 1)
114  {
115  top_oneof = message.GetDescriptor()->oneof_decl(0);
116  }
117  else
118  {
119  PRINT_ERROR_NAMED("Multiple oneofs found in the message but no top_oneof_name provided, I don't know which one to choose.");
120  return false;
121  }
122  }
123  else
124  {
125  top_oneof = message.GetDescriptor()->FindOneofByName(top_oneof_name);
126  }
127  if (top_oneof)
128  {
129  return get_oneof_field_type_expand_isolated(message, top_oneof, item_name, include_namespace, max_depth);
130  }
131  return false;
132 }
133 
134 #endif
135 
136 } // namespace corbo
#define PRINT_ERROR_NAMED(msg)
Definition: console.h:260


control_box_rst
Author(s): Christoph Rösmann
autogenerated on Mon Feb 28 2022 22:07:58