sdbus-c++ 1.2.0
High-level C++ D-Bus library based on systemd D-Bus implementation
Message.h
Go to the documentation of this file.
1
27#ifndef SDBUS_CXX_MESSAGE_H_
28#define SDBUS_CXX_MESSAGE_H_
29
31#include <sdbus-c++/Error.h>
32#include <string>
33#include <vector>
34#include <map>
35#include <utility>
36#include <cstdint>
37#include <cassert>
38#include <functional>
39#include <sys/types.h>
40
41// Forward declarations
42namespace sdbus {
43 class Variant;
44 class ObjectPath;
45 class Signature;
46 template <typename... _ValueTypes> class Struct;
47 class UnixFd;
48 class MethodReply;
49 namespace internal {
50 class ISdBus;
51 class IConnection;
52 }
53}
54
55namespace sdbus {
56
57 /********************************************/
70 class [[nodiscard]] Message
71 {
72 public:
73 Message& operator<<(bool item);
74 Message& operator<<(int16_t item);
75 Message& operator<<(int32_t item);
76 Message& operator<<(int64_t item);
77 Message& operator<<(uint8_t item);
78 Message& operator<<(uint16_t item);
79 Message& operator<<(uint32_t item);
80 Message& operator<<(uint64_t item);
81 Message& operator<<(double item);
82 Message& operator<<(const char *item);
83 Message& operator<<(const std::string &item);
84 Message& operator<<(const Variant &item);
85 Message& operator<<(const ObjectPath &item);
86 Message& operator<<(const Signature &item);
87 Message& operator<<(const UnixFd &item);
88
89 Message& operator>>(bool& item);
90 Message& operator>>(int16_t& item);
91 Message& operator>>(int32_t& item);
92 Message& operator>>(int64_t& item);
93 Message& operator>>(uint8_t& item);
94 Message& operator>>(uint16_t& item);
95 Message& operator>>(uint32_t& item);
96 Message& operator>>(uint64_t& item);
97 Message& operator>>(double& item);
98 Message& operator>>(char*& item);
99 Message& operator>>(std::string &item);
100 Message& operator>>(Variant &item);
101 Message& operator>>(ObjectPath &item);
102 Message& operator>>(Signature &item);
103 Message& operator>>(UnixFd &item);
104
105 Message& openContainer(const std::string& signature);
106 Message& closeContainer();
107 Message& openDictEntry(const std::string& signature);
108 Message& closeDictEntry();
109 Message& openVariant(const std::string& signature);
110 Message& closeVariant();
111 Message& openStruct(const std::string& signature);
112 Message& closeStruct();
113
114 Message& enterContainer(const std::string& signature);
115 Message& exitContainer();
116 Message& enterDictEntry(const std::string& signature);
117 Message& exitDictEntry();
118 Message& enterVariant(const std::string& signature);
119 Message& exitVariant();
120 Message& enterStruct(const std::string& signature);
121 Message& exitStruct();
122
123 explicit operator bool() const;
124 void clearFlags();
125
126 std::string getInterfaceName() const;
127 std::string getMemberName() const;
128 std::string getSender() const;
129 std::string getPath() const;
130 std::string getDestination() const;
131 void peekType(std::string& type, std::string& contents) const;
132 bool isValid() const;
133 bool isEmpty() const;
134
135 void copyTo(Message& destination, bool complete) const;
136 void seal();
137 void rewind(bool complete);
138
139 pid_t getCredsPid() const;
140 uid_t getCredsUid() const;
141 uid_t getCredsEuid() const;
142 gid_t getCredsGid() const;
143 gid_t getCredsEgid() const;
144 std::vector<gid_t> getCredsSupplementaryGids() const;
145 std::string getSELinuxContext() const;
146
147 class Factory;
148
149 protected:
150 Message() = default;
151 explicit Message(internal::ISdBus* sdbus) noexcept;
152 Message(void *msg, internal::ISdBus* sdbus) noexcept;
153 Message(void *msg, internal::ISdBus* sdbus, adopt_message_t) noexcept;
154
155 Message(const Message&) noexcept;
156 Message& operator=(const Message&) noexcept;
157 Message(Message&& other) noexcept;
158 Message& operator=(Message&& other) noexcept;
159
160 ~Message();
161
162 friend Factory;
163
164 protected:
165 void* msg_{};
166 internal::ISdBus* sdbus_{};
167 mutable bool ok_{true};
168 };
169
170 class MethodCall : public Message
171 {
172 using Message::Message;
173 friend Factory;
174
175 public:
176 MethodCall() = default;
177
178 MethodReply send(uint64_t timeout) const;
179 [[deprecated("Use send overload with floating_slot instead")]] void send(void* callback, void* userData, uint64_t timeout, dont_request_slot_t) const;
180 void send(void* callback, void* userData, uint64_t timeout, floating_slot_t) const;
181 [[nodiscard]] Slot send(void* callback, void* userData, uint64_t timeout) const;
182
183 MethodReply createReply() const;
184 MethodReply createErrorReply(const sdbus::Error& error) const;
185
186 void dontExpectReply();
187 bool doesntExpectReply() const;
188
189 protected:
190 MethodCall(void *msg, internal::ISdBus* sdbus, const internal::IConnection* connection, adopt_message_t) noexcept;
191
192 private:
193 MethodReply sendWithReply(uint64_t timeout = 0) const;
194 MethodReply sendWithNoReply() const;
195 const internal::IConnection* connection_{};
196 };
197
198 class MethodReply : public Message
199 {
200 using Message::Message;
201 friend Factory;
202
203 public:
204 MethodReply() = default;
205 void send() const;
206 };
207
208 class Signal : public Message
209 {
210 using Message::Message;
211 friend Factory;
212
213 public:
214 Signal() = default;
215 void setDestination(const std::string& destination);
216 void send() const;
217 };
218
220 {
221 using Message::Message;
222 friend Factory;
223
224 public:
225 PropertySetCall() = default;
226 };
227
229 {
230 using Message::Message;
231 friend Factory;
232
233 public:
234 PropertyGetReply() = default;
235 };
236
237 // Represents any of the above message types, or just a message that serves as a container for data
238 class PlainMessage : public Message
239 {
240 using Message::Message;
241 friend Factory;
242
243 public:
244 PlainMessage() = default;
245 };
246
247 template <typename _Element>
248 inline Message& operator<<(Message& msg, const std::vector<_Element>& items)
249 {
250 msg.openContainer(signature_of<_Element>::str());
251
252 for (const auto& item : items)
253 msg << item;
254
255 msg.closeContainer();
256
257 return msg;
258 }
259
260 template <typename _Key, typename _Value>
261 inline Message& operator<<(Message& msg, const std::map<_Key, _Value>& items)
262 {
263 const std::string dictEntrySignature = signature_of<_Key>::str() + signature_of<_Value>::str();
264 const std::string arraySignature = "{" + dictEntrySignature + "}";
265
266 msg.openContainer(arraySignature);
267
268 for (const auto& item : items)
269 {
270 msg.openDictEntry(dictEntrySignature);
271 msg << item.first;
272 msg << item.second;
273 msg.closeDictEntry();
274 }
275
276 msg.closeContainer();
277
278 return msg;
279 }
280
281 namespace detail
282 {
283 template <typename... _Args>
284 void serialize_pack(Message& msg, _Args&&... args)
285 {
286 (void)(msg << ... << args);
287 }
288
289 template <class _Tuple, std::size_t... _Is>
290 void serialize_tuple( Message& msg
291 , const _Tuple& t
292 , std::index_sequence<_Is...>)
293 {
294 serialize_pack(msg, std::get<_Is>(t)...);
295 }
296 }
297
298 template <typename... _ValueTypes>
299 inline Message& operator<<(Message& msg, const Struct<_ValueTypes...>& item)
300 {
301 auto structSignature = signature_of<Struct<_ValueTypes...>>::str();
302 assert(structSignature.size() > 2);
303 // Remove opening and closing parenthesis from the struct signature to get contents signature
304 auto structContentSignature = structSignature.substr(1, structSignature.size()-2);
305
306 msg.openStruct(structContentSignature);
307 detail::serialize_tuple(msg, item, std::index_sequence_for<_ValueTypes...>{});
308 msg.closeStruct();
309
310 return msg;
311 }
312
313 template <typename... _ValueTypes>
314 inline Message& operator<<(Message& msg, const std::tuple<_ValueTypes...>& item)
315 {
316 detail::serialize_tuple(msg, item, std::index_sequence_for<_ValueTypes...>{});
317 return msg;
318 }
319
320
321 template <typename _Element>
322 inline Message& operator>>(Message& msg, std::vector<_Element>& items)
323 {
324 if(!msg.enterContainer(signature_of<_Element>::str()))
325 return msg;
326
327 while (true)
328 {
329 _Element elem;
330 if (msg >> elem)
331 items.emplace_back(std::move(elem));
332 else
333 break;
334 }
335
336 msg.clearFlags();
337
338 msg.exitContainer();
339
340 return msg;
341 }
342
343 template <typename _Key, typename _Value>
344 inline Message& operator>>(Message& msg, std::map<_Key, _Value>& items)
345 {
346 const std::string dictEntrySignature = signature_of<_Key>::str() + signature_of<_Value>::str();
347 const std::string arraySignature = "{" + dictEntrySignature + "}";
348
349 if (!msg.enterContainer(arraySignature))
350 return msg;
351
352 while (true)
353 {
354 if (!msg.enterDictEntry(dictEntrySignature))
355 break;
356
357 _Key key;
358 _Value value;
359 msg >> key >> value;
360
361 items.emplace(std::move(key), std::move(value));
362
363 msg.exitDictEntry();
364 }
365
366 msg.clearFlags();
367
368 msg.exitContainer();
369
370 return msg;
371 }
372
373 namespace detail
374 {
375 template <typename... _Args>
376 void deserialize_pack(Message& msg, _Args&... args)
377 {
378 (void)(msg >> ... >> args);
379 }
380
381 template <class _Tuple, std::size_t... _Is>
382 void deserialize_tuple( Message& msg
383 , _Tuple& t
384 , std::index_sequence<_Is...> )
385 {
386 deserialize_pack(msg, std::get<_Is>(t)...);
387 }
388 }
389
390 template <typename... _ValueTypes>
391 inline Message& operator>>(Message& msg, Struct<_ValueTypes...>& item)
392 {
393 auto structSignature = signature_of<Struct<_ValueTypes...>>::str();
394 // Remove opening and closing parenthesis from the struct signature to get contents signature
395 auto structContentSignature = structSignature.substr(1, structSignature.size()-2);
396
397 if (!msg.enterStruct(structContentSignature))
398 return msg;
399
400 detail::deserialize_tuple(msg, item, std::index_sequence_for<_ValueTypes...>{});
401
402 msg.exitStruct();
403
404 return msg;
405 }
406
407 template <typename... _ValueTypes>
408 inline Message& operator>>(Message& msg, std::tuple<_ValueTypes...>& item)
409 {
410 detail::deserialize_tuple(msg, item, std::index_sequence_for<_ValueTypes...>{});
411 return msg;
412 }
413
414}
415
416#endif /* SDBUS_CXX_MESSAGE_H_ */
Definition: Error.h:44
Definition: Message.h:71
Definition: Message.h:171
Definition: Message.h:199
Definition: Types.h:153
Definition: Message.h:239
Definition: Message.h:229
Definition: Message.h:220
Definition: Message.h:209
Definition: Types.h:174
Definition: Types.h:200
Definition: Types.h:54
Definition: TypeTraits.h:79
Definition: TypeTraits.h:76
Definition: TypeTraits.h:73
Definition: TypeTraits.h:88