kodi
DBusMessage.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include <cstdint>
12 #include <memory>
13 #include <string>
14 #include <type_traits>
15 
16 #include <dbus/dbus.h>
17 
18 class CDBusError;
19 
20 template<typename T>
21 struct ToDBusType;
22 template<> struct ToDBusType<bool> { static constexpr int TYPE = DBUS_TYPE_BOOLEAN; };
23 template<> struct ToDBusType<char*> { static constexpr int TYPE = DBUS_TYPE_STRING; };
24 template<> struct ToDBusType<const char*> { static constexpr int TYPE = DBUS_TYPE_STRING; };
25 template<> struct ToDBusType<std::uint8_t> { static constexpr int TYPE = DBUS_TYPE_BYTE; };
26 template<> struct ToDBusType<std::int16_t> { static constexpr int TYPE = DBUS_TYPE_INT16; };
27 template<> struct ToDBusType<std::uint16_t> { static constexpr int TYPE = DBUS_TYPE_UINT16; };
28 template<> struct ToDBusType<std::int32_t> { static constexpr int TYPE = DBUS_TYPE_INT32; };
29 template<> struct ToDBusType<std::uint32_t> { static constexpr int TYPE = DBUS_TYPE_UINT32; };
30 template<> struct ToDBusType<std::int64_t> { static constexpr int TYPE = DBUS_TYPE_INT64; };
31 template<> struct ToDBusType<std::uint64_t> { static constexpr int TYPE = DBUS_TYPE_UINT64; };
32 template<> struct ToDBusType<double> { static constexpr int TYPE = DBUS_TYPE_DOUBLE; };
33 
34 template<typename T>
36 
38 {
39  void operator()(DBusMessage* message) const;
40 };
41 using DBusMessagePtr = std::unique_ptr<DBusMessage, DBusMessageDeleter>;
42 
44 {
45 public:
46  CDBusMessage(const char *destination, const char *object, const char *interface, const char *method);
47  CDBusMessage(std::string const& destination, std::string const& object, std::string const& interface, std::string const& method);
48 
49  void AppendObjectPath(const char *object);
50 
51  template<typename T>
52  void AppendArgument(const T arg)
53  {
54  AppendWithType(ToDBusType<T>::TYPE, &arg);
55  }
56  void AppendArgument(const char **arrayString, unsigned int length);
57 
58  template<typename TFirst>
59  void AppendArguments(const TFirst first)
60  {
61  AppendArgument(first);
62  // Recursion end
63  }
64  template<typename TFirst, typename... TArgs>
65  void AppendArguments(const TFirst first, const TArgs... args)
66  {
67  AppendArgument(first);
68  AppendArguments(args...);
69  }
70 
71  DBusMessageIter * GetArgumentIter();
72 
91  template<typename... TArgs>
92  bool GetReplyArguments(TArgs*... args)
93  {
94  DBusMessageIter iter;
95  if (!InitializeReplyIter(&iter))
96  {
97  return false;
98  }
99  return GetReplyArgumentsWithIter(&iter, args...);
100  }
101 
102  DBusMessage *SendSystem();
103  DBusMessage *SendSession();
104  DBusMessage *SendSystem(CDBusError& error);
105  DBusMessage *SendSession(CDBusError& error);
106 
107  bool SendAsyncSystem();
108  bool SendAsyncSession();
109 
110  DBusMessage *Send(DBusBusType type);
111  DBusMessage *Send(DBusBusType type, CDBusError& error);
112  DBusMessage *Send(DBusConnection *con, CDBusError& error);
113 private:
114  void AppendWithType(int type, const void* value);
115  bool SendAsync(DBusBusType type);
116 
117  void PrepareArgument();
118 
119  bool InitializeReplyIter(DBusMessageIter* iter);
120  bool CheckTypeAndGetValue(DBusMessageIter* iter, int expectType, void* dest);
121  template<typename TFirst>
122  bool GetReplyArgumentsWithIter(DBusMessageIter* iter, TFirst* first)
123  {
124  // Recursion end
125  return CheckTypeAndGetValue(iter, ToDBusTypeFromPointer<TFirst>::TYPE, first);
126  }
127  template<typename TFirst, typename... TArgs>
128  bool GetReplyArgumentsWithIter(DBusMessageIter* iter, TFirst* first, TArgs*... args)
129  {
130  if (!CheckTypeAndGetValue(iter, ToDBusTypeFromPointer<TFirst>::TYPE, first))
131  {
132  return false;
133  }
134  // Ignore return value, if we try to read past the end of the message this
135  // will be catched by the type check (past-end type is DBUS_TYPE_INVALID)
136  dbus_message_iter_next(iter);
137  return GetReplyArgumentsWithIter(iter, args...);
138  }
139 
140  DBusMessagePtr m_message;
141  DBusMessagePtr m_reply = nullptr;
142  DBusMessageIter m_args;
143  bool m_haveArgs;
144 };
145 
146 template<>
147 void CDBusMessage::AppendArgument<bool>(const bool arg);
148 template<>
149 void CDBusMessage::AppendArgument<std::string>(const std::string arg);
Definition: DBusMessage.h:21
Definition: DBusUtil.h:60
Definition: DBusMessage.h:37
bool GetReplyArguments(TArgs *... args)
Retrieve simple arguments from DBus reply message.
Definition: DBusMessage.h:92
Definition: DBusMessage.h:43