diff --git a/include/sdbus-c++/Message.h b/include/sdbus-c++/Message.h index 9dd793e..de735ab 100644 --- a/include/sdbus-c++/Message.h +++ b/include/sdbus-c++/Message.h @@ -100,6 +100,7 @@ namespace sdbus { Message& operator<<(double item); Message& operator<<(const char *item); Message& operator<<(const std::string &item); + Message& operator<<(std::string_view item); Message& operator<<(const Variant &item); template Message& operator<<(const std::variant& value); diff --git a/include/sdbus-c++/TypeTraits.h b/include/sdbus-c++/TypeTraits.h index a0e6e2c..7b146c5 100644 --- a/include/sdbus-c++/TypeTraits.h +++ b/include/sdbus-c++/TypeTraits.h @@ -41,6 +41,7 @@ # endif #endif #include +#include #include #include #include @@ -231,6 +232,10 @@ namespace sdbus { static constexpr bool is_trivial_dbus_type = false; }; + template <> + struct signature_of : signature_of + {}; + template <> struct signature_of : signature_of {}; diff --git a/src/Message.cpp b/src/Message.cpp index 52421c9..cda9ccd 100644 --- a/src/Message.cpp +++ b/src/Message.cpp @@ -35,6 +35,7 @@ #include "ScopeGuard.h" #include +#include #include SDBUS_HEADER namespace sdbus { @@ -197,6 +198,17 @@ Message& Message::operator<<(const std::string& item) return *this; } +Message& Message::operator<<(std::string_view item) +{ + char* destPtr{}; + auto r = sd_bus_message_append_string_space((sd_bus_message*)msg_, item.length(), &destPtr); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to serialize a string_view value", -r); + + std::memcpy(destPtr, item.data(), item.length()); + + return *this; +} + Message& Message::operator<<(const Variant &item) { item.serializeTo(*this); diff --git a/tests/unittests/Message_test.cpp b/tests/unittests/Message_test.cpp index 964b650..d1d4175 100644 --- a/tests/unittests/Message_test.cpp +++ b/tests/unittests/Message_test.cpp @@ -119,7 +119,7 @@ namespace my { template <> struct sdbus::signature_of - : sdbus::signature_of>> + : sdbus::signature_of>> {}; /*-------------------------------------*/ @@ -204,6 +204,21 @@ TEST(AMessage, CanCarryASimpleInteger) ASSERT_THAT(dataRead, Eq(dataWritten)); } +TEST(AMessage, CanCarryAStringAsAStringView) +{ + auto msg = sdbus::createPlainMessage(); + + const std::string_view dataWritten = "Hello"; + + msg << dataWritten; + msg.seal(); + + std::string dataRead; + msg >> dataRead; + + ASSERT_THAT(dataRead, Eq(dataWritten)); +} + TEST(AMessage, CanCarryAUnixFd) { auto msg = sdbus::createPlainMessage(); diff --git a/tests/unittests/TypeTraits_test.cpp b/tests/unittests/TypeTraits_test.cpp index f06491a..be7464e 100644 --- a/tests/unittests/TypeTraits_test.cpp +++ b/tests/unittests/TypeTraits_test.cpp @@ -85,6 +85,7 @@ namespace TYPE(double)HAS_DBUS_TYPE_SIGNATURE("d") TYPE(const char*)HAS_DBUS_TYPE_SIGNATURE("s") TYPE(std::string)HAS_DBUS_TYPE_SIGNATURE("s") + TYPE(std::string_view)HAS_DBUS_TYPE_SIGNATURE("s") TYPE(sdbus::BusName)HAS_DBUS_TYPE_SIGNATURE("s") TYPE(sdbus::InterfaceName)HAS_DBUS_TYPE_SIGNATURE("s") TYPE(sdbus::MemberName)HAS_DBUS_TYPE_SIGNATURE("s") @@ -122,10 +123,11 @@ namespace >, sdbus::Signature, sdbus::UnixFd, - const char* + const char*, + std::string_view > >; - TYPE(ComplexType)HAS_DBUS_TYPE_SIGNATURE("a{t(a{ya(oanbva{is})}ghs)}") + TYPE(ComplexType)HAS_DBUS_TYPE_SIGNATURE("a{t(a{ya(oanbva{is})}ghss)}") typedef ::testing::Types< bool , uint8_t @@ -138,6 +140,7 @@ namespace , double , const char* , std::string + , std::string_view , sdbus::BusName , sdbus::InterfaceName , sdbus::MemberName