328a6216ef6ec107f9e13efff91c4f2e77812bc4
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / rpc / template_message_processor.h
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 #ifndef ANBOX_RPC_TEMPLATE_MESSAGE_PROCESSOR_H_
20 #define ANBOX_RPC_TEMPLATE_MESSAGE_PROCESSOR_H_
21
22 #include <google/protobuf/stubs/common.h>
23 #ifdef USE_PROTOBUF_CALLBACK_HEADER
24 #include <google/protobuf/stubs/callback.h>
25 #endif
26
27 #include "anbox/rpc/message_processor.h"
28
29 #include "anbox_rpc.pb.h"
30
31 namespace anbox {
32 namespace rpc {
33 // Utility metafunction result_ptr_t<> allows invoke() to pick the right
34 // send_response() overload. The base template resolves to the prototype
35 // "send_response(::google::protobuf::uint32 id, ::google::protobuf::Message*
36 // response)"
37 // Client code may specialize result_ptr_t to resolve to another overload.
38 template <typename ResultType>
39 struct result_ptr_t {
40   typedef ::google::protobuf::MessageLite* type;
41 };
42
43 // Boiler plate for unpacking a parameter message, invoking a server function,
44 // and
45 // sending the result message. Assumes the existence of Self::send_response().
46 template <class Self, class Bridge, class BridgeX, class ParameterMessage,
47           class ResultMessage>
48 void invoke(Self* self, Bridge* rpc,
49             void (BridgeX::*function)(ParameterMessage const* request,
50                                       ResultMessage* response,
51                                       ::google::protobuf::Closure* done),
52             Invocation const& invocation) {
53   ParameterMessage parameter_message;
54   if (!parameter_message.ParseFromString(invocation.parameters()))
55     throw std::runtime_error("Failed to parse message parameters!");
56   ResultMessage result_message;
57
58   try {
59     std::unique_ptr<google::protobuf::Closure> callback(
60         google::protobuf::NewPermanentCallback<
61             Self, ::google::protobuf::uint32,
62             typename result_ptr_t<ResultMessage>::type>(
63             self, &Self::send_response, invocation.id(), &result_message));
64
65     (rpc->*function)(&parameter_message, &result_message, callback.get());
66   } catch (std::exception const& x) {
67     result_message.set_error(std::string("Error processing request: ") +
68                              x.what());
69     self->send_response(invocation.id(), &result_message);
70   }
71 }
72 }  // namespace rpc
73 }  // namespace anbox
74
75 #endif