All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 IGN_TRANSPORT_REPHANDLER_HH_
19 #define IGN_TRANSPORT_REPHANDLER_HH_
20 
21 #ifdef _MSC_VER
22 #pragma warning(push, 0)
23 #endif
24 #include <google/protobuf/message.h>
25 #ifdef _MSC_VER
26 #pragma warning(pop)
27 #endif
28 
29 #if GOOGLE_PROTOBUF_VERSION > 2999999
30 #include <google/protobuf/stubs/casts.h>
31 #endif
32 
33 #include <functional>
34 #include <iostream>
35 #include <memory>
36 #include <string>
37 
41 
42 namespace ignition
43 {
44  namespace transport
45  {
49  {
51  public: IRepHandler()
52  : hUuid(Uuid().ToString())
53  {
54  }
55 
57  public: virtual ~IRepHandler() = default;
58 
63  public: virtual void RunLocalCallback(const transport::ProtoMsg &_msgReq,
64  transport::ProtoMsg &_msgRep,
65  bool &_result) = 0;
66 
73  public: virtual void RunCallback(const std::string &_req,
74  std::string &_rep,
75  bool &_result) = 0;
76 
79  public: std::string HandlerUuid() const
80  {
81  return this->hUuid;
82  }
83 
86  public: virtual std::string ReqTypeName() const = 0;
87 
90  public: virtual std::string RepTypeName() const = 0;
91 
93  protected: std::string hUuid;
94  };
95 
100  // the service call. 'Rep' is the protobuf message type that will be filled
102  template <typename Req, typename Rep> class RepHandler
103  : public IRepHandler
104  {
105  // Documentation inherited.
106  public: RepHandler() = default;
107 
114  public: void SetCallback(const std::function
115  <void(const Req &, Rep &, bool &)> &_cb)
116  {
117  this->cb = _cb;
118  }
119 
120  // Documentation inherited.
121  public: void RunLocalCallback(const transport::ProtoMsg &_msgReq,
122  transport::ProtoMsg &_msgRep,
123  bool &_result)
124  {
125  // Execute the callback (if existing)
126  if (this->cb)
127  {
128 #if GOOGLE_PROTOBUF_VERSION > 2999999
129  auto msgReq = google::protobuf::down_cast<const Req*>(&_msgReq);
130  auto msgRep = google::protobuf::down_cast<Rep*>(&_msgRep);
131 #else
132  auto msgReq =
133  google::protobuf::internal::down_cast<const Req*>(&_msgReq);
134  auto msgRep = google::protobuf::internal::down_cast<Rep*>(&_msgRep);
135 #endif
136 
137  this->cb(*msgReq, *msgRep, _result);
138  }
139  else
140  {
141  std::cerr << "RepHandler::RunLocalCallback() error: "
142  << "Callback is NULL" << std::endl;
143  _result = false;
144  }
145  }
146 
147  // Documentation inherited.
148  public: void RunCallback(const std::string &_req,
149  std::string &_rep,
150  bool &_result)
151  {
152  // Check if we have a callback registered.
153  if (!this->cb)
154  {
155  std::cerr << "RepHandler::RunCallback() error: "
156  << "Callback is NULL" << std::endl;
157  _result = false;
158  return;
159  }
160 
161  // Instantiate the specific protobuf message associated to this topic.
162  auto msgReq = this->CreateMsg(_req);
163  if (!msgReq)
164  {
165  _result = false;
166  return;
167  }
168 
169  Rep msgRep;
170  this->cb(*msgReq, msgRep, _result);
171 
172  if (!msgRep.SerializeToString(&_rep))
173  {
174  std::cerr << "RepHandler::RunCallback(): Error serializing the "
175  << "response" << std::endl;
176  _result = false;
177  return;
178  }
179  }
180 
181  // Documentation inherited.
182  public: virtual std::string ReqTypeName() const
183  {
184  return Req().GetTypeName();
185  }
186 
187  // Documentation inherited.
188  public: virtual std::string RepTypeName() const
189  {
190  return Rep().GetTypeName();
191  }
192 
196  private: std::shared_ptr<Req> CreateMsg(const std::string &_data) const
197  {
198  // Instantiate a specific protobuf message
199  std::shared_ptr<Req> msgPtr(new Req());
200 
201  // Create the message using some serialized data
202  if (!msgPtr->ParseFromString(_data))
203  {
204  std::cerr << "RepHandler::CreateMsg() error: ParseFromString failed"
205  << std::endl;
206  }
207 
208  return msgPtr;
209  }
210 
212  private: std::function<void(const Req &, Rep &, bool &)> cb;
213  };
214  }
215 }
216 
217 #endif
std::string HandlerUuid() const
Get the unique UUID of this handler.
Definition: RepHandler.hh:79
Interface class used to manage a replier handler.
Definition: RepHandler.hh:48
std::string hUuid
Unique handler's UUID.
Definition: RepHandler.hh:93
virtual std::string ReqTypeName() const
Get the message type name used in the service request.
Definition: RepHandler.hh:182
IRepHandler()
Constructor.
Definition: RepHandler.hh:51
void RunCallback(const std::string &_req, std::string &_rep, bool &_result)
Executes the callback registered for this handler.
Definition: RepHandler.hh:148
A portable class for representing a Universally Unique Identifier.
Definition: Uuid.hh:41
virtual std::string RepTypeName() const
Get the message type name used in the service response.
Definition: RepHandler.hh:188
google::protobuf::Message ProtoMsg
Definition: TransportTypes.hh:65
void RunLocalCallback(const transport::ProtoMsg &_msgReq, transport::ProtoMsg &_msgRep, bool &_result)
Executes the local callback registered for this handler.
Definition: RepHandler.hh:121
with the service response.
Definition: RepHandler.hh:102
#define IGNITION_TRANSPORT_VISIBLE
Use to represent "symbol visible" if supported.
Definition: Helpers.hh:57
void SetCallback(const std::function< void(const Req &, Rep &, bool &)> &_cb)
Set the callback for this handler.
Definition: RepHandler.hh:114