27#ifndef SDBUS_CXX_MESSAGE_H_
28#define SDBUS_CXX_MESSAGE_H_
35#if __cplusplus >= 202002L
39#include <unordered_map>
52 template <
typename... _ValueTypes>
class Struct;
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);
95 template <
typename _Element,
typename _Allocator>
96 Message& operator<<(
const std::vector<_Element, _Allocator>& items);
97 template <
typename _Element, std::
size_t _Size>
98 Message& operator<<(
const std::array<_Element, _Size>& items);
99#if __cplusplus >= 202002L
100 template <
typename _Element, std::
size_t _Extent>
101 Message& operator<<(
const std::span<_Element, _Extent>& items);
103 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
104 Message& operator<<(
const std::map<_Key, _Value, _Compare, _Allocator>& items);
105 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
106 Message& operator<<(
const std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>& items);
107 template <
typename... _ValueTypes>
108 Message& operator<<(
const Struct<_ValueTypes...>& item);
109 template <
typename... _ValueTypes>
110 Message& operator<<(
const std::tuple<_ValueTypes...>& item);
112 Message& operator>>(
bool& item);
113 Message& operator>>(int16_t& item);
114 Message& operator>>(int32_t& item);
115 Message& operator>>(int64_t& item);
116 Message& operator>>(uint8_t& item);
117 Message& operator>>(uint16_t& item);
118 Message& operator>>(uint32_t& item);
119 Message& operator>>(uint64_t& item);
120 Message& operator>>(
double& item);
121 Message& operator>>(
char*& item);
122 Message& operator>>(std::string &item);
127 template <
typename _Element,
typename _Allocator>
128 Message& operator>>(std::vector<_Element, _Allocator>& items);
129 template <
typename _Element, std::
size_t _Size>
130 Message& operator>>(std::array<_Element, _Size>& items);
131#if __cplusplus >= 202002L
132 template <
typename _Element, std::
size_t _Extent>
133 Message& operator>>(std::span<_Element, _Extent>& items);
135 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
136 Message& operator>>(std::map<_Key, _Value, _Compare, _Allocator>& items);
137 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
138 Message& operator>>(std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>& items);
139 template <
typename... _ValueTypes>
140 Message& operator>>(Struct<_ValueTypes...>& item);
141 template <
typename... _ValueTypes>
142 Message& operator>>(std::tuple<_ValueTypes...>& item);
144 Message& openContainer(
const std::string& signature);
146 Message& openDictEntry(
const std::string& signature);
148 Message& openVariant(
const std::string& signature);
150 Message& openStruct(
const std::string& signature);
153 Message& enterContainer(
const std::string& signature);
155 Message& enterDictEntry(
const std::string& signature);
157 Message& enterVariant(
const std::string& signature);
159 Message& enterStruct(
const std::string& signature);
162 Message& appendArray(
char type,
const void *ptr,
size_t size);
163 Message& readArray(
char type,
const void **ptr,
size_t *size);
165 explicit operator bool()
const;
168 std::string getInterfaceName()
const;
169 std::string getMemberName()
const;
170 std::string getSender()
const;
171 std::string getPath()
const;
172 std::string getDestination()
const;
173 void peekType(std::string& type, std::string& contents)
const;
174 bool isValid()
const;
175 bool isEmpty()
const;
176 bool isAtEnd(
bool complete)
const;
178 void copyTo(
Message& destination,
bool complete)
const;
180 void rewind(
bool complete);
182 pid_t getCredsPid()
const;
183 uid_t getCredsUid()
const;
184 uid_t getCredsEuid()
const;
185 gid_t getCredsGid()
const;
186 gid_t getCredsEgid()
const;
187 std::vector<gid_t> getCredsSupplementaryGids()
const;
188 std::string getSELinuxContext()
const;
193 template <
typename _Array>
194 void serializeArray(
const _Array& items);
195 template <
typename _Array>
196 void deserializeArray(_Array& items);
197 template <
typename _Array>
198 void deserializeArrayFast(_Array& items);
199 template <
typename _Element,
typename _Allocator>
200 void deserializeArrayFast(std::vector<_Element, _Allocator>& items);
201 template <
typename _Array>
202 void deserializeArraySlow(_Array& items);
203 template <
typename _Element,
typename _Allocator>
204 void deserializeArraySlow(std::vector<_Element, _Allocator>& items);
206 template <
typename _Dictionary>
207 void serializeDictionary(
const _Dictionary& items);
208 template <
typename _Dictionary>
209 void deserializeDictionary(_Dictionary& items);
213 explicit Message(internal::ISdBus* sdbus)
noexcept;
214 Message(
void *msg, internal::ISdBus* sdbus)
noexcept;
228 internal::ISdBus* sdbus_{};
229 mutable bool ok_{
true};
234 using Message::Message;
241 [[deprecated(
"Use send overload with floating_slot instead")]]
void send(
void* callback,
void* userData, uint64_t timeout,
dont_request_slot_t)
const;
242 void send(
void* callback,
void* userData, uint64_t timeout,
floating_slot_t)
const;
243 [[nodiscard]] Slot send(
void* callback,
void* userData, uint64_t timeout)
const;
248 void dontExpectReply();
249 bool doesntExpectReply()
const;
255 MethodReply sendWithReply(uint64_t timeout = 0)
const;
257 const internal::IConnection* connection_{};
262 using Message::Message;
272 using Message::Message;
277 void setDestination(
const std::string& destination);
283 using Message::Message;
292 using Message::Message;
302 using Message::Message;
309 template <
typename _Element,
typename _Allocator>
310 inline Message& Message::operator<<(
const std::vector<_Element, _Allocator>& items)
312 serializeArray(items);
317 template <
typename _Element, std::
size_t _Size>
318 inline Message& Message::operator<<(
const std::array<_Element, _Size>& items)
320 serializeArray(items);
325#if __cplusplus >= 202002L
326 template <
typename _Element, std::
size_t _Extent>
327 inline Message& Message::operator<<(
const std::span<_Element, _Extent>& items)
329 serializeArray(items);
335 template <
typename _Array>
336 inline void Message::serializeArray(
const _Array& items)
338 using ElementType =
typename _Array::value_type;
342 if constexpr (signature_of<ElementType>::is_trivial_dbus_type && !std::is_same_v<ElementType, bool>)
344 appendArray(*signature_of<ElementType>::str().c_str(), items.data(), items.size() *
sizeof(ElementType));
348 openContainer(signature_of<ElementType>::str());
350 for (
const auto& item : items)
357 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
358 inline Message& Message::operator<<(
const std::map<_Key, _Value, _Compare, _Allocator>& items)
360 serializeDictionary(items);
365 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
366 inline Message& Message::operator<<(
const std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>& items)
368 serializeDictionary(items);
373 template <
typename _Dictionary>
374 inline void Message::serializeDictionary(
const _Dictionary& items)
376 using KeyType =
typename _Dictionary::key_type;
377 using ValueType =
typename _Dictionary::mapped_type;
379 const std::string dictEntrySignature = signature_of<KeyType>::str() + signature_of<ValueType>::str();
380 const std::string arraySignature =
"{" + dictEntrySignature +
"}";
382 openContainer(arraySignature);
384 for (
const auto& item : items)
386 openDictEntry(dictEntrySignature);
388 *
this << item.second;
397 template <
typename... _Args>
398 void serialize_pack(Message& msg, _Args&&... args)
400 (void)(msg << ... << args);
403 template <
class _Tuple, std::size_t... _Is>
404 void serialize_tuple( Message& msg
406 , std::index_sequence<_Is...>)
408 serialize_pack(msg, std::get<_Is>(t)...);
412 template <
typename... _ValueTypes>
413 inline Message& Message::operator<<(
const Struct<_ValueTypes...>& item)
415 auto structSignature = signature_of<Struct<_ValueTypes...>>::str();
416 assert(structSignature.size() > 2);
418 auto structContentSignature = structSignature.substr(1, structSignature.size() - 2);
420 openStruct(structContentSignature);
421 detail::serialize_tuple(*
this, item, std::index_sequence_for<_ValueTypes...>{});
427 template <
typename... _ValueTypes>
428 inline Message& Message::operator<<(
const std::tuple<_ValueTypes...>& item)
430 detail::serialize_tuple(*
this, item, std::index_sequence_for<_ValueTypes...>{});
434 template <
typename _Element,
typename _Allocator>
435 inline Message& Message::operator>>(std::vector<_Element, _Allocator>& items)
437 deserializeArray(items);
442 template <
typename _Element, std::
size_t _Size>
443 inline Message& Message::operator>>(std::array<_Element, _Size>& items)
445 deserializeArray(items);
450#if __cplusplus >= 202002L
451 template <
typename _Element, std::
size_t _Extent>
452 inline Message& Message::operator>>(std::span<_Element, _Extent>& items)
454 deserializeArray(items);
460 template <
typename _Array>
461 inline void Message::deserializeArray(_Array& items)
463 using ElementType =
typename _Array::value_type;
467 if constexpr (signature_of<ElementType>::is_trivial_dbus_type && !std::is_same_v<ElementType, bool>)
469 deserializeArrayFast(items);
473 deserializeArraySlow(items);
477 template <
typename _Array>
478 inline void Message::deserializeArrayFast(_Array& items)
480 using ElementType =
typename _Array::value_type;
483 const ElementType* arrayPtr{};
485 readArray(*signature_of<ElementType>::str().c_str(), (
const void**)&arrayPtr, &arraySize);
487 size_t elementsInMsg = arraySize /
sizeof(ElementType);
488 bool notEnoughSpace = items.size() < elementsInMsg;
489 SDBUS_THROW_ERROR_IF(notEnoughSpace,
"Failed to deserialize array: not enough space in destination sequence", EINVAL);
491 std::copy_n(arrayPtr, elementsInMsg, items.begin());
494 template <
typename _Element,
typename _Allocator>
495 void Message::deserializeArrayFast(std::vector<_Element, _Allocator>& items)
498 const _Element* arrayPtr{};
500 readArray(*signature_of<_Element>::str().c_str(), (
const void**)&arrayPtr, &arraySize);
502 items.insert(items.end(), arrayPtr, arrayPtr + (arraySize /
sizeof(_Element)));
505 template <
typename _Array>
506 inline void Message::deserializeArraySlow(_Array& items)
508 using ElementType =
typename _Array::value_type;
510 if(!enterContainer(signature_of<ElementType>::str()))
513 for (
auto& elem : items)
514 if (!(*this >> elem))
517 SDBUS_THROW_ERROR_IF(!isAtEnd(
false),
"Failed to deserialize array: not enough space in destination sequence", EINVAL);
524 template <
typename _Element,
typename _Allocator>
525 void Message::deserializeArraySlow(std::vector<_Element, _Allocator>& items)
527 if(!enterContainer(signature_of<_Element>::str()))
534 items.emplace_back(std::move(elem));
544 template <
typename _Key,
typename _Value,
typename _Compare,
typename _Allocator>
545 inline Message& Message::operator>>(std::map<_Key, _Value, _Compare, _Allocator>& items)
547 deserializeDictionary(items);
552 template <
typename _Key,
typename _Value,
typename _Hash,
typename _KeyEqual,
typename _Allocator>
553 inline Message& Message::operator>>(std::unordered_map<_Key, _Value, _Hash, _KeyEqual, _Allocator>& items)
555 deserializeDictionary(items);
560 template <
typename _Dictionary>
561 inline void Message::deserializeDictionary(_Dictionary& items)
563 using KeyType =
typename _Dictionary::key_type;
564 using ValueType =
typename _Dictionary::mapped_type;
566 const std::string dictEntrySignature = signature_of<KeyType>::str() + signature_of<ValueType>::str();
567 const std::string arraySignature =
"{" + dictEntrySignature +
"}";
569 if (!enterContainer(arraySignature))
574 if (!enterDictEntry(dictEntrySignature))
579 *
this >> key >> value;
581 items.emplace(std::move(key), std::move(value));
593 template <
typename... _Args>
594 void deserialize_pack(Message& msg, _Args&... args)
596 (void)(msg >> ... >> args);
599 template <
class _Tuple, std::size_t... _Is>
600 void deserialize_tuple( Message& msg
602 , std::index_sequence<_Is...> )
604 deserialize_pack(msg, std::get<_Is>(t)...);
608 template <
typename... _ValueTypes>
609 inline Message& Message::operator>>(Struct<_ValueTypes...>& item)
611 auto structSignature = signature_of<Struct<_ValueTypes...>>::str();
613 auto structContentSignature = structSignature.substr(1, structSignature.size()-2);
615 if (!enterStruct(structContentSignature))
618 detail::deserialize_tuple(*
this, item, std::index_sequence_for<_ValueTypes...>{});
625 template <
typename... _ValueTypes>
626 inline Message& Message::operator>>(std::tuple<_ValueTypes...>& item)
628 detail::deserialize_tuple(*
this, item, std::index_sequence_for<_ValueTypes...>{});
Definition TypeTraits.h:84
Definition TypeTraits.h:81
Definition TypeTraits.h:78