Gazebo Transport

API Reference

14.0.0~pre1
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
44namespace 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
102 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