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>
 
  107        Message& operator<<(
const Struct<_ValueTypes...>& item);
 
  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>
 
  139        Message& operator>>(Struct<_ValueTypes...>& item);
 
  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 TypeTraits.h:84
Definition TypeTraits.h:81
Definition TypeTraits.h:78