Initial import to Git
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusProxyAsyncCallbackHandler.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #ifndef COMMONAPI_DBUS_DBUS_PROXY_ASYNC_CALLBACK_HANDLER_H_
5 #define COMMONAPI_DBUS_DBUS_PROXY_ASYNC_CALLBACK_HANDLER_H_
6
7 #include "DBusProxyConnection.h"
8 #include "DBusMessage.h"
9 #include "DBusSerializableArguments.h"
10 #include "DBusHelper.h"
11
12 #include <functional>
13 #include <future>
14 #include <memory>
15 #include <iostream>
16
17
18 namespace CommonAPI {
19 namespace DBus {
20
21 template <typename ... _ArgTypes>
22 class DBusProxyAsyncCallbackHandler: public DBusProxyConnection::DBusMessageReplyAsyncHandler {
23  public:
24         typedef std::function<void(CallStatus, _ArgTypes...)> FunctionType;
25
26         static inline std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler> create(FunctionType&& callback) {
27                 return std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(
28                                 new DBusProxyAsyncCallbackHandler(std::move(callback)));
29         }
30
31         DBusProxyAsyncCallbackHandler() = delete;
32         DBusProxyAsyncCallbackHandler(FunctionType&& callback):
33                 callback_(std::move(callback)) {
34         }
35
36         virtual std::future<CallStatus> getFuture() {
37                 return promise_.get_future();
38         }
39
40         virtual void onDBusMessageReply(const CallStatus& dbusMessageCallStatus, const DBusMessage& dbusMessage) {
41                 promise_.set_value(handleDBusMessageReply(dbusMessageCallStatus, dbusMessage, typename make_sequence<sizeof...(_ArgTypes)>::type()));
42         }
43
44  private:
45         template <int... _ArgIndices>
46         inline CallStatus handleDBusMessageReply(const CallStatus dbusMessageCallStatus, const DBusMessage& dbusMessage, index_sequence<_ArgIndices...>) const {
47                 CallStatus callStatus = dbusMessageCallStatus;
48                 std::tuple<_ArgTypes...> argTuple;
49
50         if (dbusMessageCallStatus == CallStatus::SUCCESS) {
51             if (!dbusMessage.isErrorType()) {
52                 DBusInputStream dbusInputStream(dbusMessage);
53                 const bool success = DBusSerializableArguments<_ArgTypes...>::deserialize(dbusInputStream, std::get<_ArgIndices>(argTuple)...);
54                 if (!success)
55                     callStatus = CallStatus::REMOTE_ERROR;
56             } else {
57                 callStatus = CallStatus::REMOTE_ERROR;
58             }
59         }
60
61                 callback_(callStatus, std::move(std::get<_ArgIndices>(argTuple))...);
62                 return callStatus;
63         }
64
65         std::promise<CallStatus> promise_;
66         const FunctionType callback_;
67 };
68
69 } // namespace DBus
70 } // namespace CommonAPI
71
72 #endif // COMMONAPI_DBUS_DBUS_PROXY_ASYNC_CALLBACK_HANDLER_H_