[AT-SPI] Update test DBusWrapper for ABI compatibility
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / dali-toolkit-test-utils / dbus-wrapper.h
1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
3
4 /*
5  * Copyright 2019  Samsung Electronics Co., Ltd
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <memory>
22 #include <array>
23 #include <atomic>
24 #include <cstdint>
25 #include <cstring>
26 #include <map>
27 #include <list>
28 #include <sstream>
29 #include <string>
30 #include <thread>
31 #include <tuple>
32 #include <type_traits>
33 #include <unordered_map>
34 #include <vector>
35 #include <functional>
36
37 // INTERNAL INCLUDES
38 //#include <dali/public-api/adaptor-framework/accessibility.h>
39 //#include <dali/internal/accessibility/bridge/optional.h>
40
41 #include <dali/devel-api/adaptor-framework/accessibility.h>
42
43 #define ATSPI_PREFIX_PATH "/org/a11y/atspi/accessible/"
44 #define ATSPI_NULL_PATH "/org/a11y/atspi/null"
45
46
47 //// BART QUICK HACK
48 #define bart_assert(x) do{}while(0)
49
50 struct _Eina_Value;
51
52 /// \cond
53 struct ObjectPath
54 {
55   std::string value;
56 };
57
58 struct DBusWrapper
59 {
60   virtual ~DBusWrapper() = default;
61
62   enum class ConnectionType
63   {
64     SYSTEM,
65     SESSION
66   };
67
68 #define DEFINE_TYPE(name, eldbus_name, unref_call) \
69     struct name { virtual ~name() = default; }; \
70     using name ## Ptr = std::shared_ptr<name>; \
71     using name ## WeakPtr = std::weak_ptr<name>; \
72
73   DEFINE_TYPE(Connection, Eldbus_Connection, )
74   DEFINE_TYPE(MessageIter, Eldbus_Message_Iter, eldbus_message_iter_container_close( Value ))
75   DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref( Value ))
76   DEFINE_TYPE(Proxy, Eldbus_Proxy, eldbus_proxy_unref( Value ))
77   DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref( Value ))
78   DEFINE_TYPE(Pending, Eldbus_Pending, )
79   DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
80
81 #undef DEFINE_TYPE
82   virtual ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) = 0;
83
84 #define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
85   virtual void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) = 0; \
86   virtual bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) = 0;
87 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
88   eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
89
90   eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
91   eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
92   eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
93   eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
94   eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
95   eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
96   eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
97   eldbus_message_iter_arguments_append_impl_basic(double, d)
98   eldbus_message_iter_arguments_append_impl_basic(bool, b)
99   eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
100   eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
101
102 #undef eldbus_message_iter_arguments_append_impl_basic
103 #undef eldbus_message_iter_arguments_append_impl_basic_impl
104
105   virtual MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) = 0;
106   virtual MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) = 0;
107   virtual MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) = 0;
108   virtual MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) = 0;
109   virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) = 0;
110   virtual bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) = 0;
111   virtual std::string eldbus_message_signature_get_impl(const MessagePtr &msg) = 0;
112
113   using SendCallback = std::function<void(const MessagePtr &msg)>;
114   virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) = 0;
115   virtual std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) = 0;
116   virtual void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) = 0;
117   virtual std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) = 0;
118   virtual MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) = 0;
119   virtual MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) = 0;
120   virtual PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) = 0;
121   virtual MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) = 0;
122   virtual MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) = 0;
123   virtual ConnectionPtr eldbus_connection_get_impl(ConnectionType type) = 0;
124   virtual std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) = 0;
125   virtual ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) = 0;
126   virtual ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) = 0;
127   virtual ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) = 0;
128   virtual void eldbus_name_request_impl(const ConnectionPtr&, const std::string&) {} // no-op
129   virtual void eldbus_name_release_impl(const ConnectionPtr&, const std::string&) {} // no-op
130
131   class StringStorage
132   {
133   public:
134     struct char_ptr_deleter
135     {
136       void operator()( char* p )
137       {
138         free( p );
139       }
140     };
141     std::vector< std::unique_ptr< char, char_ptr_deleter > > storage;
142
143     const char* add( const char* txt )
144     {
145       auto ptr = strdup( txt );
146       storage.push_back( std::unique_ptr< char, char_ptr_deleter >( ptr ) );
147       return storage.back().get();
148     }
149     const char* add( const std::string& txt )
150     {
151       return add( txt.c_str() );
152     }
153   };
154
155   struct CallId
156   {
157     static std::atomic< unsigned int > LastId;
158     unsigned int id = ++LastId;
159   };
160   struct MethodInfo
161   {
162     CallId id;
163     std::string memberName;
164     std::vector< std::pair<std::string, std::string> > in, out; // _Eldbus_Arg_Info
165     std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > callback;
166   };
167   struct SignalInfo
168   {
169     CallId id;
170     std::string memberName;
171     std::vector< std::pair<std::string, std::string> > args;
172     unsigned int uniqueId;
173   };
174   struct PropertyInfo
175   {
176     CallId setterId, getterId;
177     std::string memberName, typeSignature;
178     std::function< std::string( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) > getCallback, setCallback;
179   };
180   struct SignalId
181   {
182     CallId id;
183
184     SignalId() = default;
185     SignalId( CallId id ) : id( id ) {}
186   };
187   virtual void add_interface_impl( bool fallback, const std::string& pathName,
188                               const ConnectionPtr &connection,
189                               std::vector<std::function<void()>> &destructors,
190                               const std::string& interfaceName,
191                               std::vector< MethodInfo >& dscrMethods,
192                               std::vector< PropertyInfo >& dscrProperties,
193                               std::vector< SignalInfo >& dscrSignals ) = 0;
194   virtual void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const _Eina_Value * ) > cb) = 0;
195   static DBusWrapper *Installed();
196   static void Install(std::unique_ptr<DBusWrapper>);
197
198   StringStorage Strings;
199 };
200
201 namespace detail {
202   enum class MethodType {
203     Method, Getter, Setter
204   };
205 }
206
207 namespace std {
208   template <> struct hash<std::tuple<std::string, std::string, std::string>> {
209     size_t operator () (const std::tuple<std::string, std::string, std::string> &a) const {
210       auto a1 = std::hash<std::string>()(std::get<0>(a));
211       auto a2 = std::hash<std::string>()(std::get<1>(a));
212       auto a3 = std::hash<std::string>()(std::get<2>(a));
213       size_t v = a1;
214       v = (v * 11400714819323198485llu) + a2;
215       v = (v * 11400714819323198485llu) + a3;
216       return v;
217     }
218   };
219   template <> struct hash<std::tuple<std::string, std::string, std::string, detail::MethodType>> {
220     size_t operator () (const std::tuple<std::string, std::string, std::string, detail::MethodType> &a) const {
221       auto a1 = std::hash<std::string>()(std::get<0>(a));
222       auto a2 = std::hash<std::string>()(std::get<1>(a));
223       auto a3 = std::hash<std::string>()(std::get<2>(a));
224       auto a4 = static_cast<size_t>(std::get<3>(a));
225       size_t v = a1;
226       v = (v * 11400714819323198485llu) + a2;
227       v = (v * 11400714819323198485llu) + a3;
228       v = (v * 11400714819323198485llu) + a4;
229       return v;
230     }
231   };
232   template <> struct hash<std::tuple<std::string, std::string, unsigned int>> {
233     size_t operator () (const std::tuple<std::string, std::string, unsigned int> &a) const {
234       auto a1 = std::hash<std::string>()(std::get<0>(a));
235       auto a2 = std::hash<std::string>()(std::get<1>(a));
236       auto a3 = std::get<2>(a);
237       size_t v = a1;
238       v = (v * 11400714819323198485llu) + a2;
239       v = (v * 11400714819323198485llu) + a3;
240       return v;
241     }
242   };
243 }
244 namespace detail {
245   template <typename T> struct DBusSigImpl { enum { value = 0, end = 0 }; };
246   template <typename T> struct DBusSig { enum { value = DBusSigImpl<typename std::decay<T>::type>::value, end = DBusSigImpl<typename std::decay<T>::type>::end }; };
247   template <typename T, typename Q, size_t I, size_t S> struct IndexFromTypeTupleImpl {
248     enum { value = std::is_same<typename std::decay<typename std::tuple_element<I, T>::type>::type, Q>::value ? I : IndexFromTypeTupleImpl<T, Q, I + 1, S>::value };
249   };
250   template <typename T, typename Q, size_t S> struct IndexFromTypeTupleImpl<T, Q, S, S> { enum { value = S }; };
251   template <typename T, typename Q> struct IndexFromTypeTuple {
252     enum { value = IndexFromTypeTupleImpl<T, typename std::decay<Q>::type, 0, std::tuple_size<T>::value>::value };
253   };
254   template <typename T, typename = void> struct Encoder;
255   template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple;
256 }
257 struct TestDBusWrapper : public DBusWrapper
258 {
259   using MethodType = detail::MethodType;
260   ConnectionPtr connection;
261   std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> testMethods;
262   std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> daliMethods;
263   std::unordered_map<std::tuple<std::string, std::string, unsigned int>, std::string> daliSignalsMap;
264   std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const MessagePtr&)>> daliSignals;
265   std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const _Eina_Value *)>> propertyChangeListeners;
266
267   std::vector<std::function<void()>> asyncCalls;
268
269   template <typename T> struct Variant {
270     T value;
271     Variant() = default;
272     Variant(T t) : value(std::move(t)) { }
273   };
274   template <typename ... ARGS> void Encode(const MessagePtr &m, const std::tuple<ARGS...> &args) {
275     auto iter = eldbus_message_iter_get_impl(m, true);
276     detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(*this, iter, args);
277   }
278   template <typename ... ARGS> void Decode(const MessagePtr &m, std::tuple<ARGS...> &args) {
279     auto iter = eldbus_message_iter_get_impl(m, false);
280     detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(*this, args, iter);
281   }
282   MessagePtr newMessage(const std::string &path, const std::string &interface, const std::string &name, bool reply);
283   MessagePtr newReplyMessage(const MessagePtr &m);
284
285   template <typename ... ARGS> void fromTestEmitSignal(std::string path, const std::string &interface, const std::string &name, const std::tuple<ARGS...> &args) {
286     if (path.empty()) throw error{};
287     if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
288     auto msg = newMessage(path, interface, name, false);
289     Encode(msg, args);
290     auto it = daliSignals.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
291     if (it == daliSignals.end()) throw error{};
292     it->second(msg);
293   }
294   static std::shared_ptr<_Eina_Value> createEinaValue(bool);
295   template <typename T> void fromTestChangeProperty(std::string path, const std::string &interface, const std::string &name, T new_value) {
296     auto v = createEinaValue(new_value);
297     if (path.empty()) throw error{};
298     if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
299     auto it = propertyChangeListeners.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
300     if (it == propertyChangeListeners.end()) throw error{};
301     it->second(v.get());
302   }
303   template <typename ... ARGS1, typename ... ARGS2> std::tuple<ARGS1...> fromTestCall(const std::string &path, const std::string &interface, const std::string &name, const std::tuple<ARGS2...> &args) {
304     auto msg = newMessage(path, interface, name, false);
305     Encode(msg, args);
306     auto res = call(daliMethods, "daliMethods", msg, MethodType::Method);
307     std::string a, b;
308     if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
309     std::tuple<ARGS1...> tmp;
310     Decode(res, tmp);
311     return tmp;
312   }
313   template <typename T> T fromTestGet(const std::string &path, const std::string &interface, const std::string &name) {
314     auto msg = newMessage(path, interface, name, false);
315     auto res = call(daliMethods, "daliMethods", msg, MethodType::Getter);
316     std::string a, b;
317     if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
318     std::tuple<T> tmp;
319     Decode(res, tmp);
320     return std::move(std::get<0>(tmp));
321   }
322   template <typename ... ARGS1, typename T> std::tuple<ARGS1...> fromTestSet(const std::string &path, const std::string &interface, const std::string &name, const T &arg) {
323     auto msg = newMessage(path, interface, name, false);
324     Encode(msg, TestDBusWrapper::Variant<T>{ arg });
325     auto res = call(daliMethods, "daliMethods", msg, MethodType::Setter);
326     std::string a, b;
327     if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
328     std::tuple<ARGS1...> tmp;
329     Decode(res, tmp);
330     return tmp;
331   }
332
333   TestDBusWrapper();
334   ~TestDBusWrapper();
335
336   class error : public std::exception {
337     std::shared_ptr<std::ostringstream> temp = std::make_shared<std::ostringstream>();
338     mutable std::string text;
339   public:
340     error() = default;
341
342     template <typename T> error &operator << (T &&t) {
343       *temp << std::forward<T>(t);
344       return *this;
345     }
346     const char *what() const noexcept override {
347       text = temp->str();
348       return text.c_str();
349     }
350   };
351   #define DEFINE_TYPE(name) struct name ## Impl; static name ## Impl *get(const name ## Ptr &);
352   DEFINE_TYPE(Connection)
353   DEFINE_TYPE(Proxy)
354   DEFINE_TYPE(Object)
355   DEFINE_TYPE(Message)
356   DEFINE_TYPE(MessageIter)
357   #undef DEFINE_TYPE
358
359   class Element;
360   using ElementList = std::list<Element>;
361   using ElementMap = std::map<std::string, std::string>;
362   using ElementTuple = std::tuple<
363     uint8_t, uint16_t, uint32_t, uint64_t, int16_t, int32_t, int64_t, double, bool, std::string, ObjectPath,
364     ElementList
365   >;
366
367   class Element {
368     ElementTuple data;
369     char signature_ = 0, end_ = 0, index_ = 0;
370     template <typename T> void set(T &&t, char signature = detail::DBusSig<T>::value) {
371       signature_ = signature;
372       end_ = detail::DBusSig<T>::end;
373       index_ = static_cast<char>(detail::IndexFromTypeTuple<ElementTuple, T>::value);
374       get<T>() = std::forward<T>(t);
375     }
376   public:
377     template <typename T> Element(T &&t, typename std::enable_if<detail::DBusSig<T>::value != 0>::type* = nullptr) { set(std::forward<T>(t)); }
378     Element(ElementList t, int signature) { set(std::move(t), static_cast<char>(signature)); }
379
380     char signature() const { return signature_; }
381     char end() const { return end_; }
382     char index() const { return index_; }
383     bool isContainer() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, ElementList>::value; }
384     template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
385     bool is() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, T>::value; }
386     template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
387     const T &get() const { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
388     template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
389     T &get() { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
390   };
391
392   ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) override;
393
394 #define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
395   void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) override; \
396   bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) override;
397 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
398   eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
399
400   eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
401   eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
402   eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
403   eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
404   eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
405   eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
406   eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
407   eldbus_message_iter_arguments_append_impl_basic(double, d)
408   eldbus_message_iter_arguments_append_impl_basic(bool, b)
409   eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
410   eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
411
412 #undef eldbus_message_iter_arguments_append_impl_basic
413 #undef eldbus_message_iter_arguments_append_impl_basic_impl
414
415   MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) override;
416   MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override;
417   MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) override;
418   MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) override;
419   MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override;
420   bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override;
421   std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override;
422   PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override;
423   std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) override;
424   void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) override;
425   std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override;
426   MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) override;
427   MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) override;
428   PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) override;
429   MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) override;
430   MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) override;
431   ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override;
432   std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) override;
433   ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) override;
434   ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) override;
435   ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) override;
436   void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const _Eina_Value * ) > cb) override;
437   void add_interface_impl( bool fallback, const std::string& pathName,
438                               const ConnectionPtr &connection,
439                               std::vector<std::function<void()>> &destructors,
440                               const std::string& interfaceName,
441                               std::vector< MethodInfo >& dscrMethods,
442                               std::vector< PropertyInfo >& dscrProperties,
443                               std::vector< SignalInfo >& dscrSignals ) override;
444   static bool completed(const MessageIterPtr &iter);
445 private:
446   MessagePtr call(std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> &mp, const std::string &name, const MessagePtr &msg, MethodType type);
447 };
448
449 namespace detail {
450   template <> struct DBusSigImpl<uint8_t> { enum { value = 'y', end = 0 }; };
451   template <> struct DBusSigImpl<uint16_t> { enum { value = 'q', end = 0 }; };
452   template <> struct DBusSigImpl<uint32_t> { enum { value = 'u', end = 0 }; };
453   template <> struct DBusSigImpl<uint64_t> { enum { value = 't', end = 0 }; };
454   template <> struct DBusSigImpl<int16_t> { enum { value = 'n', end = 0 }; };
455   template <> struct DBusSigImpl<int32_t> { enum { value = 'i', end = 0 }; };
456   template <> struct DBusSigImpl<int64_t> { enum { value = 'x', end = 0 }; };
457   template <> struct DBusSigImpl<double> { enum { value = 'd', end = 0 }; };
458   template <> struct DBusSigImpl<bool> { enum { value = 'b', end = 0 }; };
459   template <> struct DBusSigImpl<std::string> { enum { value = 's', end = 0 }; };
460   template <> struct DBusSigImpl<ObjectPath> { enum { value = 'o', end = 0 }; };
461   template <> struct DBusSigImpl<TestDBusWrapper::ElementList> { enum { value = '(', end = ')' }; };
462   template <> struct DBusSigImpl<TestDBusWrapper::ElementMap> { enum { value = '{', end = '}' }; };
463
464   template <typename T> struct Encoder<T, decltype(TestDBusWrapper().eldbus_message_iter_arguments_append_impl(TestDBusWrapper::MessageIterPtr(), T()))> {
465     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
466       w.eldbus_message_iter_arguments_append_impl(tgt, src);
467     }
468     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
469       if (!w.eldbus_message_iter_get_and_next_impl(src, tgt)) throw TestDBusWrapper::error{};
470     }
471   };
472   template <typename T> struct Encoder<T, typename std::enable_if<std::is_enum<T>::value>::type> {
473     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
474       Encoder<typename std::underlying_type<T>::type>::encode(w, tgt, static_cast<typename std::underlying_type<T>::type>(src));
475     }
476     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
477       typename std::underlying_type<T>::type v = 0;
478       Encoder<typename std::underlying_type<T>::type>::decode(w, v, src);
479       tgt = static_cast<T>(v);
480     }
481   };
482   template <typename T> struct Encoder<const T> {
483     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
484       Encoder<T>::encode(w, tgt, src);
485     }
486     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
487       Encoder<T>::decode(w, tgt, src);
488     }
489   };
490   template <typename T> struct Encoder<const T &> {
491     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
492       Encoder<T>::encode(w, tgt, src);
493     }
494     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
495       Encoder<T>::decode(w, tgt, src);
496     }
497   };
498   template <typename T> struct Encoder<T &> {
499     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
500       Encoder<T>::encode(w, tgt, src);
501     }
502     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
503       Encoder<T>::decode(w, tgt, src);
504     }
505   };
506   template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple {
507     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
508       Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::encode(w, tgt, std::get<I>(src));
509       EncoderTuple<I + 1, S, ARGS...>::encode(w, tgt, src);
510     }
511     static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
512       Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::decode(w, std::get<I>(tgt), src);
513       EncoderTuple<I + 1, S, ARGS...>::decode(w, tgt, src);
514     }
515   };
516   template <size_t S, typename ... ARGS> struct EncoderTuple<S, S, ARGS...> {
517     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) { }
518     static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) { }
519   };
520   template <typename ...ARGS> struct Encoder<std::tuple<ARGS...>> {
521     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
522       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'r', "");
523       EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(w, var, src);
524     }
525     static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
526       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'r' );
527       if( !s ) throw TestDBusWrapper::error{};
528       EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(w, tgt, s);
529     }
530   };
531   template <typename A, typename B> struct Encoder<std::pair<A, B>> {
532     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::pair<A, B> &src, char type = 'r') {
533       auto var = w.eldbus_message_iter_container_new_impl( tgt, type, "");
534       Encoder<A>::encode(w, var, src.first);
535       Encoder<B>::encode(w, var, src.second);
536     }
537     static void decode(TestDBusWrapper &w, std::pair<A, B> &tgt, const TestDBusWrapper::MessageIterPtr &src, char type = 'r') {
538       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, type );
539       if( !s ) throw TestDBusWrapper::error{};
540       Encoder<A>::decode(w, tgt.first, s);
541       Encoder<B>::decode(w, tgt.second, s);
542     }
543   };
544   template <typename T> struct Encoder<TestDBusWrapper::Variant<T>> {
545     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const TestDBusWrapper::Variant<T> &src) {
546       //w.eldbus_message_iter_arguments_append_impl(tgt, src);
547       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'v', "");
548       Encoder<T>::encode(w, var, src.value);
549     }
550     static void decode(TestDBusWrapper &w, TestDBusWrapper::Variant<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
551       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'v' );
552       if( !s ) throw TestDBusWrapper::error{};
553       Encoder<T>::decode(w, tgt.value, s);
554     }
555   };
556   template <typename T> struct Encoder<std::vector<T>> {
557     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::vector<T> &src) {
558       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
559       for(auto &q : src)
560         Encoder<T>::encode(w, var, q);
561     }
562     static void decode(TestDBusWrapper &w, std::vector<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
563       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
564       if( !s ) throw TestDBusWrapper::error{};
565       while(!TestDBusWrapper::completed(s)) {
566         tgt.push_back({});
567         Encoder<T>::decode(w, tgt.back(), s);
568       }
569     }
570   };
571   template <typename K, typename V> struct Encoder<std::unordered_map<K,V>> {
572     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::unordered_map<K,V> &src) {
573       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
574       for(auto &q : src){
575         Encoder<typename std::unordered_map<K,V>::value_type>::encode(w, var, q, 'e');
576       }
577     }
578     static void decode(TestDBusWrapper &w, std::unordered_map<K,V> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
579       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
580       if( !s ) throw TestDBusWrapper::error{};
581       while(!TestDBusWrapper::completed(s)) {
582         std::pair<K, V> tmp;
583         Encoder<std::pair<K,V>>::decode(w, tmp, s, 'e');
584         tgt.insert(std::move(tmp));
585       }
586     }
587   };
588   template <typename T, size_t I> struct Encoder<std::array<T, I>> {
589     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::array<T, I> &src) {
590       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
591       for(auto &q : src)
592         Encoder<T>::encode(w, var, q);
593     }
594     static void decode(TestDBusWrapper &w, std::array<T, I> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
595       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
596       if( !s ) throw TestDBusWrapper::error{};
597       size_t i = 0;
598       while(!TestDBusWrapper::completed(s)) {
599         if(i >= tgt.size()) throw TestDBusWrapper::error{};
600         Encoder<T>::decode(w, tgt[i], s);
601         ++i;
602       }
603       if( i!=tgt.size()) throw TestDBusWrapper::error{};
604     }
605   };
606   template <> struct Encoder<Dali::Accessibility::Address> {
607     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const Dali::Accessibility::Address &src) {
608       Encoder<std::tuple<std::string, ObjectPath>>::encode(w, tgt,std::tuple<std::string, ObjectPath> {
609         src.GetBus(), ObjectPath{ "/org/a11y/atspi/accessible/" + src.GetPath() } }
610       );
611     }
612     static void decode(TestDBusWrapper &w, Dali::Accessibility::Address &tgt, const TestDBusWrapper::MessageIterPtr &src) {
613       std::tuple<std::string, ObjectPath> tmp;
614       Encoder<std::tuple<std::string, ObjectPath>>::decode(w, tmp, src);
615       static const size_t prefixSize = std::string{ "/org/a11y/atspi/accessible/" }.size();
616       tgt = { std::move(std::get<0>(tmp)), std::get<1>(tmp).value.substr(prefixSize) };
617     }
618   };
619   template <> struct Encoder<const char*> {
620     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const char *src) {
621       Encoder<std::string>::encode(w, tgt, src);
622     }
623   };
624 }
625 /// \endcond
626
627 #define DBUS_DEBUG( ... )                                \
628   do                                                     \
629   {                                                      \
630     DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \
631   } while( 0 )
632
633 #define DBUS_W DBusWrapper::Installed()
634
635 /**
636  * @brief Template based, single file, wrapper library around eldbus for DBUS based communication.
637  *
638  * Main motivation was missing asynchronous calls in AT-SPI library and difficulties,
639  * when using eldbus from C++.
640  *
641  * The library:
642  * - takes care of marshalling arguments to and from DBUS calls.
643  * - allows synchronous and asynchronous calls.
644  * - allows synchronous and asynchronous listeners on signals.
645  * - manages all involved objects' lifetimes.
646  * - errors are passed as optional-alike objects, no exceptions are used.
647  * - allows setting additional debug-print function for more details about
648  *   what's going on
649  *
650  * DBUS's method signatures (and expected return values) are specified as template argument,
651  * using functor syntax. For example:
652  * \code{.cpp}
653  * auto dbus = DBusClient{ ... };
654  * auto v = dbus.method<std::tuple<int, float>(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe");
655  * \endcode
656  * means (synchronous) call on dbus object, which takes three arguments (thus making call signature \b dds)
657  * of types float, float and string (float will be automatically converted to double).
658  * Expected return value is std::tuple<int, float>, which gives signature <B>(id)</B> - std::tuple acts
659  * as struct container. Returned value v will be of type ValueOrError<std::tuple<int, float>>.\n
660  * Slightly different (asynchronous) example:
661  * \code{.cpp}
662  * auto dbus = DBusClient{ ... };
663  * std::function<void(ValueOrError<int, float>)> callback;
664  * dbus.method<ValueOrError<int, float>(float, float, std::string)>("foo").asyncCall(callback, 1.0f, 2.0f, "qwe");
665  * \endcode
666  * Now the call takes the same arguments and has the same signature. But expected values are different -
667  * now the signature is simply \b id. ValueOrError acts in this case as placeholder for list of values,
668  * which DBUS allows as return data. The call itself is asynchronous - instead of expecting reply
669  * you need to pass a callback, which will be called either with received data and error message.
670  *
671  * Library is not thread-safe, the same object shouldn't be called from different threads without
672  * synchronization. There's no guarantee, that callbacks will be executed on the same thread.
673  */
674 namespace DBus
675 {
676 /// \cond
677 class DBusServer;
678 class DBusClient;
679 class DBusInterfaceDescription;
680
681 /**
682  * @brief Formats debug message and calls debug printer (if any) with it
683  */
684 void debugPrint( const char* file, size_t line, const char* format, ... );
685
686 /**
687  * @brief Sets debug printer callback, which will be called with debug messages
688  *
689  * Callback will be called in various moments of DBus activity. First value passed to callback
690  * is pointer to text, second it's length. Text is ended with 0 (not counted towards it's size),
691  * user can safely printf it.
692  */
693 void setDebugPrinter( std::function< void( const char*, size_t ) > );
694
695 struct Error
696 {
697   std::string message;
698
699   Error() = default;
700   Error( std::string msg ) : message( std::move( msg ) )
701   {
702     bart_assert( !message.empty() );
703   }
704 };
705
706 struct Success
707 {
708 };
709 /// \endcond
710
711 /**
712  * @brief Value representing data, that came from DBUS or error message
713  *
714  * Object of this class either helds series of values (of types ARGS...)
715  * or error message. This object will be true in boolean context, if has data
716  * and false, if an error occured.
717  * It's valid to create ValueOrError object with empty argument list or void:
718  * \code{.cpp}
719  * ValueOrError<> v1;
720  * ValueOrError<void> v2;
721  * \endcode
722  * Both mean the same - ValueOrError containing no real data and being a marker,
723  * wherever operation successed or failed and containing possible error message.
724  */
725 template < typename... ARGS >
726 class ValueOrError
727 {
728 public:
729   /**
730    * @brief Empty constructor. Valid only, if all ARGS types are default constructible.
731    */
732   ValueOrError() = default;
733
734   /**
735    * @brief Value constructor.
736    *
737    * This will be initialized as success with passed in values.
738    */
739   ValueOrError( ARGS... t ) : value( std::move( t )... ) {}
740
741   /**
742    * @brief Alternative Value constructor.
743    *
744    * This will be initialized as success with passed in values.
745    */
746   ValueOrError( std::tuple< ARGS... > t ) : value( std::move( t ) ) {}
747
748   /**
749    * @brief Error constructor. This will be initialized as failure with given error message.
750    */
751   ValueOrError( Error e ) : error( std::move( e ) )
752   {
753     bart_assert( !error.message.empty() );
754   }
755
756   /**
757    * @brief bool operator.
758    *
759    * Returns true, if operation was successful (getValues member is callable), or false
760    * when operation failed (getError is callable).
761    */
762   explicit operator bool() const
763   {
764     return error.message.empty();
765   }
766
767   /**
768    * @brief Returns error message object.
769    *
770    * Returns object containing error message associated with the failed operation.
771    * Only callable, if operation actually failed, otherwise will bart_assert.
772    */
773   const Error& getError() const
774   {
775     return error;
776   }
777
778   /**
779    * @brief Returns modifiable tuple of held data.
780    *
781    * Returns reference to the internal tuple containing held data.
782    * User can modify (or move) data safely.
783    * Only callable, if operation actually successed, otherwise will bart_assert.
784    */
785   std::tuple< ARGS... >& getValues()
786   {
787     bart_assert( *this );
788     return value;
789   }
790
791   /**
792    * @brief Returns const tuple of held data.
793    *
794    * Returns const reference to the internal tuple containing held data.
795    * Only callable, if operation actually successed, otherwise will bart_assert.
796    */
797   const std::tuple< ARGS... >& getValues() const
798   {
799     bart_assert( *this );
800     return value;
801   }
802
803 protected:
804   /// \cond
805   std::tuple< ARGS... > value;
806   Error error;
807   /// \endcond
808 };
809
810 /// \cond
811 template <>
812 class ValueOrError<>
813 {
814 public:
815   ValueOrError() = default;
816   ValueOrError( std::tuple<> t ) {}
817   ValueOrError( Error e ) : error( std::move( e ) )
818   {
819     bart_assert( !error.message.empty() );
820   }
821
822   explicit operator bool() const
823   {
824     return error.message.empty();
825   }
826   const Error& getError() const
827   {
828     return error;
829   }
830   std::tuple<>& getValues()
831   {
832     bart_assert( *this );
833     static std::tuple<> t;
834     return t;
835   }
836   std::tuple<> getValues() const
837   {
838     bart_assert( *this );
839     return {};
840   }
841
842 protected:
843   Error error;
844 };
845
846 template <>
847 class ValueOrError< void >
848 {
849 public:
850   ValueOrError() = default;
851   ValueOrError( Success ) {}
852   ValueOrError( Error e ) : error( std::move( e ) )
853   {
854     bart_assert( !error.message.empty() );
855   }
856
857   explicit operator bool() const
858   {
859     return error.message.empty();
860   }
861   const Error& getError() const
862   {
863     return error;
864   }
865   std::tuple<>& getValues()
866   {
867     bart_assert( *this );
868     static std::tuple<> t;
869     return t;
870   }
871   std::tuple<> getValues() const
872   {
873     bart_assert( *this );
874     return {};
875   }
876
877 protected:
878   Error error;
879 };
880
881 using ObjectPath = ObjectPath;
882
883 /// \endcond
884
885 /**
886  * @brief Class used to marshall DBUS's variant type
887  *
888  * Minimalistic class, that allows user to specify DBUS variant type
889  * as argument or return value. You need to pass real type hidden under variant as
890  * template type \b A. At this point library doesn't allow to expected one of few classes
891  * as return data in variant. So for example user can't specify method call, which on return
892  * expects DBUS variant holding either string or int.
893  */
894 template < typename A >
895 struct EldbusVariant
896 {
897   A value;
898 };
899
900 /**
901  * @brief Namespace for private, internal functions and classes
902  */
903 namespace detail
904 {
905 /// \cond
906 template < typename T, typename = void >
907 struct signature;
908 template < typename... ARGS >
909 struct signature< std::tuple< ARGS... > >;
910 template < typename A, typename B >
911 struct signature< std::pair< A, B > >;
912 template < typename A >
913 struct signature< std::vector< A > >;
914 template < typename A, size_t N >
915 struct signature< std::array< A, N > >;
916 template < typename A, typename B >
917 struct signature< std::unordered_map< A, B > >;
918 template < typename A, typename B >
919 struct signature< std::map< A, B > >;
920 /// \endcond
921
922 /**
923  * @brief Signature class for marshalling uint8 type.
924  */
925 template <>
926 struct signature< uint8_t >
927 {
928   /**
929    * @brief Returns name of type marshalled, for informative purposes
930    */
931   static std::string name()
932   {
933     return "uint8_t";
934   }
935
936   /**
937    * @brief Returns DBUS' signature of type marshalled
938    */
939   static std::string sig()
940   {
941     return "y";
942   }
943
944   /**
945    * @brief Marshals value v as marshalled type into message
946    */
947   static void set( const DBusWrapper::MessageIterPtr &iter, uint8_t v )
948   {
949     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
950   }
951
952   /**
953    * @brief Marshals value from marshalled type into variable v
954    */
955   static bool get( const DBusWrapper::MessageIterPtr &iter, uint8_t& v )
956   {
957     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
958   }
959 };
960
961 /**
962  * @brief Signature class for marshalling uint16 type.
963  */
964 template <>
965 struct signature< uint16_t >
966 {
967   /**
968    * @brief Returns name of type marshalled, for informative purposes
969    */
970   static std::string name()
971   {
972     return "uint16_t";
973   }
974
975   /**
976    * @brief Returns DBUS' signature of type marshalled
977    */
978   static std::string sig()
979   {
980     return "q";
981   }
982
983   /**
984    * @brief Marshals value v as marshalled type into message
985    */
986   static void set( const DBusWrapper::MessageIterPtr &iter, uint16_t v )
987   {
988     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
989   }
990
991   /**
992    * @brief Marshals value from marshalled type into variable v
993    */
994   static bool get( const DBusWrapper::MessageIterPtr &iter, uint16_t& v )
995   {
996     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
997   }
998 };
999
1000 /**
1001  * @brief Signature class for marshalling uint32 type.
1002  */
1003 template <>
1004 struct signature< uint32_t >
1005 {
1006   /**
1007    * @brief Returns name of type marshalled, for informative purposes
1008    */
1009   static std::string name()
1010   {
1011     return "uint32_t";
1012   }
1013
1014   /**
1015    * @brief Returns DBUS' signature of type marshalled
1016    */
1017   static std::string sig()
1018   {
1019     return "u";
1020   }
1021
1022   /**
1023    * @brief Marshals value v as marshalled type into message
1024    */
1025   static void set( const DBusWrapper::MessageIterPtr &iter, uint32_t v )
1026   {
1027     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1028   }
1029
1030   /**
1031    * @brief Marshals value from marshalled type into variable v
1032    */
1033   static bool get( const DBusWrapper::MessageIterPtr &iter, uint32_t& v )
1034   {
1035     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1036   }
1037 };
1038
1039 /**
1040  * @brief Signature class for marshalling uint64 type.
1041  */
1042 template <>
1043 struct signature< uint64_t >
1044 {
1045   /**
1046    * @brief Returns name of type marshalled, for informative purposes
1047    */
1048   static std::string name()
1049   {
1050     return "uint64_t";
1051   }
1052
1053   /**
1054    * @brief Returns DBUS' signature of type marshalled
1055    */
1056   static std::string sig()
1057   {
1058     return "t";
1059   }
1060
1061   /**
1062    * @brief Marshals value v as marshalled type into message
1063    */
1064   static void set( const DBusWrapper::MessageIterPtr &iter, uint64_t v )
1065   {
1066     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1067   }
1068
1069   /**
1070    * @brief Marshals value from marshalled type into variable v
1071    */
1072   static bool get( const DBusWrapper::MessageIterPtr &iter, uint64_t& v )
1073   {
1074     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1075   }
1076 };
1077
1078 /**
1079  * @brief Signature class for marshalling int16 type.
1080  */
1081 template <>
1082 struct signature< int16_t >
1083 {
1084   /**
1085    * @brief Returns name of type marshalled, for informative purposes
1086    */
1087   static std::string name()
1088   {
1089     return "int16_t";
1090   }
1091
1092   /**
1093    * @brief Returns DBUS' signature of type marshalled
1094    */
1095   static std::string sig()
1096   {
1097     return "n";
1098   }
1099
1100   /**
1101    * @brief Marshals value v as marshalled type into message
1102    */
1103   static void set( const DBusWrapper::MessageIterPtr &iter, int16_t v )
1104   {
1105     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1106   }
1107
1108   /**
1109    * @brief Marshals value from marshalled type into variable v
1110    */
1111   static bool get( const DBusWrapper::MessageIterPtr &iter, int16_t& v )
1112   {
1113     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1114   }
1115 };
1116
1117 /**
1118  * @brief Signature class for marshalling int32 type.
1119  */
1120 template <>
1121 struct signature< int32_t >
1122 {
1123   /**
1124    * @brief Returns name of type marshalled, for informative purposes
1125    */
1126   static std::string name()
1127   {
1128     return "int32_t";
1129   }
1130
1131   /**
1132    * @brief Returns DBUS' signature of type marshalled
1133    */
1134   static std::string sig()
1135   {
1136     return "i";
1137   }
1138
1139   /**
1140    * @brief Marshals value v as marshalled type into message
1141    */
1142   static void set( const DBusWrapper::MessageIterPtr &iter, int32_t v )
1143   {
1144     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1145   }
1146
1147   /**
1148    * @brief Marshals value from marshalled type into variable v
1149    */
1150   static bool get( const DBusWrapper::MessageIterPtr &iter, int32_t& v )
1151   {
1152     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1153   }
1154 };
1155
1156 /**
1157  * @brief Signature class for marshalling int64 type.
1158  */
1159 template <>
1160 struct signature< int64_t >
1161 {
1162   /**
1163    * @brief Returns name of type marshalled, for informative purposes
1164    */
1165   static std::string name()
1166   {
1167     return "int64_t";
1168   }
1169
1170   /**
1171    * @brief Returns DBUS' signature of type marshalled
1172    */
1173   static std::string sig()
1174   {
1175     return "x";
1176   }
1177
1178   /**
1179    * @brief Marshals value v as marshalled type into message
1180    */
1181   static void set( const DBusWrapper::MessageIterPtr &iter, int64_t v )
1182   {
1183     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1184   }
1185
1186   /**
1187    * @brief Marshals value from marshalled type into variable v
1188    */
1189   static bool get( const DBusWrapper::MessageIterPtr &iter, int64_t& v )
1190   {
1191     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1192   }
1193 };
1194
1195 /**
1196  * @brief Signature class for marshalling double type.
1197  */
1198 template <>
1199 struct signature< double >
1200 {
1201   /**
1202    * @brief Returns name of type marshalled, for informative purposes
1203    */
1204   static std::string name()
1205   {
1206     return "double";
1207   }
1208
1209   /**
1210    * @brief Returns DBUS' signature of type marshalled
1211    */
1212   static std::string sig()
1213   {
1214     return "d";
1215   }
1216
1217   /**
1218    * @brief Marshals value v as marshalled type into message
1219    */
1220   static void set( const DBusWrapper::MessageIterPtr &iter, double v )
1221   {
1222     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1223   }
1224
1225   /**
1226    * @brief Marshals value from marshalled type into variable v
1227    */
1228   static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
1229   {
1230     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1231   }
1232
1233   /**
1234    * @brief Marshals value from marshalled type into variable v
1235    */
1236   static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
1237   {
1238     double v = 0;
1239     auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1240     v2 = static_cast< float >( v );
1241     return r;
1242   }
1243 };
1244
1245 /**
1246  * @brief Signature class for marshalling float type.
1247  */
1248 template <>
1249 struct signature< float >
1250 {
1251   /**
1252    * @brief Returns name of type marshalled, for informative purposes
1253    */
1254   static std::string name()
1255   {
1256     return "float";
1257   }
1258
1259   /**
1260    * @brief Returns DBUS' signature of type marshalled
1261    */
1262   static std::string sig()
1263   {
1264     return "d";
1265   }
1266
1267   /**
1268    * @brief Marshals value v as marshalled type into message
1269    */
1270   static void set( const DBusWrapper::MessageIterPtr &iter, float v )
1271   {
1272     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1273   }
1274
1275   /**
1276    * @brief Marshals value from marshalled type into variable v
1277    */
1278   static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
1279   {
1280     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1281   }
1282
1283   /**
1284    * @brief Marshals value from marshalled type into variable v
1285    */
1286   static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
1287   {
1288     double v = 0;
1289     auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1290     v2 = static_cast< float >( v );
1291     return r;
1292   }
1293 };
1294
1295 /**
1296  * @brief Signature class for marshalling boolean type.
1297  */
1298 template <>
1299 struct signature< bool >
1300 {
1301   /**
1302    * @brief Returns name of type marshalled, for informative purposes
1303    */
1304   static std::string name()
1305   {
1306     return "bool";
1307   }
1308
1309   /**
1310    * @brief Returns DBUS' signature of type marshalled
1311    */
1312   static std::string sig()
1313   {
1314     return "b";
1315   }
1316
1317   /**
1318    * @brief Marshals value v as marshalled type into message
1319    */
1320   static void set( const DBusWrapper::MessageIterPtr &iter, bool v )
1321   {
1322     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1323   }
1324
1325   /**
1326    * @brief Marshals value from marshalled type into variable v
1327    */
1328   static bool get( const DBusWrapper::MessageIterPtr &iter, bool& v )
1329   {
1330     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1331   }
1332 };
1333
1334 template < typename T >
1335 struct signature< T, typename std::enable_if< std::is_enum< T >::value, void >::type >
1336 {
1337   /**
1338    * @brief Returns name of type marshalled, for informative purposes
1339    */
1340   static std::string name()
1341   {
1342     return "enum";
1343   }
1344
1345   /**
1346    * @brief Returns DBUS' signature of type marshalled
1347    */
1348   static std::string sig()
1349   {
1350     return signature<typename std::underlying_type<T>::type>::sig();
1351   }
1352
1353   /**
1354    * @brief Marshals value v as marshalled type into message
1355    */
1356   static void set( const DBusWrapper::MessageIterPtr &iter, T v )
1357   {
1358     signature<typename std::underlying_type<T>::type>::set(iter, static_cast< int64_t >( v ));
1359   }
1360
1361   /**
1362    * @brief Marshals value from marshalled type into variable v
1363    */
1364   static bool get( const DBusWrapper::MessageIterPtr &iter, T& v )
1365   {
1366     typename std::underlying_type<T>::type q = 0;
1367     if (!signature<typename std::underlying_type<T>::type>::get(iter, q))
1368       return false;
1369
1370     v = static_cast< T >( q );
1371     return true;
1372   }
1373 };
1374
1375 /**
1376  * @brief Signature class for marshalling string type.
1377  *
1378  * Both (const) char * and std::string types are accepted as value to send.
1379  * Only std::string is accepted as value to receive.
1380  */
1381 template <>
1382 struct signature< std::string >
1383 {
1384   /**
1385    * @brief Returns name of type marshalled, for informative purposes
1386    */
1387   static std::string name()
1388   {
1389     return "string";
1390   }
1391
1392   /**
1393    * @brief Returns DBUS' signature of type marshalled
1394    */
1395   static std::string sig()
1396   {
1397     return "s";
1398   }
1399
1400   /**
1401    * @brief Marshals value v as marshalled type into message
1402    */
1403   static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
1404   {
1405     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1406   }
1407
1408 // /**
1409 //  * @brief Marshals value v as marshalled type into message
1410 //  */
1411 //  static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
1412 //  {
1413 //    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1414 //  }
1415
1416   /**
1417    * @brief Marshals value from marshalled type into variable v
1418    */
1419   static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
1420   {
1421     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1422   }
1423 };
1424
1425 template <>
1426 struct signature< ObjectPath >
1427 {
1428   /**
1429    * @brief Returns name of type marshalled, for informative purposes
1430    */
1431   static std::string name()
1432   {
1433     return "path";
1434   }
1435
1436   /**
1437    * @brief Returns DBUS' signature of type marshalled
1438    */
1439   static std::string sig()
1440   {
1441     return "o";
1442   }
1443
1444   /**
1445    * @brief Marshals value v as marshalled type into message
1446    */
1447   static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
1448   {
1449     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1450   }
1451
1452   /**
1453    * @brief Marshals value v as marshalled type into message
1454    */
1455   static void set( const DBusWrapper::MessageIterPtr &iter, const ObjectPath& v )
1456   {
1457     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1458   }
1459
1460   /**
1461    * @brief Marshals value v as marshalled type into message
1462    */
1463   static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
1464   {
1465     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1466   }
1467
1468   /**
1469    * @brief Marshals value from marshalled type into variable v
1470    */
1471   static bool get( const DBusWrapper::MessageIterPtr &iter, ObjectPath& v )
1472   {
1473     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1474   }
1475
1476   /**
1477    * @brief Marshals value from marshalled type into variable v
1478    */
1479   static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
1480   {
1481     ObjectPath q;
1482     if (!DBUS_W->eldbus_message_iter_get_and_next_impl(iter, q)) return false;
1483     v = std::move(q.value);
1484     return true;
1485   }
1486 };
1487
1488 /**
1489  * @brief Signature class for marshalling (const) char * type.
1490  *
1491  * Both (const) char * and std::string types are accepted as value to send.
1492  * You can't use (const) char * variable type to receive value.
1493  */
1494 template <>
1495 struct signature< char* >
1496 {
1497   /**
1498    * @brief Returns name of type marshalled, for informative purposes
1499    */
1500   static std::string name()
1501   {
1502     return "string";
1503   }
1504
1505   /**
1506    * @brief Returns DBUS' signature of type marshalled
1507    */
1508   static std::string sig()
1509   {
1510     return "s";
1511   }
1512
1513   /**
1514    * @brief Marshals value v as marshalled type into message
1515    */
1516   static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
1517   {
1518     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1519   }
1520
1521   /**
1522    * @brief Marshals value v as marshalled type into message
1523    */
1524   static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
1525   {
1526     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, std::string{ v });
1527   }
1528 };
1529 /// \cond
1530
1531 template < size_t INDEX, typename A, typename... ARGS >
1532 struct signature_tuple_element_type_helper
1533 {
1534   using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type;
1535 };
1536
1537 template < typename A, typename... ARGS >
1538 struct signature_tuple_element_type_helper< 0, A, ARGS... >
1539 {
1540   using type = A;
1541 };
1542 /// \endcond
1543
1544 /**
1545  * @brief Helper class to marshall tuples
1546  *
1547  * This class marshals all elements of the tuple value starting at the index INDEX
1548  * and incrementing. This class recursively calls itself with increasing INDEX value
1549  * until INDEX is equal to SIZE, where recursive calling ends.
1550  */
1551 template < size_t INDEX, size_t SIZE, typename... ARGS >
1552 struct signature_tuple_helper
1553 {
1554   using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type;
1555
1556   /**
1557    * @brief Returns name of type marshalled, for informative purposes
1558    */
1559   static std::string name()
1560   {
1561     if( INDEX + 1 >= SIZE )
1562       return signature< current_type >::name();
1563     return signature< current_type >::name() + ", " + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::name();
1564   }
1565
1566   /**
1567    * @brief Returns DBUS' signature of type marshalled
1568    */
1569   static std::string sig()
1570   {
1571     return signature< current_type >::sig() + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::sig();
1572   }
1573
1574   /**
1575    * @brief Marshals value v as marshalled type into message
1576    */
1577   static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
1578   {
1579     signature< current_type >::set( iter, std::get< INDEX >( args ) );
1580     signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set( iter, args );
1581   }
1582
1583   /**
1584    * @brief Marshals value from marshalled type into variable v
1585    */
1586   static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
1587   {
1588     return signature< current_type >::get( iter, std::get< INDEX >( args ) ) &&
1589            signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get( iter, args );
1590   }
1591 };
1592
1593 /**
1594  * @brief Helper class to marshall tuples
1595  *
1596  * This class marks end of the tuple marshalling. Members of this class are called
1597  * when INDEX value is equal to SIZE.
1598  */
1599 template < size_t SIZE, typename... ARGS >
1600 struct signature_tuple_helper< SIZE, SIZE, ARGS... >
1601 {
1602   /**
1603    * @brief Returns name of type marshalled, for informative purposes
1604    */
1605   static std::string name()
1606   {
1607     return "";
1608   }
1609
1610   /**
1611    * @brief Returns DBUS' signature of type marshalled
1612    */
1613   static std::string sig()
1614   {
1615     return "";
1616   }
1617
1618   /**
1619    * @brief Marshals value v as marshalled type into message
1620    */
1621   static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
1622   {
1623   }
1624
1625   /**
1626    * @brief Marshals value from marshalled type into variable v
1627    */
1628   static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
1629   {
1630     return true;
1631   }
1632 };
1633
1634 /**
1635  * @brief Signature class for marshalling tuple of values
1636  *
1637  * This class marshalls tuple of values. This represents
1638  * DBUS struct typle, encoded with character 'r'
1639  */
1640 template < typename... ARGS >
1641 struct signature< std::tuple< ARGS... > >
1642 {
1643   /**
1644    * @brief Returns name of type marshalled, for informative purposes
1645    */
1646   static std::string name()
1647   {
1648     return "tuple<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
1649   }
1650
1651   /**
1652    * @brief Returns DBUS' signature of type marshalled
1653    */
1654   static std::string sig()
1655   {
1656     return "(" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig() + ")";
1657   }
1658
1659   /**
1660    * @brief Marshals value v as marshalled type into message
1661    */
1662   static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
1663   {
1664     auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'r', "");
1665     signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( entry, args );
1666   }
1667
1668   /**
1669    * @brief Marshals value from marshalled type into variable v
1670    */
1671   static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
1672   {
1673     auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
1674     if (!entry) return false;
1675     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( entry, args );
1676   }
1677 };
1678
1679 /**
1680  * @brief Signature class for marshalling ValueOrError template type
1681  *
1682  * ValueOrError template type is used to marshall list of values passed to
1683  * DBUS (or received from) at the "top" level. For example ss(s) is represented as
1684  * \code{.cpp} ValueOrError<std::string, std::string, std::tuple<std::string>> \endcode
1685  * While (ss(s)) is represented as
1686  * \code{.cpp} std::tuple<std::string, std::string, std::tuple<std::string>> \endcode
1687  * or
1688  * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \endcode
1689  */
1690 template < typename... ARGS >
1691 struct signature< ValueOrError< ARGS... > >
1692 {
1693   /**
1694    * @brief Returns name of type marshalled, for informative purposes
1695    */
1696   static std::string name()
1697   {
1698     return "ValueOrError<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
1699   }
1700
1701   /**
1702    * @brief Returns DBUS' signature of type marshalled
1703    */
1704   static std::string sig()
1705   {
1706     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig();
1707   }
1708
1709   /**
1710    * @brief Marshals value v as marshalled type into message
1711    */
1712   static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< ARGS... >& args )
1713   {
1714     signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( iter, args.getValues() );
1715   }
1716
1717   /**
1718    * @brief Marshals value from marshalled type into variable v
1719    */
1720   static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< ARGS... >& args )
1721   {
1722     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( iter, args.getValues() );
1723   }
1724 };
1725
1726 /**
1727  * @brief Signature class for marshalling ValueOrError<void> type
1728  */
1729 template <>
1730 struct signature< ValueOrError< void > >
1731 {
1732   /**
1733    * @brief Returns name of type marshalled, for informative purposes
1734    */
1735   static std::string name()
1736   {
1737     return "ValueOrError<void>";
1738   }
1739
1740   /**
1741    * @brief Returns DBUS' signature of type marshalled
1742    */
1743   static std::string sig()
1744   {
1745     return "";
1746   }
1747
1748   /**
1749    * @brief Marshals value v as marshalled type into message
1750    */
1751   static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< void >& args )
1752   {
1753   }
1754
1755   /**
1756    * @brief Marshals value from marshalled type into variable v
1757    */
1758   static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< void >& args )
1759   {
1760     return true;
1761   }
1762 };
1763
1764 /**
1765  * @brief Signature class for marshalling ValueOrError<> type
1766  */
1767 template <>
1768 struct signature< ValueOrError<> >
1769 {
1770   /**
1771    * @brief Returns name of type marshalled, for informative purposes
1772    */
1773   static std::string name()
1774   {
1775     return "ValueOrError<>";
1776   }
1777
1778   /**
1779    * @brief Returns DBUS' signature of type marshalled
1780    */
1781   static std::string sig()
1782   {
1783     return "";
1784   }
1785
1786   /**
1787    * @brief Marshals value v as marshalled type into message
1788    */
1789   static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError<>& args )
1790   {
1791   }
1792
1793   /**
1794    * @brief Marshals value from marshalled type into variable v
1795    */
1796   static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError<>& args )
1797   {
1798     return true;
1799   }
1800 };
1801
1802 /**
1803  * @brief Signature class for marshalling pair of types
1804  */
1805 template < typename A, typename B >
1806 struct signature< std::pair< A, B > >
1807 {
1808   /**
1809    * @brief Returns name of type marshalled, for informative purposes
1810    */
1811   static std::string name()
1812   {
1813     return "pair<" + signature_tuple_helper< 0, 2, A, B >::name() + ">";
1814   }
1815
1816   /**
1817    * @brief Returns DBUS' signature of type marshalled
1818    */
1819   static std::string sig()
1820   {
1821     return "(" + signature_tuple_helper< 0, 2, A, B >::sig() + ")";
1822   }
1823
1824   /**
1825    * @brief Marshals value v as marshalled type into message
1826    */
1827   static void set( const DBusWrapper::MessageIterPtr &iter, const std::pair< A, B >& ab, bool dictionary = false )
1828   {
1829     auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, dictionary ? 'e' : 'r', "");
1830     signature_tuple_helper< 0, 2, A, B >::set( entry, ab );
1831   }
1832
1833   /**
1834    * @brief Marshals value from marshalled type into variable v
1835    */
1836   static bool get( const DBusWrapper::MessageIterPtr &iter, std::pair< A, B >& ab )
1837   {
1838     auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
1839     if (!entry) {
1840       entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, '{' );
1841       if (!entry) return false;
1842     }
1843
1844     std::tuple< A, B > ab_tmp;
1845     auto z = signature_tuple_helper< 0, 2, A, B >::get( entry, ab_tmp );
1846     if( z )
1847     {
1848       ab.first = std::move( std::get< 0 >( ab_tmp ) );
1849       ab.second = std::move( std::get< 1 >( ab_tmp ) );
1850     }
1851     return z;
1852   }
1853 };
1854
1855 /**
1856  * @brief Signature class for marshalling std::vector template type
1857  *
1858  * This marshals container's content as DBUS a ascii character type code.
1859  */
1860 template < typename A >
1861 struct signature< std::vector< A > >
1862 {
1863   /**
1864    * @brief Returns name of type marshalled, for informative purposes
1865    */
1866   static std::string name()
1867   {
1868     return "vector<" + signature< A >::name() + ">";
1869   }
1870
1871   /**
1872    * @brief Returns DBUS' signature of type marshalled
1873    */
1874   static std::string sig()
1875   {
1876     return "a" + signature< A >::sig();
1877   }
1878
1879   /**
1880    * @brief Marshals value v as marshalled type into message
1881    */
1882   static void set( const DBusWrapper::MessageIterPtr &iter, const std::vector< A >& v )
1883   {
1884     auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
1885     bart_assert( lst );
1886     for( auto& a : v )
1887     {
1888       signature< A >::set( lst, a );
1889     }
1890   }
1891
1892   /**
1893    * @brief Marshals value from marshalled type into variable v
1894    */
1895   static bool get( const DBusWrapper::MessageIterPtr &iter, std::vector< A >& v )
1896   {
1897     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
1898     if (!s) return false;
1899     v.clear();
1900     A a;
1901     while( signature< A >::get( s, a ) )
1902       v.push_back( std::move( a ) );
1903
1904     return true;
1905   }
1906 };
1907
1908 /**
1909  * @brief Signature class for marshalling std::array template type
1910  *
1911  * This marshals container's content as DBUS a ascii character type code.
1912  */
1913 template < typename A, size_t N >
1914 struct signature< std::array< A, N > >
1915 {
1916   /**
1917    * @brief Returns name of type marshalled, for informative purposes
1918    */
1919   static std::string name()
1920   {
1921     return "array<" + signature< A >::name() + ", " + std::to_string( N ) + ">";
1922   }
1923
1924   /**
1925    * @brief Returns DBUS' signature of type marshalled
1926    */
1927   static std::string sig()
1928   {
1929     return "a" + signature< A >::sig();
1930   }
1931
1932   /**
1933    * @brief Marshals value v as marshalled type into message
1934    */
1935   static void set( const DBusWrapper::MessageIterPtr &iter, const std::array< A, N >& v )
1936   {
1937     auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
1938     bart_assert( lst );
1939     for( auto& a : v )
1940     {
1941       signature< A >::set( lst, a );
1942     }
1943   }
1944
1945   /**
1946    * @brief Marshals value from marshalled type into variable v
1947    */
1948   static bool get( const DBusWrapper::MessageIterPtr &iter, std::array< A, N >& v )
1949   {
1950     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
1951     if ( !s )
1952       return false;
1953     for( auto& a : v )
1954     {
1955       if( !signature< A >::get( s, a ) )
1956         return false;
1957     }
1958     return true;
1959   }
1960 };
1961
1962 /**
1963  * @brief Signature class for marshalling EldbusVariant type
1964  *
1965  * This marshals variant's content as DBUS v ascii character type code.
1966  */
1967 template < typename A >
1968 struct signature< EldbusVariant< A > >
1969 {
1970   /**
1971    * @brief Returns name of type marshalled, for informative purposes
1972    */
1973   static std::string name()
1974   {
1975     return "variant<" + signature< A >::name() + ">";
1976   }
1977
1978   /**
1979    * @brief Returns DBUS' signature of type marshalled
1980    */
1981   static std::string sig()
1982   {
1983     return "v";
1984   }
1985
1986   /**
1987    * @brief Marshals value v as marshalled type into message
1988    */
1989   static void set( const DBusWrapper::MessageIterPtr &iter, const EldbusVariant< A >& v )
1990   {
1991     set( iter, v.value );
1992   }
1993
1994   /**
1995    * @brief Marshals value v as marshalled type into message
1996    */
1997   static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
1998   {
1999     auto var = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'v', signature< A >::sig());
2000     signature< A >::set( var, v );
2001   }
2002
2003   /**
2004    * @brief Marshals value from marshalled type into variable v
2005    */
2006   static bool get( const DBusWrapper::MessageIterPtr &iter, EldbusVariant< A >& v )
2007   {
2008     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'v' );
2009     if( !s )
2010       return false;
2011     return signature< A >::get( s, v.value );
2012   }
2013 };
2014
2015 /**
2016  * @brief Signature class for marshalling std::unordered_map template type
2017  *
2018  * This marshals container's content as DBUS {} ascii character type code.
2019  * Note, that library doesnt check, if the key is basic type, as DBUS
2020  * specification mandates.
2021  * User can always exchange std::unordered_map for std::map and the reverse.
2022  * User can receive such values as std::vector of std::pair<key, value> values.
2023  * Order of such values is unspecified.
2024  */
2025 template < typename A, typename B >
2026 struct signature< std::unordered_map< A, B > >
2027 {
2028   /**
2029    * @brief Returns name of type marshalled, for informative purposes
2030    */
2031   static std::string name()
2032   {
2033     return "unordered_map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
2034   }
2035
2036   /**
2037    * @brief Returns DBUS' signature of type marshalled
2038    */
2039   static std::string sig()
2040   {
2041     return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2042   }
2043
2044   /**
2045    * @brief Marshals value v as marshalled type into message
2046    */
2047   static void set( const DBusWrapper::MessageIterPtr &iter, const std::unordered_map< A, B >& v )
2048   {
2049     auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2050     auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
2051     bart_assert( lst );
2052     for( auto& a : v )
2053     {
2054       signature< std::pair< A, B > >::set( lst, a, true );
2055     }
2056   }
2057
2058   /**
2059    * @brief Marshals value from marshalled type into variable v
2060    */
2061   static bool get( const DBusWrapper::MessageIterPtr &iter, std::unordered_map< A, B >& v )
2062   {
2063     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
2064     v.clear();
2065     if( !s )
2066       return false;
2067     std::pair< A, B > a;
2068     while( signature< std::pair< A, B > >::get( s, a ) )
2069       v.insert( std::move( a ) );
2070     return true;
2071   }
2072 };
2073
2074 /**
2075  * @brief Signature class for marshalling std::unordered_map template type
2076  *
2077  * This marshals container's content as DBUS {} ascii character type code.
2078  * Note, that library doesnt check, if the key is basic type, as DBUS
2079  * specification mandates.
2080  * User can always exchange std::unordered_map for std::map and the reverse.
2081  * User can receive such values as std::vector of std::pair<key, value> values.
2082  * Order of such values is unspecified.
2083  */
2084 template < typename A, typename B >
2085 struct signature< std::map< A, B > >
2086 {
2087   /**
2088    * @brief Returns name of type marshalled, for informative purposes
2089    */
2090   static std::string name()
2091   {
2092     return "map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
2093   }
2094
2095   /**
2096    * @brief Returns DBUS' signature of type marshalled
2097    */
2098   static std::string sig()
2099   {
2100     return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2101   }
2102
2103   /**
2104    * @brief Marshals value v as marshalled type into message
2105    */
2106   static void set( const DBusWrapper::MessageIterPtr &iter, const std::map< A, B >& v )
2107   {
2108     auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2109     auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
2110     bart_assert( lst );
2111     for( auto& a : v )
2112     {
2113       signature< std::pair< A, B > >::set( lst, a, true );
2114     }
2115   }
2116
2117   /**
2118    * @brief Marshals value from marshalled type into variable v
2119    */
2120   static bool get( const DBusWrapper::MessageIterPtr &iter, std::map< A, B >& v )
2121   {
2122     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
2123     if( !s )
2124       return false;
2125     std::pair< A, B > a;
2126     while( signature< std::pair< A, B > >::get( s, a ) )
2127       v.insert( std::move( a ) );
2128     return true;
2129   }
2130 };
2131
2132 /**
2133  * @brief Signature helper class for marshalling const reference types
2134  */
2135 template < typename A >
2136 struct signature< const A& >
2137 {
2138   /**
2139    * @brief Returns name of type marshalled, for informative purposes
2140    */
2141   static std::string name()
2142   {
2143     return "const " + signature< A >::name() + "&";
2144   }
2145
2146   /**
2147    * @brief Returns DBUS' signature of type marshalled
2148    */
2149   static std::string sig()
2150   {
2151     return signature< A >::sig();
2152   }
2153
2154   /**
2155    * @brief Marshals value v as marshalled type into message
2156    */
2157   static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
2158   {
2159     signature< A >::set( iter, v );
2160   }
2161
2162   /**
2163    * @brief Marshals value from marshalled type into variable v
2164    */
2165   static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
2166   {
2167     signature< A >::get( iter, v );
2168   }
2169 };
2170
2171 /**
2172  * @brief Signature helper class for marshalling reference types
2173  */
2174 template < typename A >
2175 struct signature< A& >
2176 {
2177   /**
2178    * @brief Returns name of type marshalled, for informative purposes
2179    */
2180   static std::string name()
2181   {
2182     return signature< A >::name() + "&";
2183   }
2184
2185   /**
2186    * @brief Returns DBUS' signature of type marshalled
2187    */
2188   static std::string sig()
2189   {
2190     return signature< A >::sig();
2191   }
2192
2193   /**
2194    * @brief Marshals value v as marshalled type into message
2195    */
2196   static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
2197   {
2198     signature< A >::set( iter, v );
2199   }
2200
2201   /**
2202    * @brief Marshals value from marshalled type into variable v
2203    */
2204   static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
2205   {
2206     signature< A >::get( iter, v );
2207   }
2208 };
2209
2210 /**
2211  * @brief Signature helper class for marshalling const types
2212  */
2213 template < typename A >
2214 struct signature< const A >
2215 {
2216   /**
2217    * @brief Returns name of type marshalled, for informative purposes
2218    */
2219   static std::string name()
2220   {
2221     return "const " + signature< A >::name();
2222   }
2223
2224   /**
2225    * @brief Returns DBUS' signature of type marshalled
2226    */
2227   static std::string sig()
2228   {
2229     return signature< A >::sig();
2230   }
2231
2232   /**
2233    * @brief Marshals value v as marshalled type into message
2234    */
2235   static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
2236   {
2237     signature< A >::set( iter, v );
2238   }
2239
2240   /**
2241    * @brief Marshals value from marshalled type into variable v
2242    */
2243   static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
2244   {
2245     signature< A >::get( iter, v );
2246   }
2247 };
2248
2249 /// \cond
2250 using CallId = DBusWrapper::CallId;
2251
2252 template < typename ValueType >
2253 ValueType unpackValues( CallId callId, const DBusWrapper::MessagePtr &msg )
2254 {
2255   auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, false );
2256   ValueType r;
2257
2258   if( iter )
2259   {
2260     if( !signature< ValueType >::get( iter, r ) )
2261     {
2262       DBUS_DEBUG( "ValueType is %s", signature< ValueType >::name().c_str() );
2263       r = Error{"call " + std::to_string( callId.id ) + ": failed to unpack values, got signature '" +
2264                 DBUS_W->eldbus_message_signature_get_impl( msg ) + "', expected '" + signature< ValueType >::sig() + "'"};
2265     }
2266   }
2267   else
2268   {
2269     r = Error{"call " + std::to_string( callId.id ) + ": failed to get iterator"};
2270   }
2271   return r;
2272 }
2273
2274 inline void packValues_helper( const DBusWrapper::MessageIterPtr& ) {}
2275
2276 template < typename A, typename... ARGS >
2277 void packValues_helper( const DBusWrapper::MessageIterPtr &iter, A&& a, ARGS&&... r )
2278 {
2279   signature< A >::set( iter, std::forward< A >( a ) );
2280   packValues_helper( iter, std::forward< ARGS >( r )... );
2281 }
2282
2283 template < typename... ARGS >
2284 void packValues( CallId callId, const DBusWrapper::MessagePtr &msg, ARGS&&... r )
2285 {
2286   auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, true );
2287   packValues_helper( iter, std::forward< ARGS >( r )... );
2288 }
2289
2290 template < typename >
2291 struct ReturnType;
2292 template < typename R, typename... ARGS >
2293 struct ReturnType< R( ARGS... ) >
2294 {
2295   using type = R;
2296 };
2297
2298 template < typename R, typename... ARGS >
2299 struct ReturnType< std::function< R( ARGS... ) > >
2300 {
2301   using type = R;
2302 };
2303
2304 template < int... >
2305 struct sequence
2306 {
2307 };
2308
2309 template < int N, int... S >
2310 struct sequence_gen : sequence_gen< N - 1, N - 1, S... >
2311 {
2312 };
2313
2314 template < int... S >
2315 struct sequence_gen< 0, S... >
2316 {
2317   typedef sequence< S... > type;
2318 };
2319
2320 template < typename C, typename... ARGS >
2321 struct apply_helper
2322 {
2323   const std::function< C >& c;
2324   const std::tuple< ARGS... >& args;
2325
2326   template < int... S >
2327   auto apply_2( sequence< S... > ) const -> decltype( c( std::get< S >( args )... ) )
2328   {
2329     return c( std::get< S >( args )... );
2330   }
2331   auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
2332   {
2333     return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
2334   }
2335 };
2336
2337 template < typename C, typename A, typename... ARGS >
2338 struct apply_helper_2
2339 {
2340   const std::function< C >& c;
2341   const A& a;
2342   const std::tuple< ARGS... >& args;
2343
2344   template < int... S >
2345   auto apply_2( sequence< S... > ) const -> decltype( c( a, std::get< S >( args )... ) )
2346   {
2347     return c( a, std::get< S >( args )... );
2348   }
2349   auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
2350   {
2351     return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
2352   }
2353 };
2354
2355 template < typename C, typename... ARGS >
2356 auto apply( const std::function< C >& c, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
2357 {
2358   apply_helper< C, ARGS... > ah{c, args};
2359   return ah.apply_1();
2360 }
2361
2362 template < typename C, typename D, typename... ARGS >
2363 auto apply( const std::function< C >& c, const D& d, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
2364 {
2365   apply_helper_2< C, D, ARGS... > ah{c, d, args};
2366   return ah.apply_1();
2367 }
2368
2369 struct ConnectionState
2370 {
2371   DBusWrapper::ConnectionPtr connection;
2372   DBusWrapper::ObjectPtr object;
2373   DBusWrapper::ProxyPtr proxy, propertiesProxy;
2374 };
2375
2376 template < typename RETTYPE, typename... ARGS >
2377 RETTYPE call( CallId callId, const ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args )
2378 {
2379   const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2380   if( !proxy )
2381   {
2382     DBUS_DEBUG( "call %d: not initialized", callId.id );
2383     return Error{"not initialized"};
2384   }
2385
2386   DBUS_DEBUG( "call %d: calling '%s'", callId.id, funcName.c_str() );
2387   auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
2388   if( !msg )
2389   {
2390     DBUS_DEBUG( "call %d: failed", callId.id );
2391     return Error{"failed to create message"};
2392   }
2393
2394   detail::packValues( callId, msg, args... );
2395   auto reply = DBUS_W->eldbus_proxy_send_and_block_impl( proxy, msg );
2396   DBUS_DEBUG( "call %d: calling '%s' done", callId.id, funcName.c_str() );
2397   if( !reply )
2398   {
2399     DBUS_DEBUG( "call %d: failed", callId.id );
2400     return Error{"eldbus returned null as reply"};
2401   }
2402   std::string errname, errmsg;
2403   if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
2404   {
2405     DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
2406     return Error{errname + ": " + errmsg};
2407   }
2408   DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
2409     DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
2410   return detail::unpackValues< RETTYPE >( callId, reply );
2411 }
2412
2413 template < typename RETTYPE, typename... ARGS >
2414 void asyncCall( CallId callId, const ConnectionState &connectionState,
2415                 bool property, const std::string& funcName,
2416                 std::function< void( RETTYPE ) > callback, const ARGS&... args )
2417 {
2418   const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2419   if( !proxy )
2420   {
2421     DBUS_DEBUG( "call %d: not initialized", callId.id );
2422     callback( Error{"not initialized"} );
2423     return;
2424   }
2425
2426   auto msg = DBUS_W->eldbus_proxy_method_call_new_impl( proxy, funcName );
2427   if( !msg )
2428   {
2429     DBUS_DEBUG( "call %d: failed", callId.id );
2430     callback( Error{"failed to create message"} );
2431     return;
2432   }
2433
2434   detail::packValues( callId, msg, args... );
2435   auto pending = DBUS_W->eldbus_proxy_send_impl( proxy, msg, [callback, callId, proxy]( const DBusWrapper::MessagePtr &reply ) {
2436         DBUS_DEBUG( "call %d: calling done", callId.id );
2437         if( !reply )
2438         {
2439           DBUS_DEBUG( "call %d: failed", callId.id );
2440           callback( Error{"eldbus returned null as reply"} );
2441         }
2442         else
2443         {
2444           std::string errname, errmsg;
2445           if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
2446           {
2447             DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
2448             callback( Error{errname + ": " + errmsg} );
2449           }
2450           else
2451           {
2452             DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
2453                 DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
2454             callback( detail::unpackValues< RETTYPE >( callId, reply ) );
2455           }
2456         }
2457       }
2458     );
2459   if( pending )
2460   {
2461     DBUS_DEBUG( "call %d: call sent", callId.id );
2462   }
2463   else
2464   {
2465     DBUS_DEBUG( "call %d: failed to send call", callId.id );
2466     callback( Error{"failed to send call"} );
2467   }
2468 }
2469
2470 inline void displayDebugCallInfo( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
2471 {
2472   DBUS_DEBUG( "call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
2473 }
2474
2475 inline void displayDebugCallInfoSignal( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
2476 {
2477   DBUS_DEBUG( "call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
2478 }
2479
2480 inline void displayDebugCallInfoProperty( CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName,
2481                                           const std::string& propertyName )
2482 {
2483   DBUS_DEBUG( "call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str() );
2484 }
2485
2486 using StringStorage = DBusWrapper::StringStorage;
2487
2488 template < typename A, typename... ARGS >
2489 struct EldbusArgGenerator_Helper
2490 {
2491   static void add( std::vector< std::pair<std::string, std::string> >& r )
2492   {
2493     auto s = r.size();
2494     auto sig = signature< A >::sig();
2495     bart_assert( !sig.empty() );
2496     auto name = "p" + std::to_string( s + 1 );
2497     r.push_back({ std::move(sig), std::move(name) });
2498     EldbusArgGenerator_Helper<ARGS...>::add( r );
2499   }
2500 };
2501
2502 template <>
2503 struct EldbusArgGenerator_Helper< void >
2504 {
2505   static void add( std::vector< std::pair<std::string, std::string> >& )
2506   {
2507   }
2508 };
2509
2510 template <>
2511 struct EldbusArgGenerator_Helper< ValueOrError< void >, void >
2512 {
2513   static void add( std::vector< std::pair<std::string, std::string> >& )
2514   {
2515   }
2516 };
2517 template <>
2518 struct EldbusArgGenerator_Helper< ValueOrError<>, void >
2519 {
2520   static void add( std::vector< std::pair<std::string, std::string> >& )
2521   {
2522   }
2523 };
2524
2525 template < typename... ARGS >
2526 struct EldbusArgGenerator_Helper< std::tuple< ARGS... > >
2527 {
2528   static void add( std::vector< std::pair<std::string, std::string> >& r )
2529   {
2530     EldbusArgGenerator_Helper< ARGS..., void >::add( r );
2531   }
2532 };
2533
2534 template < typename RetType >
2535 struct dbus_interface_return_type_traits
2536 {
2537   using type = ValueOrError< RetType >;
2538 };
2539
2540 template < typename... ARGS >
2541 struct dbus_interface_return_type_traits< ValueOrError< ARGS... > >
2542 {
2543   using type = ValueOrError< ARGS... >;
2544 };
2545
2546 template < typename T >
2547 struct dbus_interface_traits;
2548 template < typename RetType, typename... ARGS >
2549 struct dbus_interface_traits< RetType( ARGS... ) >
2550 {
2551   using Ret = typename dbus_interface_return_type_traits< RetType >::type;
2552   using SyncCB = std::function< Ret( ARGS... ) >;
2553   using AsyncCB = std::function< void( std::function< void( Ret ) >, ARGS... ) >;
2554   using VEArgs = ValueOrError< ARGS... >;
2555 };
2556
2557 template < typename T >
2558 struct EldbusArgGenerator_Args;
2559 template < typename RetType, typename... ARGS >
2560 struct EldbusArgGenerator_Args< RetType( ARGS... ) >
2561 {
2562   static std::string name()
2563   {
2564     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name();
2565   }
2566   static std::vector< std::pair<std::string, std::string> > get()
2567   {
2568     std::vector< std::pair<std::string, std::string> > tmp;
2569     EldbusArgGenerator_Helper< ARGS..., void >::add( tmp );
2570     return tmp;
2571   }
2572 };
2573
2574 template < typename T >
2575 struct EldbusArgGenerator_ReturnType;
2576 template < typename RetType, typename... ARGS >
2577 struct EldbusArgGenerator_ReturnType< RetType( ARGS... ) >
2578 {
2579   static std::string name()
2580   {
2581     return signature< RetType >::name();
2582   }
2583   static std::vector< std::pair<std::string, std::string> > get( )
2584   {
2585     std::vector< std::pair<std::string, std::string> > tmp;
2586     EldbusArgGenerator_Helper< RetType, void >::add( tmp );
2587     return tmp;
2588   }
2589 };
2590
2591 template < typename T >
2592 struct EldbusArgGenerator_ReturnType;
2593 template < typename... ARGS >
2594 struct EldbusArgGenerator_ReturnType< void( ARGS... ) >
2595 {
2596   static std::string name()
2597   {
2598     return "";
2599   }
2600   static std::vector< std::pair<std::string, std::string> > get( )
2601   {
2602     return {};
2603   }
2604 };
2605 /// \endcond
2606 }
2607
2608 using ConnectionType = DBusWrapper::ConnectionType;
2609
2610 /**
2611  * @brief Class representing client's end of DBUS connection
2612  *
2613  * Allows calling (synchronous and asynchronos) methods on selected interface
2614  * Allows (synchronous and asynchronos) setting / getting properties.
2615  * Allows registering signals.
2616  */
2617 class DBusClient
2618 {
2619   /// \cond
2620   struct ConnectionInfo
2621   {
2622     std::string interfaceName, busName, pathName;
2623   };
2624   /// \endcond
2625 public:
2626   /**
2627    * @brief Default constructor, creates non-connected object.
2628    */
2629   DBusClient() = default;
2630
2631   /**
2632    * @brief Connects to dbus choosen by tp, using given arguments
2633    *
2634    * @param bus_name name of the bus to connect to
2635    * @param path_name object's path
2636    * @param interface_name interface name
2637    */
2638   DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
2639               ConnectionType tp );
2640
2641   /**
2642    * @brief Connects to dbus using connection conn
2643    *
2644    * @param bus_name name of the bus to connect to
2645    * @param path_name object's path
2646    * @param interface_name interface name
2647    * @param conn connection object from getDBusConnectionByType call
2648    */
2649   DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
2650               const DBusWrapper::ConnectionPtr &conn = {} );
2651
2652   /**
2653    * @brief Destructor object.
2654    *
2655    * All signals added will be disconnected.
2656    * All asynchronous calls will be cancelled, their callback's will be called
2657    * with failure message.
2658    */
2659   ~DBusClient() = default;
2660   DBusClient( const DBusClient& ) = delete;
2661   DBusClient( DBusClient&& ) = default;
2662
2663   DBusClient& operator=( DBusClient&& ) = default;
2664   DBusClient& operator=( const DBusClient& ) = delete;
2665
2666   /**
2667    * @brief bool operator
2668    *
2669    * Returns true, if object is connected to DBUS
2670    */
2671   explicit operator bool() const
2672   {
2673     return bool( connectionState->proxy );
2674   }
2675
2676   /**
2677    * @brief Helper class for calling a method
2678    *
2679    * Template type T defines both arguments sent to the method
2680    * and expected values. Receiving different values will be reported as
2681    * error. For example:
2682    * \code{.cpp} Method<int(float, float)> \endcode
2683    * defines method, which takes two arguments (two floats) and return
2684    * single value of type int.
2685    */
2686   template < typename T >
2687   struct Method
2688   {
2689     /// \cond
2690     using RetType = typename detail::dbus_interface_traits< T >::Ret;
2691     const detail::ConnectionState &connectionState;
2692     std::string funcName;
2693     std::string info;
2694     std::shared_ptr< ConnectionInfo > connectionInfo;
2695     /// \endcond
2696
2697     /**
2698      * @brief Executes synchronous call on DBUS's method
2699      *
2700      * The function returns ValueOrError<...> object, which
2701      * contains either received values or error message.
2702      *
2703      * @param args arguments to pass to the method
2704      */
2705     template < typename... ARGS >
2706     RetType call( const ARGS&... args )
2707     {
2708       detail::CallId callId;
2709       detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
2710       return detail::call< RetType >( callId, connectionState, false, funcName, args... );
2711     }
2712
2713     /**
2714      * @brief Executes asynchronous call on DBUS's method
2715      *
2716      * The function calls callback with either received values or error message.
2717      *
2718      * @param callback callback functor, which will be called with return value(s) or error message
2719      * @param args arguments to pass to the method
2720      */
2721     template < typename... ARGS >
2722     void asyncCall( std::function< void( RetType ) > callback, const ARGS&... args )
2723     {
2724       detail::CallId callId;
2725       detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
2726       detail::asyncCall< RetType >( callId, connectionState, false, funcName, std::move( callback ), args... );
2727     }
2728   };
2729
2730   /**
2731    * @brief Helper class for calling a property
2732    *
2733    * Template type T defines type of the value hidden under property.
2734    * Note, that library automatically wraps both sent and received value into
2735    * DBUS's wrapper type.
2736    */
2737   template < typename T >
2738   struct Property
2739   {
2740     /// \cond
2741     using RetType = typename detail::dbus_interface_return_type_traits< T >::type;
2742     using VariantRetType = typename detail::dbus_interface_return_type_traits< EldbusVariant< T > >::type;
2743     const detail::ConnectionState &connectionState;
2744     std::string propName;
2745     std::string info;
2746     std::shared_ptr< ConnectionInfo > connectionInfo;
2747     /// \endcond
2748
2749     /**
2750      * @brief executes synchronous get on property
2751      *
2752      * The function returns ValueOrError<...> object, which
2753      * contains either received values or error message.
2754      */
2755     RetType get()
2756     {
2757       detail::CallId callId;
2758       detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
2759       auto z = detail::call< VariantRetType >( callId, connectionState, true, "Get", connectionInfo->interfaceName, propName );
2760       if( !z )
2761         return z.getError();
2762       return {std::get< 0 >( z.getValues() ).value};
2763     }
2764
2765     /**
2766      * @brief executes asynchronous get on property
2767      *
2768      * The function calls callback with either received values or error message.
2769      *
2770      * @param callback callback functor, which will be called with return value(s) or error message
2771      */
2772     void asyncGet( std::function< void( RetType ) > callback )
2773     {
2774       detail::CallId callId;
2775       detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
2776       auto cc = [callback]( VariantRetType reply ) {
2777         if( reply )
2778           callback( std::move( std::get< 0 >( reply.getValues() ).value ) );
2779         else
2780           callback( reply.getError() );
2781       };
2782       detail::asyncCall< VariantRetType >( callId, connectionState, true, "Get", std::move( cc ), connectionInfo->interfaceName, propName );
2783     }
2784
2785     /**
2786      * @brief executes synchronous set on property
2787      *
2788      * The function returns ValueOrError<void> object, with
2789      * possible error message.
2790      */
2791     ValueOrError< void > set( const T& r )
2792     {
2793       detail::CallId callId;
2794       detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
2795       EldbusVariant< T > variantValue{std::move( r )};
2796       return detail::call< ValueOrError< void > >( callId, connectionState, true, "Set", connectionInfo->interfaceName, propName, variantValue );
2797     }
2798
2799     /**
2800      * @brief executes asynchronous get on property
2801      *
2802      * The function calls callback with either received values or error message.
2803      *
2804      * @param callback callback functor, which will be called with return value(s) or error message
2805      */
2806     void asyncSet( std::function< void( ValueOrError< void > ) > callback, const T& r )
2807     {
2808       detail::CallId callId;
2809       detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
2810       EldbusVariant< T > variantValue{std::move( r )};
2811       detail::asyncCall< ValueOrError< void > >( callId, connectionState, true, "Set", std::move( callback ), connectionInfo->interfaceName, propName, variantValue );
2812     }
2813   };
2814
2815   /**
2816    * @brief Constructs Property<...> object for calling properties
2817    *
2818    * The function constructs and returns proxy object for calling property.
2819    *
2820    * @param propName property name to set and / or query
2821    */
2822   template < typename PropertyType >
2823   Property< PropertyType > property( std::string propName )
2824   {
2825     return Property< PropertyType >{*connectionState, std::move( propName ), info, connectionInfo};
2826   }
2827
2828   /**
2829    * @brief Constructs Method<...> object for calling methods
2830    *
2831    * The function constructs and returns proxy object for calling method.
2832    *
2833    * @param funcName function name to call
2834    */
2835   template < typename MethodType >
2836   Method< MethodType > method( std::string funcName )
2837   {
2838     return Method< MethodType >{*connectionState, std::move( funcName ), info, connectionInfo};
2839   }
2840
2841   /**
2842    * @brief Registers notification callback, when property has changed
2843    *
2844    * The callback will be called with new value, when property's value has changed.
2845    * Note, that template type V must match expected type, otherwise undefined behavior will occur,
2846    * there's no check for this.
2847    */
2848   template < typename V >
2849   void addPropertyChangedEvent( std::string propertyName, std::function< void( V ) > callback )
2850   {
2851     detail::CallId callId;
2852     detail::displayDebugCallInfoSignal( callId, propertyName, info, connectionInfo->interfaceName );
2853     DBUS_DEBUG( "call %d: adding property", callId.id );
2854     auto &cI = this->connectionInfo;
2855     DBUS_W->add_property_changed_event_listener_impl(connectionState->proxy, cI->interfaceName, propertyName,
2856       [callback]( const _Eina_Value *newValue ) {
2857       V val = 0;
2858       if( !getFromEinaValue( newValue, &val ) )
2859       {
2860         DBUS_DEBUG( "unable to get property's value" );
2861         return;
2862       }
2863       callback( val );
2864     });
2865   }
2866
2867   /**
2868    * @brief Registers callback on the DBUS' signal
2869    *
2870    * The function registers callback signalName. When signal comes, callback will be called.
2871    * Callback object will exists as long as signal is registered. You can unregister signal
2872    * by destroying DBusClient object.
2873    *
2874    * @param signalName name of the signal to register
2875    * @param callback callback to call
2876    */
2877   template < typename SignalType >
2878   void addSignal( std::string signalName, std::function< SignalType > callback )
2879   {
2880     detail::CallId callId;
2881     detail::displayDebugCallInfoSignal( callId, signalName, info, connectionInfo->interfaceName );
2882     DBUS_W->eldbus_proxy_signal_handler_add_impl( connectionState->proxy, signalName,
2883       [callId, callback, signalName]( const DBusWrapper::MessagePtr &msg ) -> void {
2884         std::string errname, aux;
2885         if( DBUS_W->eldbus_message_error_get_impl( msg, errname, aux ) )
2886         {
2887           DBUS_DEBUG( "call %d: Eldbus error: %s %s", callId.id, errname.c_str(), aux.c_str() );
2888           return;
2889         }
2890         DBUS_DEBUG( "call %d: received signal with signature '%s'", callId.id, DBUS_W->eldbus_message_signature_get_impl( msg ).c_str() );
2891         using ParamsType = typename detail::dbus_interface_traits< SignalType >::VEArgs;
2892         auto params = detail::unpackValues< ParamsType >( callId, msg );
2893         if( !params )
2894         {
2895           DBUS_DEBUG( "call %d: failed: %s", callId.id, params.getError().message.c_str() );
2896           return;
2897         }
2898         try
2899         {
2900           detail::apply( callback, params.getValues() );
2901         }
2902         catch( ... )
2903         {
2904           DBUS_DEBUG( "unhandled exception" );
2905           bart_assert( 0 );
2906         }
2907       });
2908   }
2909
2910 private:
2911   /// \cond
2912   std::unique_ptr<detail::ConnectionState> connectionState{ new detail::ConnectionState };
2913   std::string info;
2914   std::shared_ptr< ConnectionInfo > connectionInfo;
2915
2916   static bool getFromEinaValue(const _Eina_Value *v, void *dst);
2917   /// \endcond
2918 };
2919
2920 /**
2921  * @brief Helper class describing DBUS's server interface
2922  *
2923  */
2924 class DBusInterfaceDescription
2925 {
2926   friend class DBusServer;
2927
2928 public:
2929   /// \cond
2930   using MethodInfo = DBusWrapper::MethodInfo;
2931   using SignalInfo = DBusWrapper::SignalInfo;
2932   using PropertyInfo = DBusWrapper::PropertyInfo;
2933   using SignalId = DBusWrapper::SignalId;
2934   /// \endcond
2935
2936   /**
2937    * @brief Creates empty interface description with given name
2938    *
2939    * @param interfaceName name of the interface
2940    */
2941   DBusInterfaceDescription( std::string interfaceName );
2942
2943   /**
2944    * @brief adds new, synchronous method to the interface
2945    *
2946    * When method memberName is called on DBUS, callback functor will be called
2947    * with values received from DBUS. callback won't be called, if method was
2948    * called with invalid signature. Value returned from functor (or error message)
2949    * will be marshalled back to the caller.
2950    *
2951    * Template type T defines both arguments sent to the method
2952    * and expected values. Receiving different values will be reported as
2953    * error. For example:
2954    * \code{.cpp} Method<int(float, float)> \endcode
2955    * defines method, which takes two arguments (two floats) and return
2956    * single value of type int.
2957    *
2958    * @param memberName name of the method
2959    * @param callback functor, which will be called
2960    */
2961   template < typename T >
2962   void addMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback )
2963   {
2964     detail::CallId callId;
2965     MethodInfo mi;
2966     methods.push_back( std::move( mi ) );
2967     auto& z = methods.back();
2968     z.in = detail::EldbusArgGenerator_Args< T >::get( );
2969     z.out = detail::EldbusArgGenerator_ReturnType< T >::get( );
2970     z.memberName = memberName;
2971     DBUS_DEBUG( "call %d: method %s, in %s, out %s", callId.id, memberName.c_str(),
2972                 detail::EldbusArgGenerator_Args< T >::name().c_str(),
2973                 detail::EldbusArgGenerator_ReturnType< T >::name().c_str() );
2974     z.callback = construct< T >( callId, callback );
2975     z.id = callId;
2976   }
2977
2978   /**
2979    * @brief adds new, synchronous property to the interface
2980    *
2981    * When property memberName is called on DBUS, respective callback functor will be called
2982    * with values received from DBUS. callback won't be called, if method was
2983    * called with invalid signature. Value returned from functor (or error message)
2984    * will be marshalled back to the caller.
2985    *
2986    * Template type T defines type of the value hidden under property.
2987    * Note, that library automatically wraps both sent and received value into
2988    * DBUS's wrapper type.
2989    *
2990    * @param memberName name of the method
2991    * @param getter functor, which will be called when property is being read
2992    * @param setter functor, which will be called when property is being set
2993    */
2994   template < typename T >
2995   void addProperty( const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >( T ) > setter )
2996   {
2997     properties.push_back( {} );
2998     auto& z = properties.back();
2999     z.memberName = memberName;
3000     z.typeSignature = detail::signature< T >::sig();
3001     if( getter )
3002     {
3003       detail::CallId getterId;
3004       z.getterId = getterId;
3005       DBUS_DEBUG( "call %d: property %s (get) type %s", getterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
3006       z.getCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) -> std::string {
3007         try
3008         {
3009           auto v = detail::apply( getter, std::tuple<>{} );
3010           if( v )
3011           {
3012             detail::signature< T >::set( dst, std::get< 0 >( v.getValues() ) );
3013             DBUS_DEBUG( "call %d: success", getterId.id );
3014             return "";
3015           }
3016           DBUS_DEBUG( "call %d: failed: %s", getterId.id, v.getError().message.c_str() );
3017           return v.getError().message;
3018         }
3019         catch( std::exception& e )
3020         {
3021           return std::string( "unhandled exception (" ) + e.what() + ")";
3022         }
3023         catch( ... )
3024         {
3025           return "unhandled exception";
3026         }
3027       };
3028     }
3029     if( setter )
3030     {
3031       detail::CallId setterId;
3032       z.setterId = setterId;
3033       DBUS_DEBUG( "call %d: property %s (set) type %s", setterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
3034       z.setCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &src_iter ) -> std::string {
3035         std::tuple< T > value;
3036         auto src_signature = DBUS_W->eldbus_message_iter_signature_get_impl( src_iter );
3037         if( detail::signature< T >::get( src_iter, std::get< 0 >( value ) ) )
3038         {
3039           try
3040           {
3041             auto v = detail::apply( setter, std::move( value ) );
3042             if( v )
3043             {
3044               DBUS_DEBUG( "call %d: success", setterId.id );
3045               return "";
3046             }
3047             DBUS_DEBUG( "call %d: failed: %s", setterId.id, v.getError().message.c_str() );
3048             return v.getError().message;
3049           }
3050           catch( std::exception& e )
3051           {
3052             return std::string( "unhandled exception (" ) + e.what() + ")";
3053           }
3054           catch( ... )
3055           {
3056             return "unhandled exception";
3057           }
3058         }
3059         DBUS_DEBUG( "call %d: failed to unpack values, got signature '%s', expected '%s'", setterId.id,
3060                     src_signature.c_str(), detail::signature< T >::sig().c_str() );
3061         return "call " + std::to_string( setterId.id ) + ": failed to unpack values, got signature '" +
3062                      src_signature + "', expected '" + detail::signature< T >::sig() + "'";
3063       };
3064     }
3065   }
3066
3067   /**
3068    * @brief adds new signal to the interface
3069    *
3070    * Template types ARGS defines values, which will be emited with the signal
3071    *
3072    * @param memberName name of the method
3073    */
3074   template < typename... ARGS >
3075   SignalId addSignal( const std::string& memberName )
3076   {
3077     detail::CallId callId;
3078     signals.push_back( {} );
3079     auto& z = signals.back();
3080     z.memberName = memberName;
3081     z.args = detail::EldbusArgGenerator_Args< void( ARGS... ) >::get( DBUS_W->Strings );
3082     z.id = callId;
3083     DBUS_DEBUG( "call %d: signal %s", callId.id, memberName.c_str() );
3084     return SignalId{callId};
3085   }
3086
3087 private:
3088   /// \cond
3089   std::vector< MethodInfo > methods;
3090   std::vector< PropertyInfo > properties;
3091   std::vector< SignalInfo > signals;
3092   std::string interfaceName;
3093
3094   template < typename T >
3095   std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > construct( detail::CallId callId,
3096                                                                            typename detail::dbus_interface_traits< T >::SyncCB callback )
3097   {
3098     using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs;
3099     return [=]( const DBusWrapper::MessagePtr &msg ) -> DBusWrapper::MessagePtr {
3100       DBUS_DEBUG( "call %d: entering", callId.id );
3101       DBusWrapper::MessagePtr ret = {};
3102       auto args = detail::unpackValues< VEArgs >( callId, msg );
3103       if( args )
3104       {
3105         try
3106         {
3107           auto v = detail::apply( callback, std::move( args.getValues() ) );
3108           if( v )
3109           {
3110             DBUS_DEBUG( "call %d: success", callId.id );
3111             ret = DBUS_W->eldbus_message_method_return_new_impl( msg );
3112             detail::packValues( callId, ret, v );
3113           }
3114           else
3115           {
3116             DBUS_DEBUG( "call %d: failed: %s", callId.id, v.getError().message.c_str() );
3117             ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", v.getError().message );
3118           }
3119         }
3120         catch( std::exception& e )
3121         {
3122           auto txt = std::string( "unhandled exception (" ) + e.what() + ")";
3123           DBUS_DEBUG( "call %d: failed: %s", callId.id, txt.c_str() );
3124           ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", txt );
3125         }
3126         catch( ... )
3127         {
3128           DBUS_DEBUG( "call %d: failed: %s", callId.id, "unhandled exception" );
3129           ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", "unhandled exception" );
3130         }
3131       }
3132       else
3133       {
3134         std::ostringstream err;
3135         err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << DBUS_W->eldbus_message_signature_get_impl( msg ) << "'";
3136         auto str = err.str();
3137         DBUS_DEBUG( "call %d: failed: %s", callId.id, str.c_str() );
3138         ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.InvalidArgs", str );
3139       }
3140       return ret;
3141     };
3142   }
3143   /// \endcond
3144 };
3145
3146 /**
3147  * @brief Class representing server's end of DBUS connection
3148  *
3149  * Allows listening (synchronously and asynchronosly) on methods on selected interface
3150  * Allows listening (synchronously and asynchronosly) on setting / getting properties.
3151  * Allows emiting signals.
3152  */
3153 class DBusServer
3154 {
3155 public:
3156   /**
3157    * @brief Constructs non-connected dbus server.
3158    */
3159   DBusServer() = default;
3160
3161   /**
3162    * @brief Constructs dbus server on either system or user dbus connection.
3163    */
3164   DBusServer( ConnectionType tp );
3165
3166   /**
3167    * @brief Constructs dbus server on connection from getDBusConnectionByType
3168    */
3169   DBusServer( const DBusWrapper::ConnectionPtr &conn );
3170
3171   /**
3172    * @brief Destructor
3173    *
3174    * Destructor will properly destroy everything. Destructor will cancel
3175    * pending replies.
3176    */
3177   ~DBusServer() = default;
3178
3179   DBusServer( const DBusServer& ) = delete;
3180   DBusServer( DBusServer&& ) = default;
3181
3182   DBusServer& operator=( DBusServer&& ) = default;
3183   DBusServer& operator=( const DBusServer& ) = delete;
3184
3185   /**
3186    * @brief Registers interface on given path name
3187    *
3188    * @param pathName path object to register interface on.
3189    * @param dscr
3190    * @param fallback
3191    */
3192   void addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false );
3193
3194   /**
3195    * @brief Gets bus name of the current connection (must be connected)
3196    */
3197   std::string getBusName() const;
3198
3199   /**
3200    * @brief Returns connection object for this dbus server object
3201    *
3202    * @return connection object
3203    */
3204   DBusWrapper::ConnectionPtr getConnection();
3205
3206   /**
3207    * @brief Emits signal
3208    *
3209    * Emits signal based only on data passed to the function
3210    *
3211    * @param signal identifier of the signal
3212    * @param args values to emit
3213    */
3214   template < typename... ARGS >
3215   void emit2( const std::string& path, const std::string& interfaceName,
3216               const std::string& signalName, const ARGS&... args )
3217   {
3218     auto msg = DBUS_W->eldbus_message_signal_new_impl( path, interfaceName, signalName );
3219     detail::CallId id;
3220     detail::packValues( id, msg, args... );
3221     DBUS_W->eldbus_connection_send_impl( connection, msg );
3222   }
3223
3224   /**
3225    * @brief Returns current object path, when handling call to property / method
3226    *
3227    * User can call this function from inside callback used to handle property / method calls.
3228    * It will retrieve object's path used in the call. Note, that in asynchronous handling
3229    * of those calls user need to retrieve and store the current object / current connection
3230    * as the value will change at the moment user's callback handling will exit. For example:
3231    * \code{.cpp}
3232    * DBusInterfaceDescription interface{"name"};
3233    * auto handler_later = [](std::function<void(void)> done_cb) {
3234    *   // process something later on
3235    *   DBusServer::getCurrentObjectPath(); // this will return empty string
3236    * };
3237    * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
3238    *   DBusServer::getCurrentObjectPath(); // this will current object's path
3239    *
3240    *   // do some processing later on and call done_cb, when it's done
3241    *   register_to_call_sometime_later_on(std::move(done_cb));
3242    * };
3243    * \endcode
3244    */
3245   static std::string getCurrentObjectPath() { return currentObjectPath; }
3246
3247   /**
3248    * @brief Returns current connection object, when handling call to property / method
3249    *
3250    * User can call this function from inside callback used to handle property / method calls.
3251    * It will retrieve object's path used in the call. Note, that in asynchronous handling
3252    * of those calls user need to retrieve and store the current object / current connection
3253    * as the value will change at the moment user's callback handling will exit. For example:
3254    * \code{.cpp}
3255    * DBusInterfaceDescription interface{"name"};
3256    * auto handler_later = [](std::function<void(void)> done_cb) {
3257    *   // process something later on
3258    *   DBusServer::getCurrentObjectPath(); // this will return empty string
3259    * };
3260    * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
3261    *   DBusServer::getCurrentObjectPath(); // this will current object's path
3262    *
3263    *   // do some processing later on and call done_cb, when it's done
3264    *   register_to_call_sometime_later_on(std::move(done_cb));
3265    * };
3266    * \endcode
3267    */
3268   static const DBusWrapper::ConnectionPtr &getCurrentConnection() { return currentConnection; }
3269
3270   /// \cond
3271   class CurrentObjectSetter
3272   {
3273   public:
3274     CurrentObjectSetter( DBusWrapper::ConnectionPtr con, std::string path )
3275     {
3276       currentObjectPath = std::move(path);
3277       currentConnection = std::move( con );
3278     }
3279     ~CurrentObjectSetter()
3280     {
3281       currentObjectPath = "";
3282       currentConnection = {};
3283     }
3284     CurrentObjectSetter( const CurrentObjectSetter& ) = delete;
3285     CurrentObjectSetter( CurrentObjectSetter&& ) = delete;
3286     void operator=( const CurrentObjectSetter& ) = delete;
3287     void operator=( CurrentObjectSetter&& ) = delete;
3288   };
3289   /// \endcond
3290
3291 private:
3292   /// \cond
3293   DBusWrapper::ConnectionPtr connection;
3294   struct DestructorObject {
3295     std::vector<std::function<void()>> destructors;
3296     ~DestructorObject() {
3297       for(auto &a : destructors) a();
3298     }
3299   };
3300
3301   std::unique_ptr<DestructorObject> destructorObject { new DestructorObject() };
3302   static thread_local std::string currentObjectPath;
3303   static thread_local DBusWrapper::ConnectionPtr currentConnection;
3304
3305   /// \endcond
3306 };
3307
3308 /// \cond
3309 DBusWrapper::ConnectionPtr getDBusConnectionByType( ConnectionType tp );
3310 DBusWrapper::ConnectionPtr getDBusConnectionByName( const std::string& name );
3311 std::string getConnectionName( const DBusWrapper::ConnectionPtr& );
3312 /// \endcond
3313 }
3314
3315 /// \cond
3316 namespace std
3317 {
3318 template < size_t INDEX, typename... ARGS >
3319 inline auto get( DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) ) &
3320 {
3321   return std::get< INDEX >( v.getValues() );
3322 }
3323
3324 template < size_t INDEX, typename... ARGS >
3325 inline auto get( const DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) )
3326 {
3327   return std::get< INDEX >( v.getValues() );
3328 }
3329 }
3330 /// \endcond
3331
3332 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H