swift
dbusmessage.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2018 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "dbusmessage.h"
5 
6 namespace XSwiftBus
7 {
8 
9  CDBusMessage::CDBusMessage(DBusMessage *message) { m_message = dbus_message_ref(message); }
10 
12  {
13  m_message = dbus_message_ref(other.m_message);
14  m_serial = other.m_serial;
15  }
16 
17  CDBusMessage::CDBusMessage(DBusMessage *message, dbus_uint32_t serial)
18  {
19  m_message = dbus_message_ref(message);
20  m_serial = serial;
21  }
22 
23  CDBusMessage::~CDBusMessage() { dbus_message_unref(m_message); }
24 
26  {
27  std::swap(m_serial, other.m_serial);
28  m_message = dbus_message_ref(other.m_message);
29  return *this;
30  }
31 
33  {
34  return dbus_message_get_type(m_message) == DBUS_MESSAGE_TYPE_METHOD_CALL;
35  }
36 
37  bool CDBusMessage::wantsReply() const { return !dbus_message_get_no_reply(m_message); }
38 
39  std::string CDBusMessage::getSender() const
40  {
41  const char *sender = dbus_message_get_sender(m_message);
42  return sender ? std::string(sender) : std::string();
43  }
44 
45  dbus_uint32_t CDBusMessage::getSerial() const { return dbus_message_get_serial(m_message); }
46 
47  std::string_view CDBusMessage::getInterfaceName() const { return dbus_message_get_interface(m_message); }
48 
49  std::string_view CDBusMessage::getObjectPath() const { return dbus_message_get_path(m_message); }
50 
51  std::string_view CDBusMessage::getMethodName() const { return dbus_message_get_member(m_message); }
52 
53  void CDBusMessage::beginArgumentWrite() { dbus_message_iter_init_append(m_message, &m_messageIterator); }
54 
56  {
57  dbus_bool_t boolean = value ? 1 : 0;
58  dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_BOOLEAN, &boolean);
59  }
60 
61  void CDBusMessage::appendArgument(const char *value)
62  {
63  dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_STRING, &value);
64  }
65 
66  void CDBusMessage::appendArgument(const std::string &value)
67  {
68  const char *ptr = value.c_str();
69  dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_STRING, &ptr);
70  }
71 
73  {
74  dbus_int32_t i = value;
75  dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_INT32, &i);
76  }
77 
78  void CDBusMessage::appendArgument(double value)
79  {
80  dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_DOUBLE, &value);
81  }
82 
83  void CDBusMessage::appendArgument(const std::vector<bool> &array)
84  {
85  // array.data() not existing for bool
86  // changing dbus_message_iter_open_container here affects DBus signature
87  // using int16 creates signature "n", mismatch on swift side
88  // using int32 creates signature "i"
89  // there are also xml files for the signature: src/xswiftbus/org.swift_project.xswiftbus.traffic.xml
90  // discussion: https://discordapp.com/channels/539048679160676382/539925070550794240/698552502831939676
91 
92  DBusMessageIter arrayIterator;
93  dbus_message_iter_open_container(&m_messageIterator, DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN_AS_STRING,
94  &arrayIterator);
95 
96  const std::vector<unsigned> ints(array.begin(), array.end());
97  const unsigned *ptr = ints.data();
98  dbus_message_iter_append_fixed_array(&arrayIterator, DBUS_TYPE_BOOLEAN, &ptr, static_cast<int>(array.size()));
99  dbus_message_iter_close_container(&m_messageIterator, &arrayIterator);
100  }
101 
102  void CDBusMessage::appendArgument(const std::vector<double> &array)
103  {
104  DBusMessageIter arrayIterator;
105  dbus_message_iter_open_container(&m_messageIterator, DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE_AS_STRING,
106  &arrayIterator);
107  const double *ptr = array.data();
108  dbus_message_iter_append_fixed_array(&arrayIterator, DBUS_TYPE_DOUBLE, &ptr, static_cast<int>(array.size()));
109  dbus_message_iter_close_container(&m_messageIterator, &arrayIterator);
110  }
111 
112  void CDBusMessage::appendArgument(const std::vector<std::string> &array)
113  {
114  DBusMessageIter arrayIterator;
115  dbus_message_iter_open_container(&m_messageIterator, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING,
116  &arrayIterator);
117  for (const auto &i : array)
118  {
119  const char *ptr = i.c_str();
120  dbus_message_iter_append_basic(&arrayIterator, DBUS_TYPE_STRING, &ptr);
121  }
122  dbus_message_iter_close_container(&m_messageIterator, &arrayIterator);
123  }
124 
125  void CDBusMessage::beginArgumentRead() { dbus_message_iter_init(m_message, &m_messageIterator); }
126 
127  void CDBusMessage::getArgument(int &value)
128  {
129  if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_INT32) { return; }
130  dbus_int32_t i;
131  dbus_message_iter_get_basic(&m_messageIterator, &i);
132  value = i;
133  dbus_message_iter_next(&m_messageIterator);
134  }
135 
136  void CDBusMessage::getArgument(bool &value)
137  {
138  if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_BOOLEAN) { return; }
139  dbus_bool_t v;
140  dbus_message_iter_get_basic(&m_messageIterator, &v);
141  if (v == TRUE) { value = true; }
142  else { value = false; }
143  dbus_message_iter_next(&m_messageIterator);
144  }
145 
146  void CDBusMessage::getArgument(double &value)
147  {
148  if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_DOUBLE) { return; }
149  dbus_message_iter_get_basic(&m_messageIterator, &value);
150  dbus_message_iter_next(&m_messageIterator);
151  }
152 
153  void CDBusMessage::getArgument(std::string &value)
154  {
155  const char *str = nullptr;
156  if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_STRING) { return; }
157  dbus_message_iter_get_basic(&m_messageIterator, &str);
158  dbus_message_iter_next(&m_messageIterator);
159  value = std::string(str);
160  }
161 
162  void CDBusMessage::getArgument(std::vector<int> &value)
163  {
164  DBusMessageIter arrayIterator;
165  dbus_message_iter_recurse(&m_messageIterator, &arrayIterator);
166  do {
167  if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_INT32) { return; }
168  dbus_int32_t i;
169  dbus_message_iter_get_basic(&arrayIterator, &i);
170  value.push_back(i);
171  }
172  while (dbus_message_iter_next(&arrayIterator));
173  dbus_message_iter_next(&m_messageIterator);
174  }
175 
176  void CDBusMessage::getArgument(std::vector<bool> &value)
177  {
178  if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_ARRAY) { return; }
179  DBusMessageIter arrayIterator;
180  dbus_message_iter_recurse(&m_messageIterator, &arrayIterator);
181  do {
182  if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_BOOLEAN) { return; }
183  dbus_bool_t b;
184  dbus_message_iter_get_basic(&arrayIterator, &b);
185  if (b == TRUE) { value.push_back(true); }
186  else { value.push_back(false); }
187  }
188  while (dbus_message_iter_next(&arrayIterator));
189  dbus_message_iter_next(&m_messageIterator);
190  }
191 
192  void CDBusMessage::getArgument(std::vector<double> &value)
193  {
194  DBusMessageIter arrayIterator;
195  dbus_message_iter_recurse(&m_messageIterator, &arrayIterator);
196  do {
197  if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DOUBLE) { return; }
198  double d;
199  dbus_message_iter_get_basic(&arrayIterator, &d);
200  value.push_back(d);
201  }
202  while (dbus_message_iter_next(&arrayIterator));
203  dbus_message_iter_next(&m_messageIterator);
204  }
205 
206  void CDBusMessage::getArgument(std::vector<std::string> &value)
207  {
208  DBusMessageIter arrayIterator;
209  dbus_message_iter_recurse(&m_messageIterator, &arrayIterator);
210  do {
211  if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_STRING) { return; }
212  const char *str = nullptr;
213  dbus_message_iter_get_basic(&arrayIterator, &str);
214  value.push_back(std::string(str));
215  }
216  while (dbus_message_iter_next(&arrayIterator));
217  dbus_message_iter_next(&m_messageIterator);
218  }
219 
220  CDBusMessage CDBusMessage::createSignal(const std::string &path, const std::string &interfaceName,
221  const std::string &signalName)
222  {
223  DBusMessage *signal = dbus_message_new_signal(path.c_str(), interfaceName.c_str(), signalName.c_str());
224  return CDBusMessage(signal);
225  }
226 
227  CDBusMessage CDBusMessage::createReply(const std::string &destination, dbus_uint32_t serial)
228  {
229  DBusMessage *reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
230  dbus_message_set_no_reply(reply, TRUE);
231  if (!destination.empty()) { dbus_message_set_destination(reply, destination.c_str()); }
232  dbus_message_set_reply_serial(reply, serial);
233  CDBusMessage msg(reply);
234  dbus_message_unref(reply);
235  return msg;
236  }
237 
238 } // namespace XSwiftBus
CDBusMessage & operator=(CDBusMessage other)
Assignment operator.
Definition: dbusmessage.cpp:25
bool wantsReply() const
Does this message want a reply?
Definition: dbusmessage.cpp:37
bool isMethodCall() const
Is this message a method call?
Definition: dbusmessage.cpp:32
void appendArgument(bool value)
Append argument. Make sure to call.
Definition: dbusmessage.cpp:55
void getArgument(int &value)
Read single argument. Make sure to call.
std::string getSender() const
Get the message sender.
Definition: dbusmessage.cpp:39
std::string_view getObjectPath() const
Get the called object path.
Definition: dbusmessage.cpp:49
std::string_view getMethodName() const
Get the called method name.
Definition: dbusmessage.cpp:51
dbus_uint32_t getSerial() const
Get the message serial. This is usally required for reply message.
Definition: dbusmessage.cpp:45
std::string_view getInterfaceName() const
Get the called interface name.
Definition: dbusmessage.cpp:47
CDBusMessage(DBusMessage *message)
Constructor.
Definition: dbusmessage.cpp:9
void beginArgumentRead()
Begin reading arguments.
void beginArgumentWrite()
Begin writing argument.
Definition: dbusmessage.cpp:53
static CDBusMessage createReply(const std::string &destination, dbus_uint32_t serial)
Creates a DBus message containing a DBus reply.
static CDBusMessage createSignal(const std::string &path, const std::string &interfaceName, const std::string &signalName)
Creates a DBus message containing a DBus signal.
~CDBusMessage()
Destructor.
Definition: dbusmessage.cpp:23
Plugin loaded by X-Plane which publishes a DBus service.
Definition: command.h:14
void swap(Optional< T > &a, Optional< T > &b) noexcept(std::is_nothrow_swappable_v< T >)
Efficient swap for two Optional objects.
Definition: optional.h:132