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