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