27#ifndef SDBUS_CXX_MESSAGE_H_
28#define SDBUS_CXX_MESSAGE_H_
35#if __cplusplus >= 202002L
39#include <unordered_map>
51 template <
typename... _ValueTypes>
class Struct;
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);
94 template <
typename _Element,
typename _Allocator>
95 Message& operator<<(
const std::vector<_Element, _Allocator>& items);
96 template <
typename _Element, std::
size_t _Size>
97 Message& operator<<(
const std::array<_Element, _Size>& items);
98#if __cplusplus >= 202002L
99 template <
typename _Element, std::
size_t _Extent>
100 Message& operator<<(
const std::span<_Element, _Extent>& items);
102 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
103 Message& operator<<(
const std::map<_Key, _Value, _Compare, _Allocator>& items);
104 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
105 Message& operator<<(
const std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>& items);
106 template <
typename... _ValueTypes>
108 template <
typename... _ValueTypes>
109 Message& operator<<(
const std::tuple<_ValueTypes...>& item);
111 Message& operator>>(
bool& item);
112 Message& operator>>(int16_t& item);
113 Message& operator>>(int32_t& item);
114 Message& operator>>(int64_t& item);
115 Message& operator>>(uint8_t& item);
116 Message& operator>>(uint16_t& item);
117 Message& operator>>(uint32_t& item);
118 Message& operator>>(uint64_t& item);
119 Message& operator>>(
double& item);
120 Message& operator>>(
char*& item);
121 Message& operator>>(std::string &item);
126 template <
typename _Element,
typename _Allocator>
127 Message& operator>>(std::vector<_Element, _Allocator>& items);
128 template <
typename _Element, std::
size_t _Size>
129 Message& operator>>(std::array<_Element, _Size>& items);
130#if __cplusplus >= 202002L
131 template <
typename _Element, std::
size_t _Extent>
132 Message& operator>>(std::span<_Element, _Extent>& items);
134 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
135 Message& operator>>(std::map<_Key, _Value, _Compare, _Allocator>& items);
136 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
137 Message& operator>>(std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>& items);
138 template <
typename... _ValueTypes>
140 template <
typename... _ValueTypes>
141 Message& operator>>(std::tuple<_ValueTypes...>& item);
143 Message& openContainer(
const std::string& signature);
145 Message& openDictEntry(
const std::string& signature);
147 Message& openVariant(
const std::string& signature);
149 Message& openStruct(
const std::string& signature);
152 Message& enterContainer(
const std::string& signature);
154 Message& enterDictEntry(
const std::string& signature);
156 Message& enterVariant(
const std::string& signature);
158 Message& enterStruct(
const std::string& signature);
161 Message& appendArray(
char type,
const void *ptr,
size_t size);
162 Message& readArray(
char type,
const void **ptr,
size_t *size);
164 explicit operator bool()
const;
167 std::string getInterfaceName()
const;
168 std::string getMemberName()
const;
169 std::string getSender()
const;
170 std::string getPath()
const;
171 std::string getDestination()
const;
172 void peekType(std::string& type, std::string& contents)
const;
173 bool isValid()
const;
174 bool isEmpty()
const;
175 bool isAtEnd(
bool complete)
const;
177 void copyTo(
Message& destination,
bool complete)
const;
179 void rewind(
bool complete);
181 pid_t getCredsPid()
const;
182 uid_t getCredsUid()
const;
183 uid_t getCredsEuid()
const;
184 gid_t getCredsGid()
const;
185 gid_t getCredsEgid()
const;
186 std::vector<gid_t> getCredsSupplementaryGids()
const;
187 std::string getSELinuxContext()
const;
192 template <
typename _Array>
193 void serializeArray(
const _Array& items);
194 template <
typename _Array>
195 void deserializeArray(_Array& items);
196 template <
typename _Array>
197 void deserializeArrayFast(_Array& items);
198 template <
typename _Element,
typename _Allocator>
199 void deserializeArrayFast(std::vector<_Element, _Allocator>& items);
200 template <
typename _Array>
201 void deserializeArraySlow(_Array& items);
202 template <
typename _Element,
typename _Allocator>
203 void deserializeArraySlow(std::vector<_Element, _Allocator>& items);
205 template <
typename _Dictionary>
206 void serializeDictionary(
const _Dictionary& items);
207 template <
typename _Dictionary>
208 void deserializeDictionary(_Dictionary& items);
212 explicit Message(internal::ISdBus* sdbus)
noexcept;
213 Message(
void *msg, internal::ISdBus* sdbus)
noexcept;
227 internal::ISdBus* sdbus_{};
228 mutable bool ok_{
true};
233 using Message::Message;
240 [[deprecated(
"Use send overload with floating_slot instead")]]
void send(
void* callback,
void* userData, uint64_t timeout,
dont_request_slot_t)
const;
241 void send(
void* callback,
void* userData, uint64_t timeout,
floating_slot_t)
const;
242 [[nodiscard]] Slot send(
void* callback,
void* userData, uint64_t timeout)
const;
247 void dontExpectReply();
248 bool doesntExpectReply()
const;
254 MethodReply sendWithReply(uint64_t timeout = 0)
const;
256 const internal::IConnection* connection_{};
261 using Message::Message;
271 using Message::Message;
276 void setDestination(
const std::string& destination);
282 using Message::Message;
291 using Message::Message;
301 using Message::Message;
308 template <
typename _Element,
typename _Allocator>
309 inline Message& Message::operator<<(
const std::vector<_Element, _Allocator>& items)
311 serializeArray(items);
316 template <
typename _Element, std::
size_t _Size>
317 inline Message& Message::operator<<(
const std::array<_Element, _Size>& items)
319 serializeArray(items);
324#if __cplusplus >= 202002L
325 template <
typename _Element, std::
size_t _Extent>
326 inline Message& Message::operator<<(
const std::span<_Element, _Extent>& items)
328 serializeArray(items);
334 template <
typename _Array>
335 inline void Message::serializeArray(
const _Array& items)
337 using ElementType =
typename _Array::value_type;
341 if constexpr (signature_of<ElementType>::is_trivial_dbus_type && !std::is_same_v<ElementType, bool>)
343 appendArray(*signature_of<ElementType>::str().c_str(), items.data(), items.size() *
sizeof(ElementType));
347 openContainer(signature_of<ElementType>::str());
349 for (
const auto& item : items)
356 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
357 inline Message& Message::operator<<(
const std::map<_Key, _Value, _Compare, _Allocator>& items)
359 serializeDictionary(items);
364 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
365 inline Message& Message::operator<<(
const std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>& items)
367 serializeDictionary(items);
372 template <
typename _Dictionary>
373 inline void Message::serializeDictionary(
const _Dictionary& items)
375 using KeyType =
typename _Dictionary::key_type;
376 using ValueType =
typename _Dictionary::mapped_type;
378 const std::string dictEntrySignature = signature_of<KeyType>::str() + signature_of<ValueType>::str();
379 const std::string arraySignature =
"{" + dictEntrySignature +
"}";
381 openContainer(arraySignature);
383 for (
const auto& item : items)
385 openDictEntry(dictEntrySignature);
387 *
this << item.second;
396 template <
typename... _Args>
397 void serialize_pack(Message& msg, _Args&&... args)
399 (void)(msg << ... << args);
402 template <
class _Tuple, std::size_t... _Is>
403 void serialize_tuple( Message& msg
405 , std::index_sequence<_Is...>)
407 serialize_pack(msg, std::get<_Is>(t)...);
411 template <
typename... _ValueTypes>
412 inline Message& Message::operator<<(
const Struct<_ValueTypes...>& item)
414 auto structSignature = signature_of<Struct<_ValueTypes...>>::str();
415 assert(structSignature.size() > 2);
417 auto structContentSignature = structSignature.substr(1, structSignature.size() - 2);
419 openStruct(structContentSignature);
420 detail::serialize_tuple(*
this, item, std::index_sequence_for<_ValueTypes...>{});
426 template <
typename... _ValueTypes>
427 inline Message& Message::operator<<(
const std::tuple<_ValueTypes...>& item)
429 detail::serialize_tuple(*
this, item, std::index_sequence_for<_ValueTypes...>{});
433 template <
typename _Element,
typename _Allocator>
434 inline Message& Message::operator>>(std::vector<_Element, _Allocator>& items)
436 deserializeArray(items);
441 template <
typename _Element, std::
size_t _Size>
442 inline Message& Message::operator>>(std::array<_Element, _Size>& items)
444 deserializeArray(items);
449#if __cplusplus >= 202002L
450 template <
typename _Element, std::
size_t _Extent>
451 inline Message& Message::operator>>(std::span<_Element, _Extent>& items)
453 deserializeArray(items);
459 template <
typename _Array>
460 inline void Message::deserializeArray(_Array& items)
462 using ElementType =
typename _Array::value_type;
466 if constexpr (signature_of<ElementType>::is_trivial_dbus_type && !std::is_same_v<ElementType, bool>)
468 deserializeArrayFast(items);
472 deserializeArraySlow(items);
476 template <
typename _Array>
477 inline void Message::deserializeArrayFast(_Array& items)
479 using ElementType =
typename _Array::value_type;
482 const ElementType* arrayPtr{};
484 readArray(*signature_of<ElementType>::str().c_str(), (
const void**)&arrayPtr, &arraySize);
486 size_t elementsInMsg = arraySize /
sizeof(ElementType);
487 bool notEnoughSpace = items.size() < elementsInMsg;
488 SDBUS_THROW_ERROR_IF(notEnoughSpace,
"Failed to deserialize array: not enough space in destination sequence", EINVAL);
490 std::copy_n(arrayPtr, elementsInMsg, items.begin());
493 template <
typename _Element,
typename _Allocator>
494 void Message::deserializeArrayFast(std::vector<_Element, _Allocator>& items)
497 const _Element* arrayPtr{};
499 readArray(*signature_of<_Element>::str().c_str(), (
const void**)&arrayPtr, &arraySize);
501 items.insert(items.end(), arrayPtr, arrayPtr + (arraySize /
sizeof(_Element)));
504 template <
typename _Array>
505 inline void Message::deserializeArraySlow(_Array& items)
507 using ElementType =
typename _Array::value_type;
509 if(!enterContainer(signature_of<ElementType>::str()))
512 for (
auto& elem : items)
513 if (!(*
this >> elem))
516 SDBUS_THROW_ERROR_IF(!isAtEnd(
false),
"Failed to deserialize array: not enough space in destination sequence", EINVAL);
523 template <
typename _Element,
typename _Allocator>
524 void Message::deserializeArraySlow(std::vector<_Element, _Allocator>& items)
526 if(!enterContainer(signature_of<_Element>::str()))
533 items.emplace_back(std::move(elem));
543 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
544 inline Message& Message::operator>>(std::map<_Key, _Value, _Compare, _Allocator>& items)
546 deserializeDictionary(items);
551 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
552 inline Message& Message::operator>>(std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>& items)
554 deserializeDictionary(items);
559 template <
typename _Dictionary>
560 inline void Message::deserializeDictionary(_Dictionary& items)
562 using KeyType =
typename _Dictionary::key_type;
563 using ValueType =
typename _Dictionary::mapped_type;
565 const std::string dictEntrySignature = signature_of<KeyType>::str() + signature_of<ValueType>::str();
566 const std::string arraySignature =
"{" + dictEntrySignature +
"}";
568 if (!enterContainer(arraySignature))
573 if (!enterDictEntry(dictEntrySignature))
578 *
this >> key >> value;
580 items.emplace(std::move(key), std::move(value));
592 template <
typename... _Args>
593 void deserialize_pack(Message& msg, _Args&... args)
595 (void)(msg >> ... >> args);
598 template <
class _Tuple, std::size_t... _Is>
599 void deserialize_tuple( Message& msg
601 , std::index_sequence<_Is...> )
603 deserialize_pack(msg, std::get<_Is>(t)...);
607 template <
typename... _ValueTypes>
608 inline Message& Message::operator>>(Struct<_ValueTypes...>& item)
610 auto structSignature = signature_of<Struct<_ValueTypes...>>::str();
612 auto structContentSignature = structSignature.substr(1, structSignature.size()-2);
614 if (!enterStruct(structContentSignature))
617 detail::deserialize_tuple(*
this, item, std::index_sequence_for<_ValueTypes...>{});
624 template <
typename... _ValueTypes>
625 inline Message& Message::operator>>(std::tuple<_ValueTypes...>& item)
627 detail::deserialize_tuple(*
this, item, std::index_sequence_for<_ValueTypes...>{});
Definition: Message.h:232
Definition: Message.h:260
Definition: Message.h:300
Definition: Message.h:290
Definition: Message.h:281
Definition: Message.h:270
Definition: TypeTraits.h:84
Definition: TypeTraits.h:81
Definition: TypeTraits.h:78