Mir
template_protobuf_message_processor.h
Go to the documentation of this file.
1 /*
2  * Copyright © 2014 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by: Alan Griffiths <alan@octopull.co.uk>
17  */
18 
19 
20 #ifndef MIR_FRONTEND_TEMPLATE_PROTOBUF_MESSAGE_PROCESSOR_H_
21 #define MIR_FRONTEND_TEMPLATE_PROTOBUF_MESSAGE_PROCESSOR_H_
22 
24 
25 #include <google/protobuf/stubs/common.h>
26 #include <boost/exception/diagnostic_information.hpp>
27 
28 #include <memory>
29 #include <string>
30 
31 namespace mir
32 {
33 namespace frontend
34 {
35 namespace detail
36 {
37 // Utility metafunction result_ptr_t<> allows invoke() to pick the right
38 // send_response() overload. The base template resolves to the prototype
39 // "send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)"
40 // Client code may specialize result_ptr_t to resolve to another overload.
41 template<typename ResultType> struct result_ptr_t
42 { typedef ::google::protobuf::MessageLite* type; };
43 
44 // Boiler plate for unpacking a parameter message, invoking a server function, and
45 // sending the result message. Assumes the existence of Self::send_response().
46 template<class Self, class Server, class ServerX, class ParameterMessage, class ResultMessage>
47 void invoke(
48  Self* self,
49  Server* server,
50  void (ServerX::*function)(
51  ParameterMessage const* request,
52  ResultMessage* response,
53  ::google::protobuf::Closure* done),
54  Invocation const& invocation)
55 {
56  ParameterMessage parameter_message;
57  if (!parameter_message.ParseFromString(invocation.parameters()))
58  BOOST_THROW_EXCEPTION(std::runtime_error("Failed to parse message parameters!"));
59  ResultMessage result_message;
60 
61  try
62  {
63  std::unique_ptr<google::protobuf::Closure> callback(
64  google::protobuf::NewPermanentCallback<
65  Self,
66  ::google::protobuf::uint32,
68  self,
69  &Self::send_response,
70  invocation.id(),
71  &result_message));
72 
73  (server->*function)(
74  &parameter_message,
75  &result_message,
76  callback.get());
77  }
78  catch (std::exception const& x)
79  {
80  using namespace std::literals::string_literals;
81  result_message.set_error("Error processing request: "s +
82  x.what() + "\nInternal error details: " + boost::diagnostic_information(x));
83  self->send_response(invocation.id(), &result_message);
84  }
85 }
86 }
87 }
88 }
89 
90 #endif /* MIR_FRONTEND_TEMPLATE_PROTOBUF_MESSAGE_PROCESSOR_H_ */
All things Mir.
Definition: atomic_callback.h:25
Definition: message_processor.h:40
Customise and run a Mir server.
Definition: server.h:75
google::protobuf::uint32 id() const
void invoke(Self *self, Server *server, void(ServerX::*function)(ParameterMessage const *request, ResultMessage *response,::google::protobuf::Closure *done), Invocation const &invocation)
Definition: template_protobuf_message_processor.h:47
const ::std::string & parameters() const
Definition: template_protobuf_message_processor.h:41
::google::protobuf::MessageLite * type
Definition: template_protobuf_message_processor.h:42

Copyright © 2012-2015 Canonical Ltd.
Generated on Thu Oct 8 16:20:16 UTC 2015