Gazebo Transport

API Reference

12.2.1
gz/transport/RepHandler.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #ifndef GZ_TRANSPORT_REPHANDLER_HH_
19 #define GZ_TRANSPORT_REPHANDLER_HH_
20 
21 #ifdef _MSC_VER
22 #pragma warning(push)
23 #pragma warning(disable: 4251)
24 #endif
25 #include <google/protobuf/message.h>
26 #include <google/protobuf/stubs/common.h>
27 #if GOOGLE_PROTOBUF_VERSION > 2999999 && GOOGLE_PROTOBUF_VERSION < 4022000
28 #include <google/protobuf/stubs/casts.h>
29 #endif
30 #ifdef _MSC_VER
31 #pragma warning(pop)
32 #endif
33 
34 #include <functional>
35 #include <iostream>
36 #include <memory>
37 #include <string>
38 
39 #include "gz/transport/config.hh"
40 #include "gz/transport/Export.hh"
42 #include "gz/transport/Uuid.hh"
43 
44 namespace gz
45 {
46  namespace transport
47  {
48  // Inline bracket to help doxygen filtering.
49  inline namespace GZ_TRANSPORT_VERSION_NAMESPACE {
50  //
53  class GZ_TRANSPORT_VISIBLE IRepHandler
54  {
56  public: IRepHandler()
57  : hUuid(Uuid().ToString())
58  {
59  }
60 
62  public: virtual ~IRepHandler() = default;
63 
68  public: virtual bool RunLocalCallback(const transport::ProtoMsg &_msgReq,
69  transport::ProtoMsg &_msgRep) = 0;
70 
77  public: virtual bool RunCallback(const std::string &_req,
78  std::string &_rep) = 0;
79 
82  public: std::string HandlerUuid() const
83  {
84  return this->hUuid;
85  }
86 
89  public: virtual std::string ReqTypeName() const = 0;
90 
93  public: virtual std::string RepTypeName() const = 0;
94 
95 #ifdef _WIN32
96 // Disable warning C4251 which is triggered by
97 // std::string
98 #pragma warning(push)
99 #pragma warning(disable: 4251)
100 #endif
101  protected: std::string hUuid;
103 #ifdef _WIN32
104 #pragma warning(pop)
105 #endif
106  };
107 
112  // the service call. 'Rep' is the protobuf message type that will be filled
114  template <typename Req, typename Rep> class RepHandler
115  : public IRepHandler
116  {
117  // Documentation inherited.
118  public: RepHandler() = default;
119 
126  public: void SetCallback(
127  const std::function<bool(const Req &, Rep &)> &_cb)
128  {
129  this->cb = _cb;
130  }
131 
132  // Documentation inherited.
133  public: bool RunLocalCallback(const transport::ProtoMsg &_msgReq,
134  transport::ProtoMsg &_msgRep)
135  {
136  // Execute the callback (if existing)
137  if (!this->cb)
138  {
139  std::cerr << "RepHandler::RunLocalCallback() error: "
140  << "Callback is NULL" << std::endl;
141  return false;
142  }
143 
144 #if GOOGLE_PROTOBUF_VERSION >= 4022000
145  auto msgReq =
146  google::protobuf::internal::DownCast<const Req*>(&_msgReq);
147  auto msgRep = google::protobuf::internal::DownCast<Rep*>(&_msgRep);
148 #elif GOOGLE_PROTOBUF_VERSION > 2999999
149  auto msgReq = google::protobuf::down_cast<const Req*>(&_msgReq);
150  auto msgRep = google::protobuf::down_cast<Rep*>(&_msgRep);
151 #else
152  auto msgReq =
153  google::protobuf::internal::down_cast<const Req*>(&_msgReq);
154  auto msgRep = google::protobuf::internal::down_cast<Rep*>(&_msgRep);
155 #endif
156 
157  return this->cb(*msgReq, *msgRep);
158  }
159 
160  // Documentation inherited.
161  public: bool RunCallback(const std::string &_req,
162  std::string &_rep)
163  {
164  // Check if we have a callback registered.
165  if (!this->cb)
166  {
167  std::cerr << "RepHandler::RunCallback() error: "
168  << "Callback is NULL" << std::endl;
169  return false;
170  }
171 
172  // Instantiate the specific protobuf message associated to this topic.
173  auto msgReq = this->CreateMsg(_req);
174  if (!msgReq)
175  {
176  return false;
177  }
178 
179  Rep msgRep;
180  if (!this->cb(*msgReq, msgRep))
181  return false;
182 
183  if (!msgRep.SerializeToString(&_rep))
184  {
185  std::cerr << "RepHandler::RunCallback(): Error serializing the "
186  << "response" << std::endl;
187  return false;
188  }
189 
190  return true;
191  }
192 
193  // Documentation inherited.
194  public: virtual std::string ReqTypeName() const
195  {
196  return Req().GetTypeName();
197  }
198 
199  // Documentation inherited.
200  public: virtual std::string RepTypeName() const
201  {
202  return Rep().GetTypeName();
203  }
204 
208  private: std::shared_ptr<Req> CreateMsg(const std::string &_data) const
209  {
210  // Instantiate a specific protobuf message
211  std::shared_ptr<Req> msgPtr(new Req());
212 
213  // Create the message using some serialized data
214  if (!msgPtr->ParseFromString(_data))
215  {
216  std::cerr << "RepHandler::CreateMsg() error: ParseFromString failed"
217  << std::endl;
218  }
219 
220  return msgPtr;
221  }
222 
224  private: std::function<bool(const Req &, Rep &)> cb;
225  };
226  }
227  }
228 }
229 
230 #endif