Add support for Unix fd D-Bus type

This commit is contained in:
sangelovic
2019-06-08 21:35:22 +02:00
committed by Stanislav Angelovič
parent efe799ef3f
commit 57c840637c
13 changed files with 125 additions and 2 deletions

View File

@ -43,6 +43,7 @@ namespace sdbus {
class ObjectPath;
class Signature;
template <typename... _ValueTypes> class Struct;
struct UnixFd;
class MethodReply;
namespace internal {
class ISdBus;
@ -100,6 +101,7 @@ namespace sdbus {
Message& operator<<(const Variant &item);
Message& operator<<(const ObjectPath &item);
Message& operator<<(const Signature &item);
Message& operator<<(const UnixFd &item);
Message& operator>>(bool& item);
Message& operator>>(int16_t& item);
@ -115,6 +117,7 @@ namespace sdbus {
Message& operator>>(Variant &item);
Message& operator>>(ObjectPath &item);
Message& operator>>(Signature &item);
Message& operator>>(UnixFd &item);
Message& openContainer(const std::string& signature);
Message& closeContainer();

View File

@ -40,6 +40,7 @@ namespace sdbus {
template <typename... _ValueTypes> class Struct;
class ObjectPath;
class Signature;
struct UnixFd;
class Message;
class MethodCall;
class MethodReply;
@ -285,6 +286,17 @@ namespace sdbus {
}
};
template <>
struct signature_of<UnixFd>
{
static constexpr bool is_valid = true;
static const std::string str()
{
return "h";
}
};
template <typename _Element>
struct signature_of<std::vector<_Element>>
{

View File

@ -97,6 +97,12 @@ namespace sdbus {
mutable Message msg_{};
};
/********************************************//**
* @class Struct
*
* Representation of struct D-Bus type
*
***********************************************/
template <typename... _ValueTypes>
class Struct
: public std::tuple<_ValueTypes...>
@ -135,6 +141,12 @@ namespace sdbus {
return result_type(std::forward<_Elements>(args)...);
}
/********************************************//**
* @class ObjectPath
*
* Representation of object path D-Bus type
*
***********************************************/
class ObjectPath : public std::string
{
public:
@ -146,6 +158,12 @@ namespace sdbus {
using std::string::operator=;
};
/********************************************//**
* @class Signature
*
* Representation of Signature D-Bus type
*
***********************************************/
class Signature : public std::string
{
public:
@ -157,6 +175,27 @@ namespace sdbus {
using std::string::operator=;
};
/********************************************//**
* @struct UnixFd
*
* Representation of Unix file descriptor D-Bus type
*
***********************************************/
struct UnixFd
{
int fd_ = -1;
UnixFd() = default;
UnixFd(int fd)
: fd_(fd)
{}
operator int() const
{
return fd_;
}
};
}
#endif /* SDBUS_CXX_TYPES_H_ */

View File

@ -210,7 +210,15 @@ Message& Message::operator<<(const ObjectPath &item)
Message& Message::operator<<(const Signature &item)
{
auto r = sd_bus_message_append_basic((sd_bus_message*)msg_, SD_BUS_TYPE_SIGNATURE, item.c_str());
SDBUS_THROW_ERROR_IF(r < 0, "Failed to serialize an Signature value", -r);
SDBUS_THROW_ERROR_IF(r < 0, "Failed to serialize a Signature value", -r);
return *this;
}
Message& Message::operator<<(const UnixFd &item)
{
auto r = sd_bus_message_append_basic((sd_bus_message*)msg_, SD_BUS_TYPE_UNIX_FD, &item.fd_);
SDBUS_THROW_ERROR_IF(r < 0, "Failed to serialize a UnixFd value", -r);
return *this;
}
@ -383,6 +391,17 @@ Message& Message::operator>>(Signature &item)
return *this;
}
Message& Message::operator>>(UnixFd &item)
{
auto r = sd_bus_message_read_basic((sd_bus_message*)msg_, SD_BUS_TYPE_UNIX_FD, &item.fd_);
if (r == 0)
ok_ = false;
SDBUS_THROW_ERROR_IF(r < 0, "Failed to deserialize a UnixFd value", -r);
return *this;
}
Message& Message::openContainer(const std::string& signature)
{

View File

@ -209,6 +209,12 @@ TEST_F(SdbusTestObject, CallsMethodWithObjectPathSuccesfully)
ASSERT_THAT(resObjectPath, Eq(OBJECT_PATH_VALUE));
}
TEST_F(SdbusTestObject, CallsMethodWithUnixFdSuccesfully)
{
auto resUnixFd = m_proxy->getUnixFd();
ASSERT_THAT(resUnixFd, Gt(UNIX_FD_VALUE));
}
TEST_F(SdbusTestObject, CallsMethodWithComplexTypeSuccesfully)
{
auto resComplex = m_proxy->getComplex();

View File

@ -157,6 +157,10 @@ protected:
{
return OBJECT_PATH_VALUE;
}
sdbus::UnixFd getUnixFd() const
{
return UNIX_FD_VALUE;
}
ComplexType getComplex() const
{

View File

@ -97,6 +97,7 @@ protected:
object_.registerMethod("getSignature").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getSignature(); });
object_.registerMethod("getObjectPath").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getObjectPath(); });
object_.registerMethod("getUnixFd").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getUnixFd(); });
object_.registerMethod("getComplex").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getComplex(); }).markAsDeprecated();
@ -163,6 +164,7 @@ protected:
virtual void doOperationAsync(uint32_t param, sdbus::Result<uint32_t> result) = 0;
virtual sdbus::Signature getSignature() const = 0;
virtual sdbus::ObjectPath getObjectPath() const = 0;
virtual sdbus::UnixFd getUnixFd() const = 0;
virtual ComplexType getComplex() const = 0;
virtual void throwError() const = 0;
@ -266,6 +268,9 @@ R"delimiter(<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspectio
<arg type="u" direction="out"/>
<arg type="s" direction="out"/>
</method>
<method name="getUnixFd">
<arg type="h" direction="out"/>
</method>
<method name="multiply">
<arg type="x" direction="in"/>
<arg type="d" direction="in"/>

View File

@ -40,6 +40,7 @@ constexpr const int32_t INT64_VALUE{-1024};
const std::string STRING_VALUE{"sdbus-c++-testing"};
const sdbus::Signature SIGNATURE_VALUE{"a{is}"};
const sdbus::ObjectPath OBJECT_PATH_VALUE{"/"};
const int UNIX_FD_VALUE = 0;
const std::string DEFAULT_STATE_VALUE{"default-state-value"};
const uint32_t DEFAULT_ACTION_VALUE{999};

View File

@ -175,6 +175,13 @@ public:
return result;
}
sdbus::UnixFd getUnixFd()
{
sdbus::UnixFd result;
object_.callMethod("getUnixFd").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
ComplexType getComplex()
{
ComplexType result;

View File

@ -30,6 +30,7 @@
#include <cstdint>
using ::testing::Eq;
using ::testing::Gt;
using ::testing::DoubleEq;
using namespace std::string_literals;
@ -125,6 +126,21 @@ TEST(AMessage, CanCarryASimpleInteger)
ASSERT_THAT(dataRead, Eq(dataWritten));
}
TEST(AMessage, CanCarryAUnixFd)
{
sdbus::Message msg{sdbus::createPlainMessage()};
sdbus::UnixFd dataWritten = 0;
msg << dataWritten;
msg.seal();
sdbus::UnixFd dataRead;
msg >> dataRead;
ASSERT_THAT(dataRead, Gt(dataWritten));
}
TEST(AMessage, CanCarryAVariant)
{
sdbus::Message msg{sdbus::createPlainMessage()};

View File

@ -72,6 +72,7 @@ namespace
TYPE(sdbus::ObjectPath)HAS_DBUS_TYPE_SIGNATURE("o")
TYPE(sdbus::Signature)HAS_DBUS_TYPE_SIGNATURE("g")
TYPE(sdbus::Variant)HAS_DBUS_TYPE_SIGNATURE("v")
TYPE(sdbus::UnixFd)HAS_DBUS_TYPE_SIGNATURE("h")
TYPE(sdbus::Struct<bool>)HAS_DBUS_TYPE_SIGNATURE("(b)")
TYPE(sdbus::Struct<uint16_t, double, std::string, sdbus::Variant>)HAS_DBUS_TYPE_SIGNATURE("(qdsv)")
TYPE(std::vector<int16_t>)HAS_DBUS_TYPE_SIGNATURE("an")
@ -91,10 +92,11 @@ namespace
>
>,
sdbus::Signature,
sdbus::UnixFd,
const char*
>
>;
TYPE(ComplexType)HAS_DBUS_TYPE_SIGNATURE("a{t(a{ya(obva{is})}gs)}")
TYPE(ComplexType)HAS_DBUS_TYPE_SIGNATURE("a{t(a{ya(obva{is})}ghs)}")
typedef ::testing::Types< bool
, uint8_t
@ -110,6 +112,7 @@ namespace
, sdbus::ObjectPath
, sdbus::Signature
, sdbus::Variant
, sdbus::UnixFd
, sdbus::Struct<bool>
, sdbus::Struct<uint16_t, double, std::string, sdbus::Variant>
, std::vector<int16_t>

View File

@ -240,3 +240,10 @@ TEST(ASignature, CanBeConstructedFromStdString)
ASSERT_THAT(sdbus::Signature{aSignature}, Eq(aSignature));
}
TEST(AUnixFd, CanBeConstructedFromInt)
{
int fd{2};
ASSERT_THAT((int)sdbus::UnixFd{fd}, Eq(fd));
}

View File

@ -44,6 +44,7 @@ const char *atomic_type_to_string(char t)
{ 'o', "sdbus::ObjectPath" },
{ 'g', "sdbus::Signature" },
{ 'v', "sdbus::Variant" },
{ 'h', "sdbus::UnixFd" },
{ '\0', "" }
};