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