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 #include "mir/cookie/authority.h"
25 
26 #include <google/protobuf/stubs/common.h>
27 #include <boost/exception/diagnostic_information.hpp>
28 
29 #include <memory>
30 #include <string>
31 
32 namespace mir
33 {
34 namespace frontend
35 {
36 namespace detail
37 {
38 // Utility metafunction result_ptr_t<> allows invoke() to pick the right
39 // send_response() overload. The base template resolves to the prototype
40 // "send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)"
41 // Client code may specialize result_ptr_t to resolve to another overload.
42 template<typename ResultType> struct result_ptr_t
43 { typedef ::google::protobuf::MessageLite* type; };
44 
45 // Boiler plate for unpacking a parameter message, invoking a server function, and
46 // sending the result message. Assumes the existence of Self::send_response().
47 template<class Self, class Server, class ServerX, class ParameterMessage, class ResultMessage>
48 void invoke(
49  Self* self,
50  Server* server,
51  void (ServerX::*function)(
52  ParameterMessage const* request,
53  ResultMessage* response,
54  ::google::protobuf::Closure* done),
55  Invocation const& invocation)
56 {
57  ParameterMessage parameter_message;
58  if (!parameter_message.ParseFromString(invocation.parameters()))
59  BOOST_THROW_EXCEPTION(std::runtime_error("Failed to parse message parameters!"));
60  ResultMessage result_message;
61 
62  try
63  {
64  std::unique_ptr<google::protobuf::Closure> callback(
65  google::protobuf::NewPermanentCallback<
66  Self,
67  ::google::protobuf::uint32,
69  self,
70  &Self::send_response,
71  invocation.id(),
72  &result_message));
73 
74  (server->*function)(
75  &parameter_message,
76  &result_message,
77  callback.get());
78  }
79  catch (mir::cookie::SecurityCheckError const& /*err*/)
80  {
81  throw;
82  }
83  catch (std::exception const& x)
84  {
85  using namespace std::literals::string_literals;
86  result_message.set_error("Error processing request: "s +
87  x.what() + "\nInternal error details: " + boost::diagnostic_information(x));
88  self->send_response(invocation.id(), &result_message);
89  }
90 }
91 }
92 }
93 }
94 
95 #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:77
Definition: authority.h:35
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:48
const ::std::string & parameters() const
Definition: template_protobuf_message_processor.h:42
::google::protobuf::MessageLite * type
Definition: template_protobuf_message_processor.h:43

Copyright © 2012-2015 Canonical Ltd.
Generated on Wed Mar 30 00:29:56 UTC 2016