refactor: add strong types to public API (#414)

This introduces strong types for `std::string`-based D-Bus types. This facilitates safer, less error-prone and more expressive API.

What previously was `auto proxy = createProxy("org.sdbuscpp.concatenator", "/org/sdbuscpp/concatenator");` is now written like `auto proxy = createProxy(ServiceName{"org.sdbuscpp.concatenator"}, ObjectPath{"/org/sdbuscpp/concatenator"});`.

These types are:
  * `ObjectPath` type for the object path (the type has been around already but now is also used consistently in sdbus-c++ API for object path strings),
  * `InterfaceName` type for D-Bus interface names,
  * `BusName` (and its aliases `ServiceName` and `ConnectionName`) type for bus/service/connection names,
  * `MemberName` (and its aliases `MethodName`, `SignalName` and `PropertyName`) type for D-Bus method, signal and property names,
  * `Signature` type for the D-Bus signature (the type has been around already but now is also used consistently in sdbus-c++ API for signature strings),
  * `Error::Name` type for D-Bus error names.
This commit is contained in:
Stanislav Angelovič
2024-03-29 13:23:44 +01:00
parent fe21ee9656
commit 42f0bd07c0
60 changed files with 1085 additions and 621 deletions

View File

@ -184,7 +184,7 @@ The following diagram illustrates the major entities in sdbus-c++.
![class](sdbus-c++-class-diagram.png) ![class](sdbus-c++-class-diagram.png)
`IConnection` represents the concept of a D-Bus connection. You can connect to either the system bus or a session bus. Services can assign unique service names to those connections. An I/O event loop should be run on the bus connection. `IConnection` represents the concept of a D-Bus connection. You can connect to either the system bus or a session bus. Services can assign well-known service names to those connections. An I/O event loop should be run on the bus connection.
`IObject` represents the concept of an object that exposes its methods, signals and properties. Its responsibilities are: `IObject` represents the concept of an object that exposes its methods, signals and properties. Its responsibilities are:
@ -238,7 +238,7 @@ Let's have an object `/org/sdbuscpp/concatenator` that implements the `org.sdbus
In the following sections, we will elaborate on the ways of implementing such an object on both the server and the client side. In the following sections, we will elaborate on the ways of implementing such an object on both the server and the client side.
> **Before running Concatenator example in your system:** In order for your service to be allowed to provide a D-Bus API on system bus, a D-Bus security policy file has to be put in place for that service. Otherwise the service will fail to start (you'll get `[org.freedesktop.DBus.Error.AccessDenied] Failed to request bus name (Permission denied)`, for example). To make the Concatenator example work in your system, [look in this section of systemd configuration](systemd-dbus-config.md#dbus-configuration) for how to name the file, where to place it, how to populate it. For further information, consult [dbus-daemon documentation](https://dbus.freedesktop.org/doc/dbus-daemon.1.html), sections *INTEGRATING SYSTEM SERVICES* and *CONFIGURATION FILE*. As an example used for sdbus-c++ integration tests, you may look at the [policy file for sdbus-c++ integration tests](/tests/integrationtests/files/org.sdbuscpp.integrationtests.conf). > **Before running Concatenator example in your system:** In order for your service to be allowed to provide a D-Bus API on ** the system bus**, a D-Bus security policy file has to be put in place for that service. Otherwise the service will fail to start (you'll get `[org.freedesktop.DBus.Error.AccessDenied] Failed to request bus name (Permission denied)`, for example). To make the Concatenator example work in your system, [look in this section of systemd configuration](systemd-dbus-config.md#dbus-configuration) for how to name the file, where to place it, how to populate it. For further information, consult [dbus-daemon documentation](https://dbus.freedesktop.org/doc/dbus-daemon.1.html), sections *INTEGRATING SYSTEM SERVICES* and *CONFIGURATION FILE*. As an example used for sdbus-c++ integration tests, you may look at the [policy file for sdbus-c++ integration tests](/tests/integrationtests/files/org.sdbuscpp.integrationtests.conf).
Implementing the Concatenator example using basic sdbus-c++ API layer Implementing the Concatenator example using basic sdbus-c++ API layer
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -289,28 +289,29 @@ void concatenate(sdbus::MethodCall call)
reply.send(); reply.send();
// Emit 'concatenated' signal // Emit 'concatenated' signal
const char* interfaceName = "org.sdbuscpp.Concatenator"; sdbus::InterfaceName interfaceName{"org.sdbuscpp.Concatenator"};
auto signal = g_concatenator->createSignal(interfaceName, "concatenated"); sdbus::SignalName signalName{"concatenated"};
auto signal = g_concatenator->createSignal(interfaceName, signalName);
signal << result; signal << result;
g_concatenator->emitSignal(signal); g_concatenator->emitSignal(signal);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Create D-Bus connection to the system bus and requests name on it. // Create D-Bus connection to (either the session or system) bus and requests a well-known name on it.
const char* serviceName = "org.sdbuscpp.concatenator"; sdbus::ServiceName serviceName{"org.sdbuscpp.concatenator"};
auto connection = sdbus::createSystemBusConnection(serviceName); auto connection = sdbus::createBusConnection(serviceName);
// Create concatenator D-Bus object. // Create concatenator D-Bus object.
const char* objectPath = "/org/sdbuscpp/concatenator"; sdbus::ObjectPath objectPath{"/org/sdbuscpp/concatenator"};
auto concatenator = sdbus::createObject(*connection, objectPath); auto concatenator = sdbus::createObject(*connection, std::move(objectPath));
g_concatenator = concatenator.get(); g_concatenator = concatenator.get();
// Register D-Bus methods and signals on the concatenator object, and exports the object. // Register D-Bus methods and signals on the concatenator object, and exports the object.
const char* interfaceName = "org.sdbuscpp.Concatenator"; sdbus::InterfaceName interfaceName{"org.sdbuscpp.Concatenator"};
concatenator->addVTable( sdbus::MethodVTableItem{"concatenate", "ais", {}, "s", {}, &concatenate, {}} concatenator->addVTable( sdbus::MethodVTableItem{"concatenate", sdbus::Signature{"ais"}, {}, sdbus::Signature{"s"}, {}, &concatenate, {}}
, sdbus::SignalVTableItem{"concatenated", "s", {}, {}} ) , sdbus::SignalVTableItem{"concatenated", sdbus::Signature{"s"}, {}, {}} )
.forInterface(interfaceName); .forInterface(interfaceName);
// Run the I/O event loop on the bus connection. // Run the I/O event loop on the bus connection.
@ -349,21 +350,24 @@ int main(int argc, char *argv[])
{ {
// Create proxy object for the concatenator object on the server side. Since here // Create proxy object for the concatenator object on the server side. Since here
// we are creating the proxy instance without passing connection to it, the proxy // we are creating the proxy instance without passing connection to it, the proxy
// will create its own connection automatically, and it will be system bus connection. // will create its own connection automatically (to either system bus or session bus,
const char* destinationName = "org.sdbuscpp.concatenator"; // depending on the context).
const char* objectPath = "/org/sdbuscpp/concatenator"; sdbus::ServiceName destination{"org.sdbuscpp.concatenator"};
auto concatenatorProxy = sdbus::createProxy(destinationName, objectPath); sdbus::ObjectPath objectPath{"/org/sdbuscpp/concatenator"};
auto concatenatorProxy = sdbus::createProxy(std::move(destination), std::move(objectPath));
// Let's subscribe for the 'concatenated' signals // Let's subscribe for the 'concatenated' signals
const char* interfaceName = "org.sdbuscpp.Concatenator"; sdbus::InterfaceName interfaceName{"org.sdbuscpp.Concatenator"};
concatenatorProxy->registerSignalHandler(interfaceName, "concatenated", &onConcatenated); sdbus::SignalName signalName{"concatenated"};
concatenatorProxy->registerSignalHandler(interfaceName, signalName, &onConcatenated);
std::vector<int> numbers = {1, 2, 3}; std::vector<int> numbers = {1, 2, 3};
std::string separator = ":"; std::string separator = ":";
MethodName concatenate{"concatenate"};
// Invoke concatenate on given interface of the object // Invoke concatenate on given interface of the object
{ {
auto method = concatenatorProxy->createMethodCall(interfaceName, "concatenate"); auto method = concatenatorProxy->createMethodCall(interfaceName, concatenate);
method << numbers << separator; method << numbers << separator;
auto reply = concatenatorProxy->callMethod(method); auto reply = concatenatorProxy->callMethod(method);
std::string result; std::string result;
@ -373,7 +377,7 @@ int main(int argc, char *argv[])
/ // Invoke concatenate again, this time with no numbers and we shall get an error / // Invoke concatenate again, this time with no numbers and we shall get an error
{ {
auto method = concatenatorProxy->createMethodCall(interfaceName, "concatenate"); auto method = concatenatorProxy->createMethodCall(interfaceName, concatenate);
method << std::vector<int>() << separator; method << std::vector<int>() << separator;
try try
{ {
@ -408,11 +412,11 @@ Please note that we can create and destroy D-Bus object proxies dynamically, at
There are several factory methods to create a bus connection object in sdbus-c++: There are several factory methods to create a bus connection object in sdbus-c++:
* `createBusConnection()` - opens a connection to the session bus when in a user context, and a connection to the system bus, otherwise * `createBusConnection()` - opens a connection to the session bus when in a user context, and a connection to the system bus, otherwise
* `createBusConnection(const std::string& name)` - opens a connection with the given name to the session bus when in a user context, and a connection with the given name to the system bus, otherwise * `createBusConnection(const sdbus::ServiceName& name)` - opens a connection to the session bus when in a user context, and a connection with the given name to the system bus, otherwise, and requests the given well-known service name on the bus
* `createSystemBusConnection()` - opens a connection to the system bus * `createSystemBusConnection()` - opens a connection to the system bus
* `createSystemBusConnection(const std::string& name)` - opens a connection with the given name to the system bus * `createSystemBusConnection(const sdbus::ServiceName& name)` - opens a connection to the system bus, and requests the given well-known service name on the bus
* `createSessionBusConnection()` - opens a connection to the session bus * `createSessionBusConnection()` - opens a connection to the session bus
* `createSessionBusConnection(const std::string& name)` - opens a connection with the given name to the session bus * `createSessionBusConnection(const sdbus::ServiceName& name)` - opens a connection to the session bus, and requests the given well-known service name on the bus.
* `createSessionBusConnectionWithAddress(const std::string& address)` - opens a connection to the session bus at a custom address * `createSessionBusConnectionWithAddress(const std::string& address)` - opens a connection to the session bus at a custom address
* `createRemoteSystemBusConnection(const std::string& host)` - opens a connection to the system bus on a remote host using ssh * `createRemoteSystemBusConnection(const std::string& host)` - opens a connection to the system bus on a remote host using ssh
* `createDirectBusConnection(const std::string& address)` - opens direct D-Bus connection at a custom address (see [Using direct (peer-to-peer) D-Bus connections](#using-direct-peer-to-peer-d-bus-connections)) * `createDirectBusConnection(const std::string& address)` - opens direct D-Bus connection at a custom address (see [Using direct (peer-to-peer) D-Bus connections](#using-direct-peer-to-peer-d-bus-connections))
@ -503,13 +507,13 @@ The code written using this layer expresses in a declarative way *what* it does,
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Create D-Bus connection to the system bus and requests name on it. // Create D-Bus connection to the (either system or session) bus and requests a well-known name on it.
const char* serviceName = "org.sdbuscpp.concatenator"; sdbus::ServiceName serviceName{"org.sdbuscpp.concatenator"};
auto connection = sdbus::createSystemBusConnection(serviceName); auto connection = sdbus::createBusConnection(serviceName);
// Create concatenator D-Bus object. // Create concatenator D-Bus object.
const char* objectPath = "/org/sdbuscpp/concatenator"; sdbus::ObjectPath objectPath{"/org/sdbuscpp/concatenator"};
auto concatenator = sdbus::createObject(*connection, objectPath); auto concatenator = sdbus::createObject(*connection, std::move(objectPath));
auto concatenate = [&concatenator](const std::vector<int> numbers, const std::string& separator) auto concatenate = [&concatenator](const std::vector<int> numbers, const std::string& separator)
{ {
@ -524,17 +528,15 @@ int main(int argc, char *argv[])
} }
// Emit 'concatenated' signal // Emit 'concatenated' signal
const char* interfaceName = "org.sdbuscpp.Concatenator"; concatenator->emitSignal("concatenated").onInterface("org.sdbuscpp.Concatenator").withArguments(result);
concatenator->emitSignal("concatenated").onInterface(interfaceName).withArguments(result);
return result; return result;
}; };
// Register D-Bus methods and signals on the concatenator object, and exports the object. // Register D-Bus methods and signals on the concatenator object, and exports the object.
const char* interfaceName = "org.sdbuscpp.Concatenator";
concatenator->addVTable( sdbus::registerMethod("concatenate").implementedAs(std::move(concatenate)) concatenator->addVTable( sdbus::registerMethod("concatenate").implementedAs(std::move(concatenate))
, sdbus::registerSignal{"concatenated").withParameters<std::string>() ) , sdbus::registerSignal{"concatenated").withParameters<std::string>() )
.forInterface(interfaceName); .forInterface("org.sdbuscpp.Concatenator");
// Run the loop on the connection. // Run the loop on the connection.
connection->enterEventLoop(); connection->enterEventLoop();
@ -562,12 +564,12 @@ void onConcatenated(const std::string& concatenatedString)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Create proxy object for the concatenator object on the server side // Create proxy object for the concatenator object on the server side
const char* destinationName = "org.sdbuscpp.concatenator"; sdbus::ServiceName destination{"org.sdbuscpp.concatenator"};
const char* objectPath = "/org/sdbuscpp/concatenator"; sdbus::ObjectPath objectPath{"/org/sdbuscpp/concatenator"};
auto concatenatorProxy = sdbus::createProxy(destinationName, objectPath); auto concatenatorProxy = sdbus::createProxy(std::move(destination), std::move(objectPath));
// Let's subscribe for the 'concatenated' signals // Let's subscribe for the 'concatenated' signals
const char* interfaceName = "org.sdbuscpp.Concatenator"; sdbus::InterfaceName interfaceName{"org.sdbuscpp.Concatenator"};
concatenatorProxy->uponSignal("concatenated").onInterface(interfaceName).call([](const std::string& str){ onConcatenated(str); }); concatenatorProxy->uponSignal("concatenated").onInterface(interfaceName).call([](const std::string& str){ onConcatenated(str); });
std::vector<int> numbers = {1, 2, 3}; std::vector<int> numbers = {1, 2, 3};
@ -712,7 +714,7 @@ namespace sdbuscpp {
class Concatenator_adaptor class Concatenator_adaptor
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.Concatenator"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.Concatenator"};
protected: protected:
Concatenator_adaptor(sdbus::IObject& object) Concatenator_adaptor(sdbus::IObject& object)
@ -771,7 +773,7 @@ namespace sdbuscpp {
class Concatenator_proxy class Concatenator_proxy
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.Concatenator"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.Concatenator"};
protected: protected:
Concatenator_proxy(sdbus::IProxy& proxy) Concatenator_proxy(sdbus::IProxy& proxy)
@ -827,7 +829,7 @@ Calling `registerAdaptor()` and `unregisterAdaptor()` was not necessary in previ
class Concatenator : public sdbus::AdaptorInterfaces<org::sdbuscpp::Concatenator_adaptor /*, more adaptor classes if there are more interfaces*/> class Concatenator : public sdbus::AdaptorInterfaces<org::sdbuscpp::Concatenator_adaptor /*, more adaptor classes if there are more interfaces*/>
{ {
public: public:
Concatenator(sdbus::IConnection& connection, std::string objectPath) Concatenator(sdbus::IConnection& connection, sdbus::ObjectPath objectPath)
: AdaptorInterfaces(connection, std::move(objectPath)) : AdaptorInterfaces(connection, std::move(objectPath))
{ {
registerAdaptor(); registerAdaptor();
@ -870,13 +872,13 @@ That's it. We now have an implementation of a D-Bus object implementing `org.sdb
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Create D-Bus connection to the system bus and requests name on it. // Create D-Bus connection to (either the system or session) bus and request a well-known name on it.
const char* serviceName = "org.sdbuscpp.concatenator"; sdbus::ServiceName serviceName{"org.sdbuscpp.concatenator"};
auto connection = sdbus::createSystemBusConnection(serviceName); auto connection = sdbus::createBusConnection(serviceName);
// Create concatenator D-Bus object. // Create concatenator D-Bus object.
const char* objectPath = "/org/sdbuscpp/concatenator"; sdbus::ObjectPath objectPath{"/org/sdbuscpp/concatenator"};
Concatenator concatenator(*connection, objectPath); Concatenator concatenator(*connection, std::move(objectPath));
// Run the loop on the connection. // Run the loop on the connection.
connection->enterEventLoop(); connection->enterEventLoop();
@ -906,7 +908,7 @@ Calling `registerProxy()` and `unregisterProxy()` was not necessary in previous
class ConcatenatorProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::Concatenator_proxy /*, more proxy classes if there are more interfaces*/> class ConcatenatorProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::Concatenator_proxy /*, more proxy classes if there are more interfaces*/>
{ {
public: public:
ConcatenatorProxy(std::string destination, std::string objectPath) ConcatenatorProxy(sdbus::ServiceName destination, sdbus::ObjectPath objectPath)
: ProxyInterfaces(std::move(destination), std::move(objectPath)) : ProxyInterfaces(std::move(destination), std::move(objectPath))
{ {
registerProxy(); registerProxy();
@ -940,9 +942,9 @@ Now let's use this proxy to make remote calls and listen to signals in a real ap
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Create proxy object for the concatenator object on the server side // Create proxy object for the concatenator object on the server side
const char* destinationName = "org.sdbuscpp.concatenator"; sdbus::ServiceName destination{"org.sdbuscpp.concatenator"};
const char* objectPath = "/org/sdbuscpp/concatenator"; sdbus::ObjectPath objectPath{"/org/sdbuscpp/concatenator"};
ConcatenatorProxy concatenatorProxy(destinationName, objectPath); ConcatenatorProxy concatenatorProxy(std::move(destination), std::move(objectPath));
std::vector<int> numbers = {1, 2, 3}; std::vector<int> numbers = {1, 2, 3};
std::string separator = ":"; std::string separator = ":";
@ -1034,8 +1036,9 @@ void concatenate(sdbus::MethodCall call)
reply.send(); reply.send();
// Emit 'concatenated' signal (creating and emitting signals is thread-safe) // Emit 'concatenated' signal (creating and emitting signals is thread-safe)
const char* interfaceName = "org.sdbuscpp.Concatenator"; sdbus::InterfaceName interfaceName{"org.sdbuscpp.Concatenator"};
auto signal = g_concatenator->createSignal(interfaceName, "concatenated"); sdbus::SignalName signalName{"concatenated"};
auto signal = g_concatenator->createSignal(interfaceName, signalName);
signal << result; signal << result;
g_concatenator->emitSignal(signal); g_concatenator->emitSignal(signal);
}).detach(); }).detach();
@ -1144,7 +1147,7 @@ int main(int argc, char *argv[])
// Invoke concatenate on given interface of the object // Invoke concatenate on given interface of the object
{ {
auto method = concatenatorProxy->createMethodCall(interfaceName, "concatenate"); auto method = concatenatorProxy->createMethodCall(interfaceName, concatenate);
method << numbers << separator; method << numbers << separator;
concatenatorProxy->callMethod(method, callback); concatenatorProxy->callMethod(method, callback);
// When the reply comes, we shall get "Got concatenate result 1:2:3" on the standard output // When the reply comes, we shall get "Got concatenate result 1:2:3" on the standard output
@ -1152,7 +1155,7 @@ int main(int argc, char *argv[])
// Invoke concatenate again, this time with no numbers and we shall get an error // Invoke concatenate again, this time with no numbers and we shall get an error
{ {
auto method = concatenatorProxy->createMethodCall(interfaceName, "concatenate"); auto method = concatenatorProxy->createMethodCall(interfaceName, concatenate);
method << std::vector<int>() << separator; method << std::vector<int>() << separator;
concatenatorProxy->callMethod(method, callback); concatenatorProxy->callMethod(method, callback);
// When the reply comes, we shall get concatenation error message on the standard error output // When the reply comes, we shall get concatenation error message on the standard error output
@ -1174,7 +1177,7 @@ Another option is to use `std::future`-based overload of the `IProxy::callMethod
... ...
// Invoke concatenate on given interface of the object // Invoke concatenate on given interface of the object
{ {
auto method = concatenatorProxy->createMethodCall(interfaceName, "concatenate"); auto method = concatenatorProxy->createMethodCall(interfaceName, concatenate);
method << numbers << separator; method << numbers << separator;
auto future = concatenatorProxy->callMethod(method, sdbus::with_future); auto future = concatenatorProxy->callMethod(method, sdbus::with_future);
try try
@ -1702,10 +1705,9 @@ int main(int argc, char *argv[])
// We can now use connection objects in a familiar way, e.g. create adaptor and proxy objects on them, and exchange messages. // We can now use connection objects in a familiar way, e.g. create adaptor and proxy objects on them, and exchange messages.
// Here, using Concatenator IDL-generated bindings example from chapters above: // Here, using Concatenator IDL-generated bindings example from chapters above:
const char* objectPath = "/org/sdbuscpp/concatenator"; Concatenator concatenator(*serverConnection, sdbus::ObjectPath{"/org/sdbuscpp/concatenator"});
Concatenator concatenator(*serverConnection, objectPath); sdbus::ServiceName emptyDestination; // Destination may be empty in case of direct connections
const char* emptyDestinationName = ""; // Destination may be empty in case of direct connections ConcatenatorProxy concatenatorProxy(*clientConnection, std::move(emptyDestination), sdbus::ObjectPath{"/org/sdbuscpp/concatenator"});
ConcatenatorProxy concatenatorProxy(*clientConnection, emptyDestinationName, objectPath);
// Perform call of concatenate D-Bus method // Perform call of concatenate D-Bus method
std::vector<int> numbers = {1, 2, 3}; std::vector<int> numbers = {1, 2, 3};
@ -1750,6 +1752,13 @@ sdbus-c++ v2 is a major release that comes with a number of breaking API/ABI/beh
* Change in behavior: In *synchronous* D-Bus calls, the proxy object now keeps the connection instance blocked for the entire duration of the method call. Incoming messages like signals will be queued and processed after the call. Access to the connection from other threads is blocked. To avoid this (in case this hurts you): * Change in behavior: In *synchronous* D-Bus calls, the proxy object now keeps the connection instance blocked for the entire duration of the method call. Incoming messages like signals will be queued and processed after the call. Access to the connection from other threads is blocked. To avoid this (in case this hurts you):
* either use short-lived, light-weight proxies for such synchronous calls, * either use short-lived, light-weight proxies for such synchronous calls,
* or call the method in an asynchronous way. * or call the method in an asynchronous way.
* Strong types were introduced for safer, less error-prone and more expressive API. What previously was `auto proxy = createProxy("org.sdbuscpp.concatenator", "/org/sdbuscpp/concatenator");` is now written like `auto proxy = createProxy(ServiceName{"org.sdbuscpp.concatenator"}, ObjectPath{"/org/sdbuscpp/concatenator"});`. These types are:
* `ObjectPath` type for the object path (the type has been around already but now is also used consistently in sdbus-c++ API for object path strings)
* `InterfaceName` type for D-Bus interface names
* `BusName` (and its aliases `ServiceName` and `ConnectionName`) type for bus/service/connection names
* `MemberName` (and its aliases `MethodName`, `SignalName` and `PropertyName`) type for D-Bus method, signal and property names
* `Signature` type for the D-Bus signature (the type has been around already but now is also used consistently in sdbus-c++ API for signature strings)
* `Error::Name` type for D-Bus error names
* Signatures of callbacks `async_reply_handler`, `signal_handler`, `message_handler` and `property_set_callback` were modified to take input message objects by value instead of non-const ref to a message. The callback handler assumes ownership of the message. This API is cleaner and more self-explaining. * Signatures of callbacks `async_reply_handler`, `signal_handler`, `message_handler` and `property_set_callback` were modified to take input message objects by value instead of non-const ref to a message. The callback handler assumes ownership of the message. This API is cleaner and more self-explaining.
* The `PollData` struct has been extended with a new data member: `eventFd`. All hooks with external event loops shall be modified to poll on this `eventFd` in addition to the `fd`. * The `PollData` struct has been extended with a new data member: `eventFd`. All hooks with external event loops shall be modified to poll on this `eventFd` in addition to the `fd`.
* `PollData::timeout_usec` was renamed to `PollData::timeout` and its type has been changed to `std::chrono::microseconds`. This member now holds directly what before had to be obtained through `PollData::getAbsoluteTimeout()` call. * `PollData::timeout_usec` was renamed to `PollData::timeout` and its type has been changed to `std::chrono::microseconds`. This member now holds directly what before had to be obtained through `PollData::getAbsoluteTimeout()` call.

View File

@ -17,7 +17,7 @@ namespace ExampleManager {
class Planet1_proxy class Planet1_proxy
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.ExampleManager.Planet1"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.ExampleManager.Planet1"};
protected: protected:
Planet1_proxy(sdbus::IProxy& proxy) Planet1_proxy(sdbus::IProxy& proxy)

View File

@ -17,7 +17,7 @@ namespace ExampleManager {
class Planet1_adaptor class Planet1_adaptor
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.ExampleManager.Planet1"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.ExampleManager.Planet1"};
protected: protected:
Planet1_adaptor(sdbus::IObject& object) Planet1_adaptor(sdbus::IObject& object)

View File

@ -17,7 +17,7 @@
class PlanetProxy final : public sdbus::ProxyInterfaces< org::sdbuscpp::ExampleManager::Planet1_proxy > class PlanetProxy final : public sdbus::ProxyInterfaces< org::sdbuscpp::ExampleManager::Planet1_proxy >
{ {
public: public:
PlanetProxy(sdbus::IConnection& connection, std::string destination, std::string path) PlanetProxy(sdbus::IConnection& connection, sdbus::ServiceName destination, sdbus::ObjectPath path)
: ProxyInterfaces(connection, std::move(destination), std::move(path)) : ProxyInterfaces(connection, std::move(destination), std::move(path))
{ {
registerProxy(); registerProxy();
@ -29,10 +29,10 @@ public:
} }
}; };
class ManagerProxy final : public sdbus::ProxyInterfaces< sdbus::ObjectManager_proxy > class ManagerProxy final : public sdbus::ProxyInterfaces<sdbus::ObjectManager_proxy>
{ {
public: public:
ManagerProxy(sdbus::IConnection& connection, const std::string& destination, std::string path) ManagerProxy(sdbus::IConnection& connection, sdbus::ServiceName destination, sdbus::ObjectPath path)
: ProxyInterfaces(connection, destination, std::move(path)) : ProxyInterfaces(connection, destination, std::move(path))
, m_connection(connection) , m_connection(connection)
, m_destination(destination) , m_destination(destination)
@ -47,8 +47,7 @@ public:
void handleExistingObjects() void handleExistingObjects()
{ {
std::map<sdbus::ObjectPath, std::map<std::string, std::map<std::string, sdbus::Variant>>> objectsInterfacesAndProperties; auto objectsInterfacesAndProperties = GetManagedObjects();
objectsInterfacesAndProperties = GetManagedObjects();
for (const auto& [object, interfacesAndProperties] : objectsInterfacesAndProperties) { for (const auto& [object, interfacesAndProperties] : objectsInterfacesAndProperties) {
onInterfacesAdded(object, interfacesAndProperties); onInterfacesAdded(object, interfacesAndProperties);
} }
@ -56,7 +55,7 @@ public:
private: private:
void onInterfacesAdded( const sdbus::ObjectPath& objectPath void onInterfacesAdded( const sdbus::ObjectPath& objectPath
, const std::map<std::string, std::map<std::string, sdbus::Variant>>& interfacesAndProperties) override , const std::map<sdbus::InterfaceName, std::map<sdbus::PropertyName, sdbus::Variant>>& interfacesAndProperties) override
{ {
std::cout << objectPath << " added:\t"; std::cout << objectPath << " added:\t";
for (const auto& [interface, _] : interfacesAndProperties) { for (const auto& [interface, _] : interfacesAndProperties) {
@ -71,14 +70,14 @@ private:
} }
const auto& properties = planetInterface->second; const auto& properties = planetInterface->second;
// get a property which was passed as part of the signal. // get a property which was passed as part of the signal.
const auto& name = properties.at("Name").get<std::string>(); const auto& name = properties.at(sdbus::PropertyName{"Name"}).get<std::string>();
// or create a proxy instance to the newly added object. // or create a proxy instance to the newly added object.
PlanetProxy planet(m_connection, m_destination, objectPath); PlanetProxy planet(m_connection, m_destination, objectPath);
std::cout << name << " has a population of " << planet.GetPopulation() << ".\n" << std::endl; std::cout << name << " has a population of " << planet.GetPopulation() << ".\n" << std::endl;
} }
void onInterfacesRemoved( const sdbus::ObjectPath& objectPath void onInterfacesRemoved( const sdbus::ObjectPath& objectPath
, const std::vector<std::string>& interfaces) override , const std::vector<sdbus::InterfaceName>& interfaces) override
{ {
std::cout << objectPath << " removed:\t"; std::cout << objectPath << " removed:\t";
for (const auto& interface : interfaces) { for (const auto& interface : interfaces) {
@ -88,14 +87,16 @@ private:
} }
sdbus::IConnection& m_connection; sdbus::IConnection& m_connection;
std::string m_destination; sdbus::ServiceName m_destination;
}; };
int main() int main()
{ {
auto connection = sdbus::createSessionBusConnection(); auto connection = sdbus::createSessionBusConnection();
auto managerProxy = std::make_unique<ManagerProxy>(*connection, "org.sdbuscpp.examplemanager", "/org/sdbuscpp/examplemanager"); sdbus::ServiceName destination{"org.sdbuscpp.examplemanager"};
sdbus::ObjectPath objectPath{"/org/sdbuscpp/examplemanager"};
auto managerProxy = std::make_unique<ManagerProxy>(*connection, std::move(destination), std::move(objectPath));
try { try {
managerProxy->handleExistingObjects(); managerProxy->handleExistingObjects();
} }

View File

@ -19,10 +19,12 @@
#include <thread> #include <thread>
#include <chrono> #include <chrono>
using sdbus::ObjectPath;
class ManagerAdaptor : public sdbus::AdaptorInterfaces<sdbus::ObjectManager_adaptor> class ManagerAdaptor : public sdbus::AdaptorInterfaces<sdbus::ObjectManager_adaptor>
{ {
public: public:
ManagerAdaptor(sdbus::IConnection& connection, std::string path) ManagerAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath path)
: AdaptorInterfaces(connection, std::move(path)) : AdaptorInterfaces(connection, std::move(path))
{ {
registerAdaptor(); registerAdaptor();
@ -39,7 +41,7 @@ class PlanetAdaptor final : public sdbus::AdaptorInterfaces< org::sdbuscpp::Exam
, sdbus::Properties_adaptor > , sdbus::Properties_adaptor >
{ {
public: public:
PlanetAdaptor(sdbus::IConnection& connection, std::string path, std::string name, uint64_t population) PlanetAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath path, std::string name, uint64_t population)
: AdaptorInterfaces(connection, std::move(path)) : AdaptorInterfaces(connection, std::move(path))
, m_name(std::move(name)) , m_name(std::move(name))
, m_population(population) , m_population(population)
@ -82,18 +84,19 @@ void printCountDown(const std::string& message, int seconds)
int main() int main()
{ {
auto connection = sdbus::createSessionBusConnection(); auto connection = sdbus::createSessionBusConnection();
connection->requestName("org.sdbuscpp.examplemanager"); sdbus::ServiceName serviceName{"org.sdbuscpp.examplemanager"};
connection->requestName(serviceName);
connection->enterEventLoopAsync(); connection->enterEventLoopAsync();
auto manager = std::make_unique<ManagerAdaptor>(*connection, "/org/sdbuscpp/examplemanager"); auto manager = std::make_unique<ManagerAdaptor>(*connection, ObjectPath{"/org/sdbuscpp/examplemanager"});
while (true) while (true)
{ {
printCountDown("Creating PlanetAdaptor in ", 5); printCountDown("Creating PlanetAdaptor in ", 5);
auto earth = std::make_unique<PlanetAdaptor>(*connection, "/org/sdbuscpp/examplemanager/Planet1/Earth", "Earth", 7'874'965'825); auto earth = std::make_unique<PlanetAdaptor>(*connection, ObjectPath{"/org/sdbuscpp/examplemanager/Planet1/Earth"}, "Earth", 7'874'965'825);
printCountDown("Creating PlanetAdaptor in ", 5); printCountDown("Creating PlanetAdaptor in ", 5);
auto trantor = std::make_unique<PlanetAdaptor>(*connection, "/org/sdbuscpp/examplemanager/Planet1/Trantor", "Trantor", 40'000'000'000); auto trantor = std::make_unique<PlanetAdaptor>(*connection, ObjectPath{"/org/sdbuscpp/examplemanager/Planet1/Trantor"}, "Trantor", 40'000'000'000);
printCountDown("Creating PlanetAdaptor in ", 5); printCountDown("Creating PlanetAdaptor in ", 5);
auto laconia = std::make_unique<PlanetAdaptor>(*connection, "/org/sdbuscpp/examplemanager/Planet1/Laconia", "Laconia", 231'721); auto laconia = std::make_unique<PlanetAdaptor>(*connection, ObjectPath{"/org/sdbuscpp/examplemanager/Planet1/Laconia"}, "Laconia", 231'721);
printCountDown("Removing PlanetAdaptor in ", 5); printCountDown("Removing PlanetAdaptor in ", 5);
earth.reset(); earth.reset();
printCountDown("Removing PlanetAdaptor in ", 5); printCountDown("Removing PlanetAdaptor in ", 5);
@ -102,7 +105,7 @@ int main()
laconia.reset(); laconia.reset();
} }
connection->releaseName("org.sdbuscpp.examplemanager"); connection->releaseName(serviceName);
connection->leaveEventLoop(); connection->leaveEventLoop();
return 0; return 0;
} }

View File

@ -102,7 +102,7 @@ namespace sdbus {
* *
* For more information, consult @ref createObject(sdbus::IConnection&,std::string) * For more information, consult @ref createObject(sdbus::IConnection&,std::string)
*/ */
AdaptorInterfaces(IConnection& connection, std::string objectPath) AdaptorInterfaces(IConnection& connection, ObjectPath objectPath)
: ObjectHolder(createObject(connection, std::move(objectPath))) : ObjectHolder(createObject(connection, std::move(objectPath)))
, _Interfaces(getObject())... , _Interfaces(getObject())...
{ {

View File

@ -53,7 +53,9 @@ namespace sdbus {
{ {
public: public:
VTableAdder(IObject& object, std::vector<VTableItem> vtable); VTableAdder(IObject& object, std::vector<VTableItem> vtable);
void forInterface(InterfaceName interfaceName);
void forInterface(std::string interfaceName); void forInterface(std::string interfaceName);
[[nodiscard]] Slot forInterface(InterfaceName interfaceName, return_slot_t);
[[nodiscard]] Slot forInterface(std::string interfaceName, return_slot_t); [[nodiscard]] Slot forInterface(std::string interfaceName, return_slot_t);
private: private:
@ -64,15 +66,16 @@ namespace sdbus {
class SignalEmitter class SignalEmitter
{ {
public: public:
SignalEmitter(IObject& object, const std::string& signalName); SignalEmitter(IObject& object, const SignalName& signalName);
SignalEmitter(SignalEmitter&& other) = default; SignalEmitter(SignalEmitter&& other) = default;
~SignalEmitter() noexcept(false); ~SignalEmitter() noexcept(false);
SignalEmitter& onInterface(const InterfaceName& interfaceName);
SignalEmitter& onInterface(const std::string& interfaceName); SignalEmitter& onInterface(const std::string& interfaceName);
template <typename... _Args> void withArguments(_Args&&... args); template <typename... _Args> void withArguments(_Args&&... args);
private: private:
IObject& object_; IObject& object_;
const std::string& signalName_; const SignalName& signalName_;
Signal signal_; Signal signal_;
int exceptions_{}; // Number of active exceptions when SignalEmitter is constructed int exceptions_{}; // Number of active exceptions when SignalEmitter is constructed
}; };
@ -80,10 +83,11 @@ namespace sdbus {
class MethodInvoker class MethodInvoker
{ {
public: public:
MethodInvoker(IProxy& proxy, const std::string& methodName); MethodInvoker(IProxy& proxy, const MethodName& methodName);
MethodInvoker(MethodInvoker&& other) = default; MethodInvoker(MethodInvoker&& other) = default;
~MethodInvoker() noexcept(false); ~MethodInvoker() noexcept(false);
MethodInvoker& onInterface(const InterfaceName& interfaceName);
MethodInvoker& onInterface(const std::string& interfaceName); MethodInvoker& onInterface(const std::string& interfaceName);
MethodInvoker& withTimeout(uint64_t usec); MethodInvoker& withTimeout(uint64_t usec);
template <typename _Rep, typename _Period> template <typename _Rep, typename _Period>
@ -95,7 +99,7 @@ namespace sdbus {
private: private:
IProxy& proxy_; IProxy& proxy_;
const std::string& methodName_; const MethodName& methodName_;
uint64_t timeout_{}; uint64_t timeout_{};
MethodCall method_; MethodCall method_;
int exceptions_{}; // Number of active exceptions when MethodInvoker is constructed int exceptions_{}; // Number of active exceptions when MethodInvoker is constructed
@ -105,7 +109,8 @@ namespace sdbus {
class AsyncMethodInvoker class AsyncMethodInvoker
{ {
public: public:
AsyncMethodInvoker(IProxy& proxy, const std::string& methodName); AsyncMethodInvoker(IProxy& proxy, const MethodName& methodName);
AsyncMethodInvoker& onInterface(const InterfaceName& interfaceName);
AsyncMethodInvoker& onInterface(const std::string& interfaceName); AsyncMethodInvoker& onInterface(const std::string& interfaceName);
AsyncMethodInvoker& withTimeout(uint64_t usec); AsyncMethodInvoker& withTimeout(uint64_t usec);
template <typename _Rep, typename _Period> template <typename _Rep, typename _Period>
@ -119,7 +124,7 @@ namespace sdbus {
private: private:
IProxy& proxy_; IProxy& proxy_;
const std::string& methodName_; const MethodName& methodName_;
uint64_t timeout_{}; uint64_t timeout_{};
MethodCall method_; MethodCall method_;
}; };
@ -127,7 +132,8 @@ namespace sdbus {
class SignalSubscriber class SignalSubscriber
{ {
public: public:
SignalSubscriber(IProxy& proxy, const std::string& signalName); SignalSubscriber(IProxy& proxy, const SignalName& signalName);
SignalSubscriber& onInterface(InterfaceName interfaceName);
SignalSubscriber& onInterface(std::string interfaceName); SignalSubscriber& onInterface(std::string interfaceName);
template <typename _Function> void call(_Function&& callback); template <typename _Function> void call(_Function&& callback);
template <typename _Function> [[nodiscard]] Slot call(_Function&& callback, return_slot_t); template <typename _Function> [[nodiscard]] Slot call(_Function&& callback, return_slot_t);
@ -137,65 +143,81 @@ namespace sdbus {
private: private:
IProxy& proxy_; IProxy& proxy_;
const std::string& signalName_; const SignalName& signalName_;
std::string interfaceName_; InterfaceName interfaceName_;
}; };
class PropertyGetter class PropertyGetter
{ {
public: public:
PropertyGetter(IProxy& proxy, const std::string& propertyName); PropertyGetter(IProxy& proxy, const PropertyName& propertyName);
Variant onInterface(const InterfaceName& interfaceName);
Variant onInterface(const std::string& interfaceName); Variant onInterface(const std::string& interfaceName);
private:
static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"};
private: private:
IProxy& proxy_; IProxy& proxy_;
const std::string& propertyName_; const PropertyName& propertyName_;
}; };
class AsyncPropertyGetter class AsyncPropertyGetter
{ {
public: public:
AsyncPropertyGetter(IProxy& proxy, const std::string& propertyName); AsyncPropertyGetter(IProxy& proxy, const PropertyName& propertyName);
AsyncPropertyGetter& onInterface(const InterfaceName& interfaceName);
AsyncPropertyGetter& onInterface(const std::string& interfaceName); AsyncPropertyGetter& onInterface(const std::string& interfaceName);
template <typename _Function> PendingAsyncCall uponReplyInvoke(_Function&& callback); template <typename _Function> PendingAsyncCall uponReplyInvoke(_Function&& callback);
std::future<Variant> getResultAsFuture(); std::future<Variant> getResultAsFuture();
private:
static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"};
private: private:
IProxy& proxy_; IProxy& proxy_;
const std::string& propertyName_; const PropertyName& propertyName_;
const std::string* interfaceName_{}; const InterfaceName* interfaceName_{};
}; };
class PropertySetter class PropertySetter
{ {
public: public:
PropertySetter(IProxy& proxy, const std::string& propertyName); PropertySetter(IProxy& proxy, const PropertyName& propertyName);
PropertySetter& onInterface(const InterfaceName& interfaceName);
PropertySetter& onInterface(const std::string& interfaceName); PropertySetter& onInterface(const std::string& interfaceName);
template <typename _Value> void toValue(const _Value& value); template <typename _Value> void toValue(const _Value& value);
template <typename _Value> void toValue(const _Value& value, dont_expect_reply_t); template <typename _Value> void toValue(const _Value& value, dont_expect_reply_t);
void toValue(const Variant& value); void toValue(const Variant& value);
void toValue(const Variant& value, dont_expect_reply_t); void toValue(const Variant& value, dont_expect_reply_t);
private:
static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"};
private: private:
IProxy& proxy_; IProxy& proxy_;
const std::string& propertyName_; const PropertyName& propertyName_;
const std::string* interfaceName_{}; const InterfaceName* interfaceName_{};
}; };
class AsyncPropertySetter class AsyncPropertySetter
{ {
public: public:
AsyncPropertySetter(IProxy& proxy, const std::string& propertyName); AsyncPropertySetter(IProxy& proxy, const PropertyName& propertyName);
AsyncPropertySetter& onInterface(const InterfaceName& interfaceName);
AsyncPropertySetter& onInterface(const std::string& interfaceName); AsyncPropertySetter& onInterface(const std::string& interfaceName);
template <typename _Value> AsyncPropertySetter& toValue(_Value&& value); template <typename _Value> AsyncPropertySetter& toValue(_Value&& value);
AsyncPropertySetter& toValue(Variant value); AsyncPropertySetter& toValue(Variant value);
template <typename _Function> PendingAsyncCall uponReplyInvoke(_Function&& callback); template <typename _Function> PendingAsyncCall uponReplyInvoke(_Function&& callback);
std::future<void> getResultAsFuture(); std::future<void> getResultAsFuture();
private:
static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"};
private: private:
IProxy& proxy_; IProxy& proxy_;
const std::string& propertyName_; const PropertyName& propertyName_;
const std::string* interfaceName_{}; const InterfaceName* interfaceName_{};
Variant value_; Variant value_;
}; };
@ -203,7 +225,11 @@ namespace sdbus {
{ {
public: public:
AllPropertiesGetter(IProxy& proxy); AllPropertiesGetter(IProxy& proxy);
std::map<std::string, Variant> onInterface(const std::string& interfaceName); std::map<PropertyName, Variant> onInterface(const InterfaceName& interfaceName);
std::map<PropertyName, Variant> onInterface(const std::string& interfaceName);
private:
static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"};
private: private:
IProxy& proxy_; IProxy& proxy_;
@ -213,13 +239,17 @@ namespace sdbus {
{ {
public: public:
AsyncAllPropertiesGetter(IProxy& proxy); AsyncAllPropertiesGetter(IProxy& proxy);
AsyncAllPropertiesGetter& onInterface(const InterfaceName& interfaceName);
AsyncAllPropertiesGetter& onInterface(const std::string& interfaceName); AsyncAllPropertiesGetter& onInterface(const std::string& interfaceName);
template <typename _Function> PendingAsyncCall uponReplyInvoke(_Function&& callback); template <typename _Function> PendingAsyncCall uponReplyInvoke(_Function&& callback);
std::future<std::map<std::string, Variant>> getResultAsFuture(); std::future<std::map<PropertyName, Variant>> getResultAsFuture();
private:
static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"};
private: private:
IProxy& proxy_; IProxy& proxy_;
const std::string* interfaceName_{}; const InterfaceName* interfaceName_{};
}; };
} // namespace sdbus } // namespace sdbus

View File

@ -53,21 +53,31 @@ namespace sdbus {
{ {
} }
inline void VTableAdder::forInterface(std::string interfaceName) inline void VTableAdder::forInterface(InterfaceName interfaceName)
{ {
object_.addVTable(std::move(interfaceName), std::move(vtable_)); object_.addVTable(std::move(interfaceName), std::move(vtable_));
} }
[[nodiscard]] inline Slot VTableAdder::forInterface(std::string interfaceName, return_slot_t) inline void VTableAdder::forInterface(std::string interfaceName)
{
forInterface(InterfaceName{std::move(interfaceName)});
}
[[nodiscard]] inline Slot VTableAdder::forInterface(InterfaceName interfaceName, return_slot_t)
{ {
return object_.addVTable(std::move(interfaceName), std::move(vtable_), return_slot); return object_.addVTable(std::move(interfaceName), std::move(vtable_), return_slot);
} }
[[nodiscard]] inline Slot VTableAdder::forInterface(std::string interfaceName, return_slot_t)
{
return forInterface(InterfaceName{std::move(interfaceName)}, return_slot);
}
/*** ------------- ***/ /*** ------------- ***/
/*** SignalEmitter ***/ /*** SignalEmitter ***/
/*** ------------- ***/ /*** ------------- ***/
inline SignalEmitter::SignalEmitter(IObject& object, const std::string& signalName) inline SignalEmitter::SignalEmitter(IObject& object, const SignalName& signalName)
: object_(object) : object_(object)
, signalName_(signalName) , signalName_(signalName)
, exceptions_(std::uncaught_exceptions()) , exceptions_(std::uncaught_exceptions())
@ -92,13 +102,20 @@ namespace sdbus {
object_.emitSignal(signal_); object_.emitSignal(signal_);
} }
inline SignalEmitter& SignalEmitter::onInterface(const std::string& interfaceName) inline SignalEmitter& SignalEmitter::onInterface(const InterfaceName& interfaceName)
{ {
signal_ = object_.createSignal(interfaceName, signalName_); signal_ = object_.createSignal(interfaceName, signalName_);
return *this; return *this;
} }
inline SignalEmitter& SignalEmitter::onInterface(const std::string& interfaceName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(interfaceName) == sizeof(InterfaceName));
return onInterface(static_cast<const InterfaceName&>(interfaceName));
}
template <typename... _Args> template <typename... _Args>
inline void SignalEmitter::withArguments(_Args&&... args) inline void SignalEmitter::withArguments(_Args&&... args)
{ {
@ -111,7 +128,7 @@ namespace sdbus {
/*** MethodInvoker ***/ /*** MethodInvoker ***/
/*** ------------- ***/ /*** ------------- ***/
inline MethodInvoker::MethodInvoker(IProxy& proxy, const std::string& methodName) inline MethodInvoker::MethodInvoker(IProxy& proxy, const MethodName& methodName)
: proxy_(proxy) : proxy_(proxy)
, methodName_(methodName) , methodName_(methodName)
, exceptions_(std::uncaught_exceptions()) , exceptions_(std::uncaught_exceptions())
@ -137,13 +154,20 @@ namespace sdbus {
proxy_.callMethod(method_, timeout_); proxy_.callMethod(method_, timeout_);
} }
inline MethodInvoker& MethodInvoker::onInterface(const std::string& interfaceName) inline MethodInvoker& MethodInvoker::onInterface(const InterfaceName& interfaceName)
{ {
method_ = proxy_.createMethodCall(interfaceName, methodName_); method_ = proxy_.createMethodCall(interfaceName, methodName_);
return *this; return *this;
} }
inline MethodInvoker& MethodInvoker::onInterface(const std::string& interfaceName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(interfaceName) == sizeof(InterfaceName));
return onInterface(static_cast<const InterfaceName&>(interfaceName));
}
inline MethodInvoker& MethodInvoker::withTimeout(uint64_t usec) inline MethodInvoker& MethodInvoker::withTimeout(uint64_t usec)
{ {
timeout_ = usec; timeout_ = usec;
@ -190,19 +214,26 @@ namespace sdbus {
/*** AsyncMethodInvoker ***/ /*** AsyncMethodInvoker ***/
/*** ------------------ ***/ /*** ------------------ ***/
inline AsyncMethodInvoker::AsyncMethodInvoker(IProxy& proxy, const std::string& methodName) inline AsyncMethodInvoker::AsyncMethodInvoker(IProxy& proxy, const MethodName& methodName)
: proxy_(proxy) : proxy_(proxy)
, methodName_(methodName) , methodName_(methodName)
{ {
} }
inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(const std::string& interfaceName) inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(const InterfaceName& interfaceName)
{ {
method_ = proxy_.createMethodCall(interfaceName, methodName_); method_ = proxy_.createMethodCall(interfaceName, methodName_);
return *this; return *this;
} }
inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(const std::string& interfaceName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(interfaceName) == sizeof(InterfaceName));
return onInterface(static_cast<const InterfaceName&>(interfaceName));
}
inline AsyncMethodInvoker& AsyncMethodInvoker::withTimeout(uint64_t usec) inline AsyncMethodInvoker& AsyncMethodInvoker::withTimeout(uint64_t usec)
{ {
timeout_ = usec; timeout_ = usec;
@ -288,13 +319,18 @@ namespace sdbus {
/*** SignalSubscriber ***/ /*** SignalSubscriber ***/
/*** ---------------- ***/ /*** ---------------- ***/
inline SignalSubscriber::SignalSubscriber(IProxy& proxy, const std::string& signalName) inline SignalSubscriber::SignalSubscriber(IProxy& proxy, const SignalName& signalName)
: proxy_(proxy) : proxy_(proxy)
, signalName_(signalName) , signalName_(signalName)
{ {
} }
inline SignalSubscriber& SignalSubscriber::onInterface(std::string interfaceName) inline SignalSubscriber& SignalSubscriber::onInterface(std::string interfaceName)
{
return onInterface(InterfaceName{std::move(interfaceName)});
}
inline SignalSubscriber& SignalSubscriber::onInterface(InterfaceName interfaceName)
{ {
interfaceName_ = std::move(interfaceName); interfaceName_ = std::move(interfaceName);
@ -368,39 +404,53 @@ namespace sdbus {
/*** PropertyGetter ***/ /*** PropertyGetter ***/
/*** -------------- ***/ /*** -------------- ***/
inline PropertyGetter::PropertyGetter(IProxy& proxy, const std::string& propertyName) inline PropertyGetter::PropertyGetter(IProxy& proxy, const PropertyName& propertyName)
: proxy_(proxy) : proxy_(proxy)
, propertyName_(propertyName) , propertyName_(propertyName)
{ {
} }
inline Variant PropertyGetter::onInterface(const std::string& interfaceName) inline Variant PropertyGetter::onInterface(const InterfaceName& interfaceName)
{ {
Variant var; Variant var;
proxy_.callMethod("Get") proxy_.callMethod("Get")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(interfaceName, propertyName_) .withArguments(interfaceName, propertyName_)
.storeResultsTo(var); .storeResultsTo(var);
return var; return var;
} }
inline Variant PropertyGetter::onInterface(const std::string& interfaceName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(interfaceName) == sizeof(InterfaceName));
return onInterface(static_cast<const InterfaceName&>(interfaceName));
}
/*** ------------------- ***/ /*** ------------------- ***/
/*** AsyncPropertyGetter ***/ /*** AsyncPropertyGetter ***/
/*** ------------------- ***/ /*** ------------------- ***/
inline AsyncPropertyGetter::AsyncPropertyGetter(IProxy& proxy, const std::string& propertyName) inline AsyncPropertyGetter::AsyncPropertyGetter(IProxy& proxy, const PropertyName& propertyName)
: proxy_(proxy) : proxy_(proxy)
, propertyName_(propertyName) , propertyName_(propertyName)
{ {
} }
inline AsyncPropertyGetter& AsyncPropertyGetter::onInterface(const std::string& interfaceName) inline AsyncPropertyGetter& AsyncPropertyGetter::onInterface(const InterfaceName& interfaceName)
{ {
interfaceName_ = &interfaceName; interfaceName_ = &interfaceName;
return *this; return *this;
} }
inline AsyncPropertyGetter& AsyncPropertyGetter::onInterface(const std::string& interfaceName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(interfaceName) == sizeof(InterfaceName));
return onInterface(static_cast<const InterfaceName&>(interfaceName));
}
template <typename _Function> template <typename _Function>
PendingAsyncCall AsyncPropertyGetter::uponReplyInvoke(_Function&& callback) PendingAsyncCall AsyncPropertyGetter::uponReplyInvoke(_Function&& callback)
{ {
@ -409,7 +459,7 @@ namespace sdbus {
assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function
return proxy_.callMethodAsync("Get") return proxy_.callMethodAsync("Get")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(*interfaceName_, propertyName_) .withArguments(*interfaceName_, propertyName_)
.uponReplyInvoke(std::forward<_Function>(callback)); .uponReplyInvoke(std::forward<_Function>(callback));
} }
@ -419,7 +469,7 @@ namespace sdbus {
assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function
return proxy_.callMethodAsync("Get") return proxy_.callMethodAsync("Get")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(*interfaceName_, propertyName_) .withArguments(*interfaceName_, propertyName_)
.getResultAsFuture<Variant>(); .getResultAsFuture<Variant>();
} }
@ -428,19 +478,26 @@ namespace sdbus {
/*** PropertySetter ***/ /*** PropertySetter ***/
/*** -------------- ***/ /*** -------------- ***/
inline PropertySetter::PropertySetter(IProxy& proxy, const std::string& propertyName) inline PropertySetter::PropertySetter(IProxy& proxy, const PropertyName& propertyName)
: proxy_(proxy) : proxy_(proxy)
, propertyName_(propertyName) , propertyName_(propertyName)
{ {
} }
inline PropertySetter& PropertySetter::onInterface(const std::string& interfaceName) inline PropertySetter& PropertySetter::onInterface(const InterfaceName& interfaceName)
{ {
interfaceName_ = &interfaceName; interfaceName_ = &interfaceName;
return *this; return *this;
} }
inline PropertySetter& PropertySetter::onInterface(const std::string& interfaceName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(interfaceName) == sizeof(InterfaceName));
return onInterface(static_cast<const InterfaceName&>(interfaceName));
}
template <typename _Value> template <typename _Value>
inline void PropertySetter::toValue(const _Value& value) inline void PropertySetter::toValue(const _Value& value)
{ {
@ -458,7 +515,7 @@ namespace sdbus {
assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function
proxy_.callMethod("Set") proxy_.callMethod("Set")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(*interfaceName_, propertyName_, value); .withArguments(*interfaceName_, propertyName_, value);
} }
@ -467,7 +524,7 @@ namespace sdbus {
assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function
proxy_.callMethod("Set") proxy_.callMethod("Set")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(*interfaceName_, propertyName_, value) .withArguments(*interfaceName_, propertyName_, value)
.dontExpectReply(); .dontExpectReply();
} }
@ -476,19 +533,26 @@ namespace sdbus {
/*** AsyncPropertySetter ***/ /*** AsyncPropertySetter ***/
/*** ------------------- ***/ /*** ------------------- ***/
inline AsyncPropertySetter::AsyncPropertySetter(IProxy& proxy, const std::string& propertyName) inline AsyncPropertySetter::AsyncPropertySetter(IProxy& proxy, const PropertyName& propertyName)
: proxy_(proxy) : proxy_(proxy)
, propertyName_(propertyName) , propertyName_(propertyName)
{ {
} }
inline AsyncPropertySetter& AsyncPropertySetter::onInterface(const std::string& interfaceName) inline AsyncPropertySetter& AsyncPropertySetter::onInterface(const InterfaceName& interfaceName)
{ {
interfaceName_ = &interfaceName; interfaceName_ = &interfaceName;
return *this; return *this;
} }
inline AsyncPropertySetter& AsyncPropertySetter::onInterface(const std::string& interfaceName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(interfaceName) == sizeof(InterfaceName));
return onInterface(static_cast<const InterfaceName&>(interfaceName));
}
template <typename _Value> template <typename _Value>
inline AsyncPropertySetter& AsyncPropertySetter::toValue(_Value&& value) inline AsyncPropertySetter& AsyncPropertySetter::toValue(_Value&& value)
{ {
@ -510,7 +574,7 @@ namespace sdbus {
assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function
return proxy_.callMethodAsync("Set") return proxy_.callMethodAsync("Set")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(*interfaceName_, propertyName_, std::move(value_)) .withArguments(*interfaceName_, propertyName_, std::move(value_))
.uponReplyInvoke(std::forward<_Function>(callback)); .uponReplyInvoke(std::forward<_Function>(callback));
} }
@ -520,7 +584,7 @@ namespace sdbus {
assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function
return proxy_.callMethodAsync("Set") return proxy_.callMethodAsync("Set")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(*interfaceName_, propertyName_, std::move(value_)) .withArguments(*interfaceName_, propertyName_, std::move(value_))
.getResultAsFuture<>(); .getResultAsFuture<>();
} }
@ -534,16 +598,23 @@ namespace sdbus {
{ {
} }
inline std::map<std::string, Variant> AllPropertiesGetter::onInterface(const std::string& interfaceName) inline std::map<PropertyName, Variant> AllPropertiesGetter::onInterface(const InterfaceName& interfaceName)
{ {
std::map<std::string, Variant> props; std::map<PropertyName, Variant> props;
proxy_.callMethod("GetAll") proxy_.callMethod("GetAll")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(interfaceName) .withArguments(interfaceName)
.storeResultsTo(props); .storeResultsTo(props);
return props; return props;
} }
inline std::map<PropertyName, Variant> AllPropertiesGetter::onInterface(const std::string& interfaceName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(interfaceName) == sizeof(InterfaceName));
return onInterface(static_cast<const InterfaceName&>(interfaceName));
}
/*** ------------------------ ***/ /*** ------------------------ ***/
/*** AsyncAllPropertiesGetter ***/ /*** AsyncAllPropertiesGetter ***/
/*** ------------------------ ***/ /*** ------------------------ ***/
@ -553,35 +624,42 @@ namespace sdbus {
{ {
} }
inline AsyncAllPropertiesGetter& AsyncAllPropertiesGetter::onInterface(const std::string& interfaceName) inline AsyncAllPropertiesGetter& AsyncAllPropertiesGetter::onInterface(const InterfaceName& interfaceName)
{ {
interfaceName_ = &interfaceName; interfaceName_ = &interfaceName;
return *this; return *this;
} }
inline AsyncAllPropertiesGetter& AsyncAllPropertiesGetter::onInterface(const std::string& interfaceName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(interfaceName) == sizeof(InterfaceName));
return onInterface(static_cast<const InterfaceName&>(interfaceName));
}
template <typename _Function> template <typename _Function>
PendingAsyncCall AsyncAllPropertiesGetter::uponReplyInvoke(_Function&& callback) PendingAsyncCall AsyncAllPropertiesGetter::uponReplyInvoke(_Function&& callback)
{ {
static_assert( std::is_invocable_r_v<void, _Function, std::optional<Error>, std::map<std::string, Variant>> static_assert( std::is_invocable_r_v<void, _Function, std::optional<Error>, std::map<PropertyName, Variant>>
, "All properties get callback function must accept std::optional<Error< and a map of property names to their values" ); , "All properties get callback function must accept std::optional<Error> and a map of property names to their values" );
assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function
return proxy_.callMethodAsync("GetAll") return proxy_.callMethodAsync("GetAll")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(*interfaceName_) .withArguments(*interfaceName_)
.uponReplyInvoke(std::forward<_Function>(callback)); .uponReplyInvoke(std::forward<_Function>(callback));
} }
inline std::future<std::map<std::string, Variant>> AsyncAllPropertiesGetter::getResultAsFuture() inline std::future<std::map<PropertyName, Variant>> AsyncAllPropertiesGetter::getResultAsFuture()
{ {
assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function
return proxy_.callMethodAsync("GetAll") return proxy_.callMethodAsync("GetAll")
.onInterface("org.freedesktop.DBus.Properties") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
.withArguments(*interfaceName_) .withArguments(*interfaceName_)
.getResultAsFuture<std::map<std::string, Variant>>(); .getResultAsFuture<std::map<PropertyName, Variant>>();
} }
} // namespace sdbus } // namespace sdbus

View File

@ -43,19 +43,34 @@ namespace sdbus {
: public std::runtime_error : public std::runtime_error
{ {
public: public:
explicit Error(const std::string& name, const char* message = nullptr) // Strong type representing the D-Bus error name
: Error(name, std::string(message ? message : "")) class Name : public std::string
{
public:
Name() = default;
explicit Name(std::string value)
: std::string(std::move(value))
{}
explicit Name(const char* value)
: std::string(value)
{}
using std::string::operator=;
};
explicit Error(Name name, const char* message = nullptr)
: Error(std::move(name), std::string(message ? message : ""))
{ {
} }
Error(const std::string& name, const std::string& message) Error(Name name, std::string message)
: std::runtime_error("[" + name + "] " + message) : std::runtime_error("[" + name + "] " + message)
, name_(name) , name_(std::move(name))
, message_(message) , message_(std::move(message))
{ {
} }
[[nodiscard]] const std::string& getName() const [[nodiscard]] const Name& getName() const
{ {
return name_; return name_;
} }
@ -71,13 +86,13 @@ namespace sdbus {
} }
private: private:
std::string name_; Name name_;
std::string message_; std::string message_;
}; };
sdbus::Error createError(int errNo, const std::string& customMsg); Error createError(int errNo, std::string customMsg);
inline const char* SDBUSCPP_ERROR_NAME = "org.sdbuscpp.Error"; inline const Error::Name SDBUSCPP_ERROR_NAME{"org.sdbuscpp.Error"};
} }
#define SDBUS_THROW_ERROR(_MSG, _ERRNO) \ #define SDBUS_THROW_ERROR(_MSG, _ERRNO) \

View File

@ -35,10 +35,14 @@
#include <optional> #include <optional>
#include <string> #include <string>
// Forward declarations
struct sd_bus; struct sd_bus;
struct sd_event; struct sd_event;
namespace sdbus { namespace sdbus {
class Message; class Message;
class ObjectPath;
class BusName;
using ServiceName = BusName;
} }
namespace sdbus { namespace sdbus {
@ -61,29 +65,29 @@ namespace sdbus {
virtual ~IConnection() = default; virtual ~IConnection() = default;
/*! /*!
* @brief Requests D-Bus name on the connection * @brief Requests a well-known D-Bus service name on a bus
* *
* @param[in] name Name to request * @param[in] name Name to request
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
virtual void requestName(const std::string& name) = 0; virtual void requestName(const ServiceName& name) = 0;
/*! /*!
* @brief Releases D-Bus name on the connection * @brief Releases an acquired well-known D-Bus service name on a bus
* *
* @param[in] name Name to release * @param[in] name Name to release
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
virtual void releaseName(const std::string& name) = 0; virtual void releaseName(const ServiceName& name) = 0;
/*! /*!
* @brief Retrieves the unique name of a connection. E.g. ":1.xx" * @brief Retrieves the unique name of a connection. E.g. ":1.xx"
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] virtual std::string getUniqueName() const = 0; [[nodiscard]] virtual BusName getUniqueName() const = 0;
/*! /*!
* @brief Enters I/O event loop on this bus connection * @brief Enters I/O event loop on this bus connection
@ -257,7 +261,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
virtual void addObjectManager(const std::string& objectPath, floating_slot_t) = 0; virtual void addObjectManager(const ObjectPath& objectPath, floating_slot_t) = 0;
/*! /*!
* @brief Installs a match rule for messages received on this bus connection * @brief Installs a match rule for messages received on this bus connection
@ -412,7 +416,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createBusConnection(const std::string& name); [[nodiscard]] std::unique_ptr<sdbus::IConnection> createBusConnection(const ServiceName& name);
/*! /*!
* @brief Creates/opens D-Bus system bus connection * @brief Creates/opens D-Bus system bus connection
@ -431,7 +435,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const std::string& name); [[nodiscard]] std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const ServiceName& name);
/*! /*!
* @brief Creates/opens D-Bus session bus connection * @brief Creates/opens D-Bus session bus connection
@ -450,7 +454,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const std::string& name); [[nodiscard]] std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const ServiceName& name);
/*! /*!
* @brief Creates/opens D-Bus session bus connection at a custom address * @brief Creates/opens D-Bus session bus connection at a custom address

View File

@ -41,6 +41,7 @@
namespace sdbus { namespace sdbus {
class Signal; class Signal;
class IConnection; class IConnection;
class ObjectPath;
} }
namespace sdbus { namespace sdbus {
@ -89,7 +90,7 @@ namespace sdbus {
*/ */
template < typename... VTableItems template < typename... VTableItems
, typename = std::enable_if_t<(is_one_of_variants_types<VTableItem, std::decay_t<VTableItems>> && ...)> > , typename = std::enable_if_t<(is_one_of_variants_types<VTableItem, std::decay_t<VTableItems>> && ...)> >
void addVTable(std::string interfaceName, VTableItems&&... items); void addVTable(InterfaceName interfaceName, VTableItems&&... items);
/*! /*!
* @brief Adds a declaration of methods, properties and signals of the object at a given interface * @brief Adds a declaration of methods, properties and signals of the object at a given interface
@ -114,7 +115,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
virtual void addVTable(std::string interfaceName, std::vector<VTableItem> vtable) = 0; virtual void addVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable) = 0;
/*! /*!
* @brief Adds a declaration of methods, properties and signals of the object at a given interface * @brief Adds a declaration of methods, properties and signals of the object at a given interface
@ -141,7 +142,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] virtual Slot addVTable(std::string interfaceName, std::vector<VTableItem> vtable, return_slot_t) = 0; [[nodiscard]] virtual Slot addVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable, return_slot_t) = 0;
/*! /*!
* @brief A little more convenient overload of addVTable() above * @brief A little more convenient overload of addVTable() above
@ -188,7 +189,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] virtual Signal createSignal(const std::string& interfaceName, const std::string& signalName) = 0; [[nodiscard]] virtual Signal createSignal(const InterfaceName& interfaceName, const SignalName& signalName) = 0;
/*! /*!
* @brief Emits signal for this object path * @brief Emits signal for this object path
@ -201,6 +202,28 @@ namespace sdbus {
*/ */
virtual void emitSignal(const sdbus::Signal& message) = 0; virtual void emitSignal(const sdbus::Signal& message) = 0;
/*!
* @brief Emits signal on D-Bus
*
* @param[in] signalName Name of the signal
* @return A helper object for convenient emission of signals
*
* This is a high-level, convenience way of emitting D-Bus signals that abstracts
* from the D-Bus message concept. Signal arguments are automatically serialized
* in a message and D-Bus signatures automatically deduced from the provided native arguments.
*
* Example of use:
* @code
* int arg1 = ...;
* double arg2 = ...;
* SignalName fooSignal{"fooSignal"};
* object_.emitSignal(fooSignal).onInterface("com.kistler.foo").withArguments(arg1, arg2);
* @endcode
*
* @throws sdbus::Error in case of failure
*/
[[nodiscard]] SignalEmitter emitSignal(const SignalName& signalName);
/*! /*!
* @brief Emits signal on D-Bus * @brief Emits signal on D-Bus
* *
@ -230,7 +253,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
virtual void emitPropertiesChangedSignal(const std::string& interfaceName, const std::vector<std::string>& propNames) = 0; virtual void emitPropertiesChangedSignal(const InterfaceName& interfaceName, const std::vector<PropertyName>& propNames) = 0;
/*! /*!
* @brief Emits PropertyChanged signal for all properties on a given interface of this object path * @brief Emits PropertyChanged signal for all properties on a given interface of this object path
@ -239,7 +262,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
virtual void emitPropertiesChangedSignal(const std::string& interfaceName) = 0; virtual void emitPropertiesChangedSignal(const InterfaceName& interfaceName) = 0;
/*! /*!
* @brief Emits InterfacesAdded signal on this object path * @brief Emits InterfacesAdded signal on this object path
@ -264,7 +287,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
virtual void emitInterfacesAddedSignal(const std::vector<std::string>& interfaces) = 0; virtual void emitInterfacesAddedSignal(const std::vector<InterfaceName>& interfaces) = 0;
/*! /*!
* @brief Emits InterfacesRemoved signal on this object path * @brief Emits InterfacesRemoved signal on this object path
@ -286,7 +309,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
virtual void emitInterfacesRemovedSignal(const std::vector<std::string>& interfaces) = 0; virtual void emitInterfacesRemovedSignal(const std::vector<InterfaceName>& interfaces) = 0;
/*! /*!
* @brief Adds an ObjectManager interface at the path of this D-Bus object * @brief Adds an ObjectManager interface at the path of this D-Bus object
@ -322,7 +345,7 @@ namespace sdbus {
/*! /*!
* @brief Returns object path of the underlying DBus object * @brief Returns object path of the underlying DBus object
*/ */
[[nodiscard]] virtual const std::string& getObjectPath() const = 0; [[nodiscard]] virtual const ObjectPath& getObjectPath() const = 0;
/*! /*!
* @brief Provides access to the currently processed D-Bus message * @brief Provides access to the currently processed D-Bus message
@ -342,13 +365,20 @@ namespace sdbus {
// Out-of-line member definitions // Out-of-line member definitions
inline SignalEmitter IObject::emitSignal(const std::string& signalName) inline SignalEmitter IObject::emitSignal(const SignalName& signalName)
{ {
return SignalEmitter(*this, signalName); return SignalEmitter(*this, signalName);
} }
inline SignalEmitter IObject::emitSignal(const std::string& signalName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(signalName) == sizeof(SignalName));
return emitSignal(static_cast<const SignalName&>(signalName));
}
template <typename... VTableItems, typename> template <typename... VTableItems, typename>
void IObject::addVTable(std::string interfaceName, VTableItems&&... items) void IObject::addVTable(InterfaceName interfaceName, VTableItems&&... items)
{ {
addVTable(std::move(interfaceName), {std::forward<VTableItems>(items)...}); addVTable(std::move(interfaceName), {std::forward<VTableItems>(items)...});
} }
@ -382,7 +412,7 @@ namespace sdbus {
* auto proxy = sdbus::createObject(connection, "/com/kistler/foo"); * auto proxy = sdbus::createObject(connection, "/com/kistler/foo");
* @endcode * @endcode
*/ */
[[nodiscard]] std::unique_ptr<sdbus::IObject> createObject(sdbus::IConnection& connection, std::string objectPath); [[nodiscard]] std::unique_ptr<sdbus::IObject> createObject(sdbus::IConnection& connection, ObjectPath objectPath);
} }

View File

@ -41,6 +41,7 @@ namespace sdbus {
class MethodCall; class MethodCall;
class MethodReply; class MethodReply;
class IConnection; class IConnection;
class ObjectPath;
class PendingAsyncCall; class PendingAsyncCall;
namespace internal { namespace internal {
class Proxy; class Proxy;
@ -81,7 +82,7 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] virtual MethodCall createMethodCall(const std::string& interfaceName, const std::string& methodName) = 0; [[nodiscard]] virtual MethodCall createMethodCall(const InterfaceName& interfaceName, const MethodName& methodName) = 0;
/*! /*!
* @brief Calls method on the remote D-Bus object * @brief Calls method on the remote D-Bus object
@ -211,11 +212,17 @@ namespace sdbus {
* Example of use: * Example of use:
* @code * @code
* int result, a = ..., b = ...; * int result, a = ..., b = ...;
* object_.callMethod("multiply").onInterface(INTERFACE_NAME).withArguments(a, b).storeResultsTo(result); * MethodName multiply{"multiply"};
* object_.callMethod(multiply).onInterface(INTERFACE_NAME).withArguments(a, b).storeResultsTo(result);
* @endcode * @endcode
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] MethodInvoker callMethod(const MethodName& methodName);
/*!
* @copydoc IProxy::callMethod(const MethodName&)
*/
[[nodiscard]] MethodInvoker callMethod(const std::string& methodName); [[nodiscard]] MethodInvoker callMethod(const std::string& methodName);
/*! /*!
@ -232,7 +239,8 @@ namespace sdbus {
* Example of use: * Example of use:
* @code * @code
* int a = ..., b = ...; * int a = ..., b = ...;
* object_.callMethodAsync("multiply").onInterface(INTERFACE_NAME).withArguments(a, b).uponReplyInvoke([](int result) * MethodName multiply{"multiply"};
* object_.callMethodAsync(multiply).onInterface(INTERFACE_NAME).withArguments(a, b).uponReplyInvoke([](int result)
* { * {
* std::cout << "Got result of multiplying " << a << " and " << b << ": " << result << std::endl; * std::cout << "Got result of multiplying " << a << " and " << b << ": " << result << std::endl;
* }); * });
@ -240,6 +248,11 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] AsyncMethodInvoker callMethodAsync(const MethodName& methodName);
/*!
* @copydoc IProxy::callMethodAsync(const MethodName&)
*/
[[nodiscard]] AsyncMethodInvoker callMethodAsync(const std::string& methodName); [[nodiscard]] AsyncMethodInvoker callMethodAsync(const std::string& methodName);
/*! /*!
@ -254,8 +267,8 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
virtual void registerSignalHandler( const std::string& interfaceName virtual void registerSignalHandler( const InterfaceName& interfaceName
, const std::string& signalName , const SignalName& signalName
, signal_handler signalHandler ) = 0; , signal_handler signalHandler ) = 0;
/*! /*!
@ -273,8 +286,8 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] virtual Slot registerSignalHandler( const std::string& interfaceName [[nodiscard]] virtual Slot registerSignalHandler( const InterfaceName& interfaceName
, const std::string& signalName , const SignalName& signalName
, signal_handler signalHandler , signal_handler signalHandler
, return_slot_t ) = 0; , return_slot_t ) = 0;
@ -294,11 +307,19 @@ namespace sdbus {
* *
* Example of use: * Example of use:
* @code * @code
* object_.uponSignal("fooSignal").onInterface("com.kistler.foo").call([this](int arg1, double arg2){ this->onFooSignal(arg1, arg2); }); * object_.uponSignal("stateChanged").onInterface("com.kistler.foo").call([this](int arg1, double arg2){ this->onStateChanged(arg1, arg2); });
* sdbus::InterfaceName foo{"com.kistler.foo"};
* sdbus::SignalName levelChanged{"levelChanged"};
* object_.uponSignal(levelChanged).onInterface(foo).call([this](uint16_t level){ this->onLevelChanged(level); });
* @endcode * @endcode
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] SignalSubscriber uponSignal(const SignalName& signalName);
/*!
* @copydoc IProxy::uponSignal(const SignalName&)
*/
[[nodiscard]] SignalSubscriber uponSignal(const std::string& signalName); [[nodiscard]] SignalSubscriber uponSignal(const std::string& signalName);
/*! /*!
@ -325,10 +346,18 @@ namespace sdbus {
* Example of use: * Example of use:
* @code * @code
* int state = object.getProperty("state").onInterface("com.kistler.foo"); * int state = object.getProperty("state").onInterface("com.kistler.foo");
* sdbus::InterfaceName foo{"com.kistler.foo"};
* sdbus::PropertyName level{"level"};
* int level = object.getProperty(level).onInterface(foo);
* @endcode * @endcode
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] PropertyGetter getProperty(const PropertyName& propertyName);
/*!
* @copydoc IProxy::getProperty(const PropertyName&)
*/
[[nodiscard]] PropertyGetter getProperty(const std::string& propertyName); [[nodiscard]] PropertyGetter getProperty(const std::string& propertyName);
/*! /*!
@ -349,6 +378,11 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] AsyncPropertyGetter getPropertyAsync(const PropertyName& propertyName);
/*!
* @copydoc IProxy::getPropertyAsync(const PropertyName&)
*/
[[nodiscard]] AsyncPropertyGetter getPropertyAsync(const std::string& propertyName); [[nodiscard]] AsyncPropertyGetter getPropertyAsync(const std::string& propertyName);
/*! /*!
@ -371,6 +405,11 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] PropertySetter setProperty(const PropertyName& propertyName);
/*!
* @copydoc IProxy::setProperty(const PropertyName&)
*/
[[nodiscard]] PropertySetter setProperty(const std::string& propertyName); [[nodiscard]] PropertySetter setProperty(const std::string& propertyName);
/*! /*!
@ -391,6 +430,11 @@ namespace sdbus {
* *
* @throws sdbus::Error in case of failure * @throws sdbus::Error in case of failure
*/ */
[[nodiscard]] AsyncPropertySetter setPropertyAsync(const PropertyName& propertyName);
/*!
* @copydoc IProxy::setPropertyAsync(const PropertyName&)
*/
[[nodiscard]] AsyncPropertySetter setPropertyAsync(const std::string& propertyName); [[nodiscard]] AsyncPropertySetter setPropertyAsync(const std::string& propertyName);
/*! /*!
@ -420,7 +464,7 @@ namespace sdbus {
* *
* Example of use: * Example of use:
* @code * @code
* auto callback = [](std::optional<sdbus::Error> err, const std::map<std::string, Variant>>& properties){ ... }; * auto callback = [](std::optional<sdbus::Error> err, const std::map<PropertyName, Variant>>& properties){ ... };
* auto props = object.getAllPropertiesAsync().onInterface("com.kistler.foo").uponReplyInvoke(std::move(callback)); * auto props = object.getAllPropertiesAsync().onInterface("com.kistler.foo").uponReplyInvoke(std::move(callback));
* @endcode * @endcode
* *
@ -438,7 +482,7 @@ namespace sdbus {
/*! /*!
* @brief Returns object path of the underlying DBus object * @brief Returns object path of the underlying DBus object
*/ */
[[nodiscard]] virtual const std::string& getObjectPath() const = 0; [[nodiscard]] virtual const ObjectPath& getObjectPath() const = 0;
/*! /*!
* @brief Provides access to the currently processed D-Bus message * @brief Provides access to the currently processed D-Bus message
@ -525,41 +569,90 @@ namespace sdbus {
return callMethodAsync(message, microsecs.count(), with_future); return callMethodAsync(message, microsecs.count(), with_future);
} }
inline MethodInvoker IProxy::callMethod(const std::string& methodName) inline MethodInvoker IProxy::callMethod(const MethodName& methodName)
{ {
return MethodInvoker(*this, methodName); return MethodInvoker(*this, methodName);
} }
inline AsyncMethodInvoker IProxy::callMethodAsync(const std::string& methodName) inline MethodInvoker IProxy::callMethod(const std::string& methodName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(methodName) == sizeof(MethodName));
return callMethod(static_cast<const MethodName&>(methodName));
}
inline AsyncMethodInvoker IProxy::callMethodAsync(const MethodName& methodName)
{ {
return AsyncMethodInvoker(*this, methodName); return AsyncMethodInvoker(*this, methodName);
} }
inline SignalSubscriber IProxy::uponSignal(const std::string& signalName) inline AsyncMethodInvoker IProxy::callMethodAsync(const std::string& methodName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(methodName) == sizeof(MethodName));
return callMethodAsync(static_cast<const MethodName&>(methodName));
}
inline SignalSubscriber IProxy::uponSignal(const SignalName& signalName)
{ {
return SignalSubscriber(*this, signalName); return SignalSubscriber(*this, signalName);
} }
inline PropertyGetter IProxy::getProperty(const std::string& propertyName) inline SignalSubscriber IProxy::uponSignal(const std::string& signalName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(signalName) == sizeof(SignalName));
return uponSignal(static_cast<const SignalName&>(signalName));
}
inline PropertyGetter IProxy::getProperty(const PropertyName& propertyName)
{ {
return PropertyGetter(*this, propertyName); return PropertyGetter(*this, propertyName);
} }
inline AsyncPropertyGetter IProxy::getPropertyAsync(const std::string& propertyName) inline PropertyGetter IProxy::getProperty(const std::string& propertyName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(propertyName) == sizeof(PropertyName));
return getProperty(static_cast<const PropertyName&>(propertyName));
}
inline AsyncPropertyGetter IProxy::getPropertyAsync(const PropertyName& propertyName)
{ {
return AsyncPropertyGetter(*this, propertyName); return AsyncPropertyGetter(*this, propertyName);
} }
inline PropertySetter IProxy::setProperty(const std::string& propertyName) inline AsyncPropertyGetter IProxy::getPropertyAsync(const std::string& propertyName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(propertyName) == sizeof(PropertyName));
return getPropertyAsync(static_cast<const PropertyName&>(propertyName));
}
inline PropertySetter IProxy::setProperty(const PropertyName& propertyName)
{ {
return PropertySetter(*this, propertyName); return PropertySetter(*this, propertyName);
} }
inline AsyncPropertySetter IProxy::setPropertyAsync(const std::string& propertyName) inline PropertySetter IProxy::setProperty(const std::string& propertyName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(propertyName) == sizeof(PropertyName));
return setProperty(static_cast<const PropertyName&>(propertyName));
}
inline AsyncPropertySetter IProxy::setPropertyAsync(const PropertyName& propertyName)
{ {
return AsyncPropertySetter(*this, propertyName); return AsyncPropertySetter(*this, propertyName);
} }
inline AsyncPropertySetter IProxy::setPropertyAsync(const std::string& propertyName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(propertyName) == sizeof(PropertyName));
return setPropertyAsync(static_cast<const PropertyName&>(propertyName));
}
inline AllPropertiesGetter IProxy::getAllProperties() inline AllPropertiesGetter IProxy::getAllProperties()
{ {
return AllPropertiesGetter(*this); return AllPropertiesGetter(*this);
@ -593,8 +686,8 @@ namespace sdbus {
* @endcode * @endcode
*/ */
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( sdbus::IConnection& connection [[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( sdbus::IConnection& connection
, std::string destination , ServiceName destination
, std::string objectPath ); , ObjectPath objectPath );
/*! /*!
* @brief Creates a proxy object for a specific remote D-Bus object * @brief Creates a proxy object for a specific remote D-Bus object
@ -619,8 +712,8 @@ namespace sdbus {
* @endcode * @endcode
*/ */
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<sdbus::IConnection>&& connection [[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<sdbus::IConnection>&& connection
, std::string destination , ServiceName destination
, std::string objectPath ); , ObjectPath objectPath );
/*! /*!
* @brief Creates a proxy object for a specific remote D-Bus object * @brief Creates a proxy object for a specific remote D-Bus object
@ -646,8 +739,8 @@ namespace sdbus {
* @endcode * @endcode
*/ */
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<sdbus::IConnection>&& connection [[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<sdbus::IConnection>&& connection
, std::string destination , ServiceName destination
, std::string objectPath , ObjectPath objectPath
, dont_run_event_loop_thread_t ); , dont_run_event_loop_thread_t );
/*! /*!
@ -667,8 +760,8 @@ namespace sdbus {
* auto proxy = sdbus::createProxy("com.kistler.foo", "/com/kistler/foo"); * auto proxy = sdbus::createProxy("com.kistler.foo", "/com/kistler/foo");
* @endcode * @endcode
*/ */
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( std::string destination [[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( ServiceName destination
, std::string objectPath ); , ObjectPath objectPath );
/*! /*!
* @brief Creates a proxy object for a specific remote D-Bus object * @brief Creates a proxy object for a specific remote D-Bus object
@ -688,8 +781,8 @@ namespace sdbus {
* auto proxy = sdbus::createProxy("com.kistler.foo", "/com/kistler/foo", sdbus::dont_run_event_loop_thread ); * auto proxy = sdbus::createProxy("com.kistler.foo", "/com/kistler/foo", sdbus::dont_run_event_loop_thread );
* @endcode * @endcode
*/ */
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( std::string destination [[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( ServiceName destination
, std::string objectPath , ObjectPath objectPath
, dont_run_event_loop_thread_t ); , dont_run_event_loop_thread_t );
} }

View File

@ -52,10 +52,14 @@
namespace sdbus { namespace sdbus {
class Variant; class Variant;
class ObjectPath; class ObjectPath;
class InterfaceName;
class MemberName;
class Signature; class Signature;
template <typename... _ValueTypes> class Struct; template <typename... _ValueTypes> class Struct;
class UnixFd; class UnixFd;
class MethodReply; class MethodReply;
class BusName;
using ConnectionName = BusName;
namespace internal { namespace internal {
class ISdBus; class ISdBus;
} }
@ -181,11 +185,11 @@ namespace sdbus {
explicit operator bool() const; explicit operator bool() const;
void clearFlags(); void clearFlags();
std::string getInterfaceName() const; InterfaceName getInterfaceName() const;
std::string getMemberName() const; MemberName getMemberName() const;
std::string getSender() const; ConnectionName getSender() const;
std::string getPath() const; ObjectPath getPath() const;
std::string getDestination() const; ConnectionName getDestination() const;
void peekType(std::string& type, std::string& contents) const; void peekType(std::string& type, std::string& contents) const;
bool isValid() const; bool isValid() const;
bool isEmpty() const; bool isEmpty() const;
@ -281,7 +285,7 @@ namespace sdbus {
public: public:
Signal() = default; Signal() = default;
void setDestination(const std::string& destination); void setDestination(const ConnectionName& destination);
void send() const; void send() const;
}; };

View File

@ -104,7 +104,7 @@ namespace sdbus {
* This constructor overload creates a proxy that manages its own D-Bus connection(s). * This constructor overload creates a proxy that manages its own D-Bus connection(s).
* For more information on its behavior, consult @ref createProxy(std::string,std::string) * For more information on its behavior, consult @ref createProxy(std::string,std::string)
*/ */
ProxyInterfaces(std::string destination, std::string objectPath) ProxyInterfaces(ServiceName destination, ObjectPath objectPath)
: ProxyObjectHolder(createProxy(std::move(destination), std::move(objectPath))) : ProxyObjectHolder(createProxy(std::move(destination), std::move(objectPath)))
, _Interfaces(getProxy())... , _Interfaces(getProxy())...
{ {
@ -119,7 +119,7 @@ namespace sdbus {
* This constructor overload creates a proxy that manages its own D-Bus connection(s). * This constructor overload creates a proxy that manages its own D-Bus connection(s).
* For more information on its behavior, consult @ref createProxy(std::string,std::string,sdbus::dont_run_event_loop_thread_t) * For more information on its behavior, consult @ref createProxy(std::string,std::string,sdbus::dont_run_event_loop_thread_t)
*/ */
ProxyInterfaces(std::string destination, std::string objectPath, dont_run_event_loop_thread_t) ProxyInterfaces(ServiceName destination, ObjectPath objectPath, dont_run_event_loop_thread_t)
: ProxyObjectHolder(createProxy(std::move(destination), std::move(objectPath), dont_run_event_loop_thread)) : ProxyObjectHolder(createProxy(std::move(destination), std::move(objectPath), dont_run_event_loop_thread))
, _Interfaces(getProxy())... , _Interfaces(getProxy())...
{ {
@ -135,7 +135,7 @@ namespace sdbus {
* The proxy created this way just references a D-Bus connection owned and managed by the user. * The proxy created this way just references a D-Bus connection owned and managed by the user.
* For more information on its behavior, consult @ref createProxy(IConnection&,std::string,std::string) * For more information on its behavior, consult @ref createProxy(IConnection&,std::string,std::string)
*/ */
ProxyInterfaces(IConnection& connection, std::string destination, std::string objectPath) ProxyInterfaces(IConnection& connection, ServiceName destination, ObjectPath objectPath)
: ProxyObjectHolder(createProxy(connection, std::move(destination), std::move(objectPath))) : ProxyObjectHolder(createProxy(connection, std::move(destination), std::move(objectPath)))
, _Interfaces(getProxy())... , _Interfaces(getProxy())...
{ {
@ -151,7 +151,7 @@ namespace sdbus {
* The proxy created this way becomes an owner of the connection. * The proxy created this way becomes an owner of the connection.
* For more information on its behavior, consult @ref createProxy(std::unique_ptr<sdbus::IConnection>&&,std::string,std::string) * For more information on its behavior, consult @ref createProxy(std::unique_ptr<sdbus::IConnection>&&,std::string,std::string)
*/ */
ProxyInterfaces(std::unique_ptr<sdbus::IConnection>&& connection, std::string destination, std::string objectPath) ProxyInterfaces(std::unique_ptr<sdbus::IConnection>&& connection, ServiceName destination, ObjectPath objectPath)
: ProxyObjectHolder(createProxy(std::move(connection), std::move(destination), std::move(objectPath))) : ProxyObjectHolder(createProxy(std::move(connection), std::move(destination), std::move(objectPath)))
, _Interfaces(getProxy())... , _Interfaces(getProxy())...
{ {
@ -167,7 +167,7 @@ namespace sdbus {
* The proxy created this way becomes an owner of the connection. * The proxy created this way becomes an owner of the connection.
* For more information on its behavior, consult @ref createProxy(std::unique_ptr<sdbus::IConnection>&&,std::string,std::string,sdbus::dont_run_event_loop_thread_t) * For more information on its behavior, consult @ref createProxy(std::unique_ptr<sdbus::IConnection>&&,std::string,std::string,sdbus::dont_run_event_loop_thread_t)
*/ */
ProxyInterfaces(std::unique_ptr<sdbus::IConnection>&& connection, std::string destination, std::string objectPath, dont_run_event_loop_thread_t) ProxyInterfaces(std::unique_ptr<sdbus::IConnection>&& connection, ServiceName destination, ObjectPath objectPath, dont_run_event_loop_thread_t)
: ProxyObjectHolder(createProxy(std::move(connection), std::move(destination), std::move(objectPath), dont_run_event_loop_thread)) : ProxyObjectHolder(createProxy(std::move(connection), std::move(destination), std::move(objectPath), dont_run_event_loop_thread))
, _Interfaces(getProxy())... , _Interfaces(getProxy())...
{ {

View File

@ -39,7 +39,7 @@ namespace sdbus {
// Proxy for peer // Proxy for peer
class Peer_proxy class Peer_proxy
{ {
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.Peer"; static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.Peer"};
protected: protected:
Peer_proxy(sdbus::IProxy& proxy) Peer_proxy(sdbus::IProxy& proxy)
@ -78,7 +78,7 @@ namespace sdbus {
// Proxy for introspection // Proxy for introspection
class Introspectable_proxy class Introspectable_proxy
{ {
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.Introspectable"; static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.Introspectable"};
protected: protected:
Introspectable_proxy(sdbus::IProxy& proxy) Introspectable_proxy(sdbus::IProxy& proxy)
@ -112,7 +112,7 @@ namespace sdbus {
// Proxy for properties // Proxy for properties
class Properties_proxy class Properties_proxy
{ {
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.Properties"; static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.Properties"};
protected: protected:
Properties_proxy(sdbus::IProxy& proxy) Properties_proxy(sdbus::IProxy& proxy)
@ -132,68 +132,106 @@ namespace sdbus {
proxy_ proxy_
->uponSignal("PropertiesChanged") ->uponSignal("PropertiesChanged")
.onInterface(INTERFACE_NAME) .onInterface(INTERFACE_NAME)
.call([this]( const std::string& interfaceName .call([this]( const InterfaceName& interfaceName
, const std::map<std::string, sdbus::Variant>& changedProperties , const std::map<PropertyName, sdbus::Variant>& changedProperties
, const std::vector<std::string>& invalidatedProperties ) , const std::vector<PropertyName>& invalidatedProperties )
{ {
this->onPropertiesChanged(interfaceName, changedProperties, invalidatedProperties); this->onPropertiesChanged(interfaceName, changedProperties, invalidatedProperties);
}); });
} }
virtual void onPropertiesChanged( const std::string& interfaceName virtual void onPropertiesChanged( const InterfaceName& interfaceName
, const std::map<std::string, sdbus::Variant>& changedProperties , const std::map<PropertyName, sdbus::Variant>& changedProperties
, const std::vector<std::string>& invalidatedProperties ) = 0; , const std::vector<PropertyName>& invalidatedProperties ) = 0;
public: public:
sdbus::Variant Get(const std::string& interfaceName, const std::string& propertyName) sdbus::Variant Get(const InterfaceName& interfaceName, const PropertyName& propertyName)
{
return proxy_->getProperty(propertyName).onInterface(interfaceName);
}
// TODO: Refactor from std::string to std::string_view before release/v2.0 !!!
sdbus::Variant Get(const InterfaceName& interfaceName, const std::string& propertyName)
{ {
return proxy_->getProperty(propertyName).onInterface(interfaceName); return proxy_->getProperty(propertyName).onInterface(interfaceName);
} }
template <typename _Function> template <typename _Function>
PendingAsyncCall GetAsync(const std::string& interfaceName, const std::string& propertyName, _Function&& callback) PendingAsyncCall GetAsync(const InterfaceName& interfaceName, const PropertyName& propertyName, _Function&& callback)
{ {
return proxy_->getPropertyAsync(propertyName).onInterface(interfaceName).uponReplyInvoke(std::forward<_Function>(callback)); return proxy_->getPropertyAsync(propertyName).onInterface(interfaceName).uponReplyInvoke(std::forward<_Function>(callback));
} }
std::future<sdbus::Variant> GetAsync(const std::string& interfaceName, const std::string& propertyName, with_future_t) template <typename _Function>
PendingAsyncCall GetAsync(const InterfaceName& interfaceName, const std::string& propertyName, _Function&& callback)
{
return proxy_->getPropertyAsync(propertyName).onInterface(interfaceName).uponReplyInvoke(std::forward<_Function>(callback));
}
std::future<sdbus::Variant> GetAsync(const InterfaceName& interfaceName, const PropertyName& propertyName, with_future_t)
{ {
return proxy_->getPropertyAsync(propertyName).onInterface(interfaceName).getResultAsFuture(); return proxy_->getPropertyAsync(propertyName).onInterface(interfaceName).getResultAsFuture();
} }
void Set(const std::string& interfaceName, const std::string& propertyName, const sdbus::Variant& value) std::future<sdbus::Variant> GetAsync(const InterfaceName& interfaceName, const std::string& propertyName, with_future_t)
{
return proxy_->getPropertyAsync(propertyName).onInterface(interfaceName).getResultAsFuture();
}
void Set(const InterfaceName& interfaceName, const PropertyName& propertyName, const sdbus::Variant& value)
{ {
proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value); proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value);
} }
void Set(const std::string& interfaceName, const std::string& propertyName, const sdbus::Variant& value, dont_expect_reply_t) void Set(const InterfaceName& interfaceName, const std::string& propertyName, const sdbus::Variant& value)
{
proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value);
}
void Set(const InterfaceName& interfaceName, const PropertyName& propertyName, const sdbus::Variant& value, dont_expect_reply_t)
{
proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value, dont_expect_reply);
}
void Set(const InterfaceName& interfaceName, const std::string& propertyName, const sdbus::Variant& value, dont_expect_reply_t)
{ {
proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value, dont_expect_reply); proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value, dont_expect_reply);
} }
template <typename _Function> template <typename _Function>
PendingAsyncCall SetAsync(const std::string& interfaceName, const std::string& propertyName, const sdbus::Variant& value, _Function&& callback) PendingAsyncCall SetAsync(const InterfaceName& interfaceName, const PropertyName& propertyName, const sdbus::Variant& value, _Function&& callback)
{ {
return proxy_->setPropertyAsync(propertyName).onInterface(interfaceName).toValue(value).uponReplyInvoke(std::forward<_Function>(callback)); return proxy_->setPropertyAsync(propertyName).onInterface(interfaceName).toValue(value).uponReplyInvoke(std::forward<_Function>(callback));
} }
std::future<void> SetAsync(const std::string& interfaceName, const std::string& propertyName, const sdbus::Variant& value, with_future_t) template <typename _Function>
PendingAsyncCall SetAsync(const InterfaceName& interfaceName, const std::string& propertyName, const sdbus::Variant& value, _Function&& callback)
{
return proxy_->setPropertyAsync(propertyName).onInterface(interfaceName).toValue(value).uponReplyInvoke(std::forward<_Function>(callback));
}
std::future<void> SetAsync(const InterfaceName& interfaceName, const PropertyName& propertyName, const sdbus::Variant& value, with_future_t)
{ {
return proxy_->setPropertyAsync(propertyName).onInterface(interfaceName).toValue(value).getResultAsFuture(); return proxy_->setPropertyAsync(propertyName).onInterface(interfaceName).toValue(value).getResultAsFuture();
} }
std::map<std::string, sdbus::Variant> GetAll(const std::string& interfaceName) std::future<void> SetAsync(const InterfaceName& interfaceName, const std::string& propertyName, const sdbus::Variant& value, with_future_t)
{
return proxy_->setPropertyAsync(propertyName).onInterface(interfaceName).toValue(value).getResultAsFuture();
}
std::map<PropertyName, sdbus::Variant> GetAll(const InterfaceName& interfaceName)
{ {
return proxy_->getAllProperties().onInterface(interfaceName); return proxy_->getAllProperties().onInterface(interfaceName);
} }
template <typename _Function> template <typename _Function>
PendingAsyncCall GetAllAsync(const std::string& interfaceName, _Function&& callback) PendingAsyncCall GetAllAsync(const InterfaceName& interfaceName, _Function&& callback)
{ {
return proxy_->getAllPropertiesAsync().onInterface(interfaceName).uponReplyInvoke(std::forward<_Function>(callback)); return proxy_->getAllPropertiesAsync().onInterface(interfaceName).uponReplyInvoke(std::forward<_Function>(callback));
} }
std::future<std::map<std::string, sdbus::Variant>> GetAllAsync(const std::string& interfaceName, with_future_t) std::future<std::map<PropertyName, sdbus::Variant>> GetAllAsync(const InterfaceName& interfaceName, with_future_t)
{ {
return proxy_->getAllPropertiesAsync().onInterface(interfaceName).getResultAsFuture(); return proxy_->getAllPropertiesAsync().onInterface(interfaceName).getResultAsFuture();
} }
@ -205,7 +243,7 @@ namespace sdbus {
// Proxy for object manager // Proxy for object manager
class ObjectManager_proxy class ObjectManager_proxy
{ {
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.ObjectManager"; static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.ObjectManager"};
protected: protected:
ObjectManager_proxy(sdbus::IProxy& proxy) ObjectManager_proxy(sdbus::IProxy& proxy)
@ -226,7 +264,7 @@ namespace sdbus {
->uponSignal("InterfacesAdded") ->uponSignal("InterfacesAdded")
.onInterface(INTERFACE_NAME) .onInterface(INTERFACE_NAME)
.call([this]( const sdbus::ObjectPath& objectPath .call([this]( const sdbus::ObjectPath& objectPath
, const std::map<std::string, std::map<std::string, sdbus::Variant>>& interfacesAndProperties ) , const std::map<sdbus::InterfaceName, std::map<PropertyName, sdbus::Variant>>& interfacesAndProperties )
{ {
this->onInterfacesAdded(objectPath, interfacesAndProperties); this->onInterfacesAdded(objectPath, interfacesAndProperties);
}); });
@ -234,21 +272,21 @@ namespace sdbus {
proxy_->uponSignal("InterfacesRemoved") proxy_->uponSignal("InterfacesRemoved")
.onInterface(INTERFACE_NAME) .onInterface(INTERFACE_NAME)
.call([this]( const sdbus::ObjectPath& objectPath .call([this]( const sdbus::ObjectPath& objectPath
, const std::vector<std::string>& interfaces ) , const std::vector<sdbus::InterfaceName>& interfaces )
{ {
this->onInterfacesRemoved(objectPath, interfaces); this->onInterfacesRemoved(objectPath, interfaces);
}); });
} }
virtual void onInterfacesAdded( const sdbus::ObjectPath& objectPath virtual void onInterfacesAdded( const sdbus::ObjectPath& objectPath
, const std::map<std::string, std::map<std::string, sdbus::Variant>>& interfacesAndProperties) = 0; , const std::map<sdbus::InterfaceName, std::map<PropertyName, sdbus::Variant>>& interfacesAndProperties) = 0;
virtual void onInterfacesRemoved( const sdbus::ObjectPath& objectPath virtual void onInterfacesRemoved( const sdbus::ObjectPath& objectPath
, const std::vector<std::string>& interfaces) = 0; , const std::vector<sdbus::InterfaceName>& interfaces) = 0;
public: public:
std::map<sdbus::ObjectPath, std::map<std::string, std::map<std::string, sdbus::Variant>>> GetManagedObjects() std::map<sdbus::ObjectPath, std::map<sdbus::InterfaceName, std::map<PropertyName, sdbus::Variant>>> GetManagedObjects()
{ {
std::map<sdbus::ObjectPath, std::map<std::string, std::map<std::string, sdbus::Variant>>> objectsInterfacesAndProperties; std::map<sdbus::ObjectPath, std::map<sdbus::InterfaceName, std::map<PropertyName, sdbus::Variant>>> objectsInterfacesAndProperties;
proxy_->callMethod("GetManagedObjects").onInterface(INTERFACE_NAME).storeResultsTo(objectsInterfacesAndProperties); proxy_->callMethod("GetManagedObjects").onInterface(INTERFACE_NAME).storeResultsTo(objectsInterfacesAndProperties);
return objectsInterfacesAndProperties; return objectsInterfacesAndProperties;
} }
@ -264,7 +302,7 @@ namespace sdbus {
// Adaptor for properties // Adaptor for properties
class Properties_adaptor class Properties_adaptor
{ {
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.Properties"; static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.Properties"};
protected: protected:
Properties_adaptor(sdbus::IObject& object) : object_(&object) Properties_adaptor(sdbus::IObject& object) : object_(&object)
@ -283,12 +321,12 @@ namespace sdbus {
} }
public: public:
void emitPropertiesChangedSignal(const std::string& interfaceName, const std::vector<std::string>& properties) void emitPropertiesChangedSignal(const InterfaceName& interfaceName, const std::vector<PropertyName>& properties)
{ {
object_->emitPropertiesChangedSignal(interfaceName, properties); object_->emitPropertiesChangedSignal(interfaceName, properties);
} }
void emitPropertiesChangedSignal(const std::string& interfaceName) void emitPropertiesChangedSignal(const InterfaceName& interfaceName)
{ {
object_->emitPropertiesChangedSignal(interfaceName); object_->emitPropertiesChangedSignal(interfaceName);
} }
@ -309,7 +347,7 @@ namespace sdbus {
*/ */
class ObjectManager_adaptor class ObjectManager_adaptor
{ {
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.ObjectManager"; static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.ObjectManager"};
protected: protected:
explicit ObjectManager_adaptor(sdbus::IObject& object) : object_(&object) explicit ObjectManager_adaptor(sdbus::IObject& object) : object_(&object)
@ -378,7 +416,7 @@ namespace sdbus {
* *
* See IObject::emitInterfacesAddedSignal(). * See IObject::emitInterfacesAddedSignal().
*/ */
void emitInterfacesAddedSignal(const std::vector<std::string>& interfaces) void emitInterfacesAddedSignal(const std::vector<sdbus::InterfaceName>& interfaces)
{ {
object_->emitInterfacesAddedSignal(interfaces); object_->emitInterfacesAddedSignal(interfaces);
} }
@ -398,7 +436,7 @@ namespace sdbus {
* *
* See IObject::emitInterfacesRemovedSignal(). * See IObject::emitInterfacesRemovedSignal().
*/ */
void emitInterfacesRemovedSignal(const std::vector<std::string>& interfaces) void emitInterfacesRemovedSignal(const std::vector<InterfaceName>& interfaces)
{ {
object_->emitInterfacesRemovedSignal(interfaces); object_->emitInterfacesRemovedSignal(interfaces);
} }

View File

@ -54,6 +54,9 @@ namespace sdbus {
class ObjectPath; class ObjectPath;
class Signature; class Signature;
class UnixFd; class UnixFd;
class BusName;
class InterfaceName;
class MemberName;
class MethodCall; class MethodCall;
class MethodReply; class MethodReply;
class Signal; class Signal;
@ -309,6 +312,21 @@ namespace sdbus {
} }
}; };
template <>
struct signature_of<BusName> : signature_of<std::string>
{
};
template <>
struct signature_of<InterfaceName> : signature_of<std::string>
{
};
template <>
struct signature_of<MemberName> : signature_of<std::string>
{
};
template <typename... _ValueTypes> template <typename... _ValueTypes>
struct signature_of<Struct<_ValueTypes...>> struct signature_of<Struct<_ValueTypes...>>
{ {

View File

@ -171,42 +171,107 @@ namespace sdbus {
/********************************************//** /********************************************//**
* @class ObjectPath * @class ObjectPath
* *
* Representation of object path D-Bus type * Strong type representing the D-Bus object path
* *
***********************************************/ ***********************************************/
class ObjectPath : public std::string class ObjectPath : public std::string
{ {
public: public:
using std::string::string; ObjectPath() = default;
ObjectPath() = default; // Fixes gcc 6.3 error (default c-tor is not imported in above using declaration) explicit ObjectPath(std::string value)
ObjectPath(const ObjectPath&) = default; // Fixes gcc 8.3 error (deleted copy constructor) : std::string(std::move(value))
ObjectPath(ObjectPath&&) = default; // Enable move - user-declared copy ctor prevents implicit creation
ObjectPath& operator = (const ObjectPath&) = default; // Fixes gcc 8.3 error (deleted copy assignment)
ObjectPath& operator = (ObjectPath&&) = default; // Enable move - user-declared copy assign prevents implicit creation
ObjectPath(std::string path)
: std::string(std::move(path))
{} {}
explicit ObjectPath(const char* value)
: std::string(value)
{}
using std::string::operator=; using std::string::operator=;
}; };
/********************************************//**
* @class BusName
*
* Strong type representing the D-Bus bus/service/connection name
*
***********************************************/
class BusName : public std::string
{
public:
BusName() = default;
explicit BusName(std::string value)
: std::string(std::move(value))
{}
explicit BusName(const char* value)
: std::string(value)
{}
using std::string::operator=;
};
using ServiceName = BusName;
using ConnectionName = BusName;
/********************************************//**
* @class InterfaceName
*
* Strong type representing the D-Bus interface name
*
***********************************************/
class InterfaceName : public std::string
{
public:
InterfaceName() = default;
explicit InterfaceName(std::string value)
: std::string(std::move(value))
{}
explicit InterfaceName(const char* value)
: std::string(value)
{}
using std::string::operator=;
};
/********************************************//**
* @class MemberName
*
* Strong type representing the D-Bus member name
*
***********************************************/
class MemberName : public std::string
{
public:
MemberName() = default;
explicit MemberName(std::string value)
: std::string(std::move(value))
{}
explicit MemberName(const char* value)
: std::string(value)
{}
using std::string::operator=;
};
using MethodName = MemberName;
using SignalName = MemberName;
using PropertyName = MemberName;
/********************************************//** /********************************************//**
* @class Signature * @class Signature
* *
* Representation of Signature D-Bus type * Strong type representing the D-Bus object path
* *
***********************************************/ ***********************************************/
class Signature : public std::string class Signature : public std::string
{ {
public: public:
using std::string::string; Signature() = default;
Signature() = default; // Fixes gcc 6.3 error (default c-tor is not imported in above using declaration) explicit Signature(std::string value)
Signature(const Signature&) = default; // Fixes gcc 8.3 error (deleted copy constructor) : std::string(std::move(value))
Signature(Signature&&) = default; // Enable move - user-declared copy ctor prevents implicit creation
Signature& operator = (const Signature&) = default; // Fixes gcc 8.3 error (deleted copy assignment)
Signature& operator = (Signature&&) = default; // Enable move - user-declared copy assign prevents implicit creation
Signature(std::string path)
: std::string(std::move(path))
{} {}
explicit Signature(const char* value)
: std::string(value)
{}
using std::string::operator=; using std::string::operator=;
}; };

View File

@ -27,6 +27,7 @@
#define SDBUS_CXX_VTABLEITEMS_H_ #define SDBUS_CXX_VTABLEITEMS_H_
#include <sdbus-c++/Flags.h> #include <sdbus-c++/Flags.h>
#include <sdbus-c++/Types.h>
#include <sdbus-c++/TypeTraits.h> #include <sdbus-c++/TypeTraits.h>
#include <string> #include <string>
@ -46,15 +47,16 @@ namespace sdbus {
MethodVTableItem& markAsPrivileged(); MethodVTableItem& markAsPrivileged();
MethodVTableItem& withNoReply(); MethodVTableItem& withNoReply();
std::string name; MethodName name;
std::string inputSignature; Signature inputSignature;
std::vector<std::string> inputParamNames; std::vector<std::string> inputParamNames;
std::string outputSignature; Signature outputSignature;
std::vector<std::string> outputParamNames; std::vector<std::string> outputParamNames;
method_callback callbackHandler; method_callback callbackHandler;
Flags flags; Flags flags;
}; };
MethodVTableItem registerMethod(MethodName methodName);
MethodVTableItem registerMethod(std::string methodName); MethodVTableItem registerMethod(std::string methodName);
struct SignalVTableItem struct SignalVTableItem
@ -64,12 +66,13 @@ namespace sdbus {
template <typename... _Args, typename... _String> SignalVTableItem& withParameters(_String... names); template <typename... _Args, typename... _String> SignalVTableItem& withParameters(_String... names);
SignalVTableItem& markAsDeprecated(); SignalVTableItem& markAsDeprecated();
std::string name; SignalName name;
std::string signature; Signature signature;
std::vector<std::string> paramNames; std::vector<std::string> paramNames;
Flags flags; Flags flags;
}; };
SignalVTableItem registerSignal(SignalName signalName);
SignalVTableItem registerSignal(std::string signalName); SignalVTableItem registerSignal(std::string signalName);
struct PropertyVTableItem struct PropertyVTableItem
@ -80,13 +83,14 @@ namespace sdbus {
PropertyVTableItem& markAsPrivileged(); PropertyVTableItem& markAsPrivileged();
PropertyVTableItem& withUpdateBehavior(Flags::PropertyUpdateBehaviorFlags behavior); PropertyVTableItem& withUpdateBehavior(Flags::PropertyUpdateBehaviorFlags behavior);
std::string name; PropertyName name;
std::string signature; Signature signature;
property_get_callback getter; property_get_callback getter;
property_set_callback setter; property_set_callback setter;
Flags flags; Flags flags;
}; };
PropertyVTableItem registerProperty(PropertyName propertyName);
PropertyVTableItem registerProperty(std::string propertyName); PropertyVTableItem registerProperty(std::string propertyName);
struct InterfaceFlagsVTableItem struct InterfaceFlagsVTableItem

View File

@ -125,11 +125,16 @@ namespace sdbus {
return *this; return *this;
} }
inline MethodVTableItem registerMethod(std::string methodName) inline MethodVTableItem registerMethod(MethodName methodName)
{ {
return {std::move(methodName), {}, {}, {}, {}, {}, {}}; return {std::move(methodName), {}, {}, {}, {}, {}, {}};
} }
inline MethodVTableItem registerMethod(std::string methodName)
{
return registerMethod(MethodName{std::move(methodName)});
}
/*** -------------------- ***/ /*** -------------------- ***/
/*** Signal VTable Item ***/ /*** Signal VTable Item ***/
/*** -------------------- ***/ /*** -------------------- ***/
@ -166,11 +171,16 @@ namespace sdbus {
return *this; return *this;
} }
inline SignalVTableItem registerSignal(std::string signalName) inline SignalVTableItem registerSignal(SignalName signalName)
{ {
return {std::move(signalName), {}, {}, {}}; return {std::move(signalName), {}, {}, {}};
} }
inline SignalVTableItem registerSignal(std::string signalName)
{
return registerSignal(SignalName{std::move(signalName)});
}
/*** -------------------- ***/ /*** -------------------- ***/
/*** Property VTable Item ***/ /*** Property VTable Item ***/
/*** -------------------- ***/ /*** -------------------- ***/
@ -239,11 +249,16 @@ namespace sdbus {
return *this; return *this;
} }
inline PropertyVTableItem registerProperty(std::string propertyName) inline PropertyVTableItem registerProperty(PropertyName propertyName)
{ {
return {std::move(propertyName), {}, {}, {}, {}}; return {std::move(propertyName), {}, {}, {}, {}};
} }
inline PropertyVTableItem registerProperty(std::string propertyName)
{
return registerProperty(PropertyName{std::move(propertyName)});
}
/*** --------------------------- ***/ /*** --------------------------- ***/
/*** Interface Flags VTable Item ***/ /*** Interface Flags VTable Item ***/
/*** --------------------------- ***/ /*** --------------------------- ***/

View File

@ -28,6 +28,7 @@
#include "sdbus-c++/Error.h" #include "sdbus-c++/Error.h"
#include "sdbus-c++/Message.h" #include "sdbus-c++/Message.h"
#include "sdbus-c++/Types.h"
#include "MessageUtils.h" #include "MessageUtils.h"
#include "ScopeGuard.h" #include "ScopeGuard.h"
@ -108,7 +109,7 @@ Connection::~Connection()
Connection::leaveEventLoop(); Connection::leaveEventLoop();
} }
void Connection::requestName(const std::string& name) void Connection::requestName(const ServiceName& name)
{ {
SDBUS_CHECK_SERVICE_NAME(name); SDBUS_CHECK_SERVICE_NAME(name);
@ -120,7 +121,7 @@ void Connection::requestName(const std::string& name)
wakeUpEventLoopIfMessagesInQueue(); wakeUpEventLoopIfMessagesInQueue();
} }
void Connection::releaseName(const std::string& name) void Connection::releaseName(const ServiceName& name)
{ {
auto r = sdbus_->sd_bus_release_name(bus_.get(), name.c_str()); auto r = sdbus_->sd_bus_release_name(bus_.get(), name.c_str());
SDBUS_THROW_ERROR_IF(r < 0, "Failed to release bus name", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to release bus name", -r);
@ -130,12 +131,12 @@ void Connection::releaseName(const std::string& name)
wakeUpEventLoopIfMessagesInQueue(); wakeUpEventLoopIfMessagesInQueue();
} }
std::string Connection::getUniqueName() const BusName Connection::getUniqueName() const
{ {
const char* unique = nullptr; const char* name{};
auto r = sdbus_->sd_bus_get_unique_name(bus_.get(), &unique); auto r = sdbus_->sd_bus_get_unique_name(bus_.get(), &name);
SDBUS_THROW_ERROR_IF(r < 0 || unique == nullptr, "Failed to get unique bus name", -r); SDBUS_THROW_ERROR_IF(r < 0 || name == nullptr, "Failed to get unique bus name", -r);
return unique; return BusName{name};
} }
void Connection::enterEventLoop() void Connection::enterEventLoop()
@ -188,14 +189,14 @@ ISdBus& Connection::getSdBusInterface()
return *sdbus_.get(); return *sdbus_.get();
} }
void Connection::addObjectManager(const std::string& objectPath, floating_slot_t) void Connection::addObjectManager(const ObjectPath& objectPath, floating_slot_t)
{ {
auto r = sdbus_->sd_bus_add_object_manager(bus_.get(), nullptr, objectPath.c_str()); auto r = sdbus_->sd_bus_add_object_manager(bus_.get(), nullptr, objectPath.c_str());
SDBUS_THROW_ERROR_IF(r < 0, "Failed to add object manager", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to add object manager", -r);
} }
Slot Connection::addObjectManager(const std::string& objectPath, return_slot_t) Slot Connection::addObjectManager(const ObjectPath& objectPath, return_slot_t)
{ {
sd_bus_slot *slot{}; sd_bus_slot *slot{};
@ -456,8 +457,8 @@ void Connection::deleteSdEventSource(sd_event_source *s)
#endif // SDBUS_basu #endif // SDBUS_basu
Slot Connection::addObjectVTable( const std::string& objectPath Slot Connection::addObjectVTable( const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const sd_bus_vtable* vtable , const sd_bus_vtable* vtable
, void* userData ) , void* userData )
{ {
@ -486,10 +487,10 @@ PlainMessage Connection::createPlainMessage() const
return Message::Factory::create<PlainMessage>(sdbusMsg, sdbus_.get(), adopt_message); return Message::Factory::create<PlainMessage>(sdbusMsg, sdbus_.get(), adopt_message);
} }
MethodCall Connection::createMethodCall( const std::string& destination MethodCall Connection::createMethodCall( const ServiceName& destination
, const std::string& objectPath , const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::string& methodName ) const , const MethodName& methodName ) const
{ {
sd_bus_message *sdbusMsg{}; sd_bus_message *sdbusMsg{};
@ -505,9 +506,9 @@ MethodCall Connection::createMethodCall( const std::string& destination
return Message::Factory::create<MethodCall>(sdbusMsg, sdbus_.get(), adopt_message); return Message::Factory::create<MethodCall>(sdbusMsg, sdbus_.get(), adopt_message);
} }
Signal Connection::createSignal( const std::string& objectPath Signal Connection::createSignal( const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::string& signalName ) const , const SignalName& signalName ) const
{ {
sd_bus_message *sdbusMsg{}; sd_bus_message *sdbusMsg{};
@ -562,9 +563,9 @@ Slot Connection::callMethod(const MethodCall& message, void* callback, void* use
return slot; return slot;
} }
void Connection::emitPropertiesChangedSignal( const std::string& objectPath void Connection::emitPropertiesChangedSignal( const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::vector<std::string>& propNames ) , const std::vector<PropertyName>& propNames )
{ {
auto names = to_strv(propNames); auto names = to_strv(propNames);
@ -576,15 +577,15 @@ void Connection::emitPropertiesChangedSignal( const std::string& objectPath
SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit PropertiesChanged signal", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit PropertiesChanged signal", -r);
} }
void Connection::emitInterfacesAddedSignal(const std::string& objectPath) void Connection::emitInterfacesAddedSignal(const ObjectPath& objectPath)
{ {
auto r = sdbus_->sd_bus_emit_object_added(bus_.get(), objectPath.c_str()); auto r = sdbus_->sd_bus_emit_object_added(bus_.get(), objectPath.c_str());
SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesAdded signal for all registered interfaces", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesAdded signal for all registered interfaces", -r);
} }
void Connection::emitInterfacesAddedSignal( const std::string& objectPath void Connection::emitInterfacesAddedSignal( const ObjectPath& objectPath
, const std::vector<std::string>& interfaces ) , const std::vector<InterfaceName>& interfaces )
{ {
auto names = to_strv(interfaces); auto names = to_strv(interfaces);
@ -595,15 +596,15 @@ void Connection::emitInterfacesAddedSignal( const std::string& objectPath
SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesAdded signal", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesAdded signal", -r);
} }
void Connection::emitInterfacesRemovedSignal(const std::string& objectPath) void Connection::emitInterfacesRemovedSignal(const ObjectPath& objectPath)
{ {
auto r = sdbus_->sd_bus_emit_object_removed(bus_.get(), objectPath.c_str()); auto r = sdbus_->sd_bus_emit_object_removed(bus_.get(), objectPath.c_str());
SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesRemoved signal for all registered interfaces", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesRemoved signal for all registered interfaces", -r);
} }
void Connection::emitInterfacesRemovedSignal( const std::string& objectPath void Connection::emitInterfacesRemovedSignal( const ObjectPath& objectPath
, const std::vector<std::string>& interfaces ) , const std::vector<InterfaceName>& interfaces )
{ {
auto names = to_strv(interfaces); auto names = to_strv(interfaces);
@ -614,10 +615,10 @@ void Connection::emitInterfacesRemovedSignal( const std::string& objectPath
SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesRemoved signal", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesRemoved signal", -r);
} }
Slot Connection::registerSignalHandler( const std::string& sender Slot Connection::registerSignalHandler( const ServiceName& sender
, const std::string& objectPath , const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::string& signalName , const SignalName& signalName
, sd_bus_message_handler_t callback , sd_bus_message_handler_t callback
, void* userData ) , void* userData )
{ {
@ -777,7 +778,8 @@ Message Connection::getCurrentlyProcessedMessage() const
return Message::Factory::create<Message>(sdbusMsg, sdbus_.get()); return Message::Factory::create<Message>(sdbusMsg, sdbus_.get());
} }
std::vector</*const */char*> Connection::to_strv(const std::vector<std::string>& strings) template <typename StringBasedType>
std::vector</*const */char*> Connection::to_strv(const std::vector<StringBasedType>& strings)
{ {
std::vector</*const */char*> strv; std::vector</*const */char*> strv;
for (auto& str : strings) for (auto& str : strings)
@ -890,7 +892,7 @@ std::unique_ptr<sdbus::IConnection> createBusConnection()
return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::default_bus); return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::default_bus);
} }
std::unique_ptr<sdbus::IConnection> createBusConnection(const std::string& name) std::unique_ptr<sdbus::IConnection> createBusConnection(const ServiceName& name)
{ {
auto conn = createBusConnection(); auto conn = createBusConnection();
conn->requestName(name); conn->requestName(name);
@ -903,7 +905,7 @@ std::unique_ptr<sdbus::IConnection> createSystemBusConnection()
return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::system_bus); return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::system_bus);
} }
std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const std::string& name) std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const ServiceName& name)
{ {
auto conn = createSystemBusConnection(); auto conn = createSystemBusConnection();
conn->requestName(name); conn->requestName(name);
@ -916,7 +918,7 @@ std::unique_ptr<sdbus::IConnection> createSessionBusConnection()
return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::session_bus); return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::session_bus);
} }
std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const std::string& name) std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const ServiceName& name)
{ {
auto conn = createSessionBusConnection(); auto conn = createSessionBusConnection();
conn->requestName(name); conn->requestName(name);

View File

@ -41,7 +41,18 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
// Forward declarations
struct sd_event_source; struct sd_event_source;
namespace sdbus {
class ObjectPath;
class InterfaceName;
class BusName;
using ServiceName = BusName;
class MemberName;
using MethodName = MemberName;
using SignalName = MemberName;
using PropertyName = MemberName;
}
namespace sdbus::internal { namespace sdbus::internal {
@ -81,9 +92,9 @@ namespace sdbus::internal {
Connection(std::unique_ptr<ISdBus>&& interface, pseudo_bus_t); Connection(std::unique_ptr<ISdBus>&& interface, pseudo_bus_t);
~Connection() override; ~Connection() override;
void requestName(const std::string& name) override; void requestName(const ServiceName & name) override;
void releaseName(const std::string& name) override; void releaseName(const ServiceName& name) override;
[[nodiscard]] std::string getUniqueName() const override; [[nodiscard]] BusName getUniqueName() const override;
void enterEventLoop() override; void enterEventLoop() override;
void enterEventLoopAsync() override; void enterEventLoopAsync() override;
void leaveEventLoop() override; void leaveEventLoop() override;
@ -91,8 +102,8 @@ namespace sdbus::internal {
bool processPendingEvent() override; bool processPendingEvent() override;
Message getCurrentlyProcessedMessage() const override; Message getCurrentlyProcessedMessage() const override;
void addObjectManager(const std::string& objectPath, floating_slot_t) override; void addObjectManager(const ObjectPath& objectPath, floating_slot_t) override;
Slot addObjectManager(const std::string& objectPath, return_slot_t) override; Slot addObjectManager(const ObjectPath& objectPath, return_slot_t) override;
void setMethodCallTimeout(uint64_t timeout) override; void setMethodCallTimeout(uint64_t timeout) override;
[[nodiscard]] uint64_t getMethodCallTimeout() const override; [[nodiscard]] uint64_t getMethodCallTimeout() const override;
@ -109,38 +120,38 @@ namespace sdbus::internal {
[[nodiscard]] const ISdBus& getSdBusInterface() const override; [[nodiscard]] const ISdBus& getSdBusInterface() const override;
[[nodiscard]] ISdBus& getSdBusInterface() override; [[nodiscard]] ISdBus& getSdBusInterface() override;
Slot addObjectVTable( const std::string& objectPath Slot addObjectVTable( const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const sd_bus_vtable* vtable , const sd_bus_vtable* vtable
, void* userData ) override; , void* userData ) override;
[[nodiscard]] PlainMessage createPlainMessage() const override; [[nodiscard]] PlainMessage createPlainMessage() const override;
[[nodiscard]] MethodCall createMethodCall( const std::string& destination [[nodiscard]] MethodCall createMethodCall( const ServiceName& destination
, const std::string& objectPath , const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::string& methodName ) const override; , const MethodName& methodName ) const override;
[[nodiscard]] Signal createSignal( const std::string& objectPath [[nodiscard]] Signal createSignal( const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::string& signalName ) const override; , const SignalName& signalName ) const override;
MethodReply callMethod(const MethodCall& message, uint64_t timeout) override; MethodReply callMethod(const MethodCall& message, uint64_t timeout) override;
void callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout, floating_slot_t) override; void callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout, floating_slot_t) override;
Slot callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout) override; Slot callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout) override;
void emitPropertiesChangedSignal( const std::string& objectPath void emitPropertiesChangedSignal( const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::vector<std::string>& propNames ) override; , const std::vector<PropertyName>& propNames ) override;
void emitInterfacesAddedSignal(const std::string& objectPath) override; void emitInterfacesAddedSignal(const ObjectPath& objectPath) override;
void emitInterfacesAddedSignal( const std::string& objectPath void emitInterfacesAddedSignal( const ObjectPath& objectPath
, const std::vector<std::string>& interfaces ) override; , const std::vector<InterfaceName>& interfaces ) override;
void emitInterfacesRemovedSignal(const std::string& objectPath) override; void emitInterfacesRemovedSignal(const ObjectPath& objectPath) override;
void emitInterfacesRemovedSignal( const std::string& objectPath void emitInterfacesRemovedSignal( const ObjectPath& objectPath
, const std::vector<std::string>& interfaces ) override; , const std::vector<InterfaceName>& interfaces ) override;
Slot registerSignalHandler( const std::string& sender Slot registerSignalHandler( const ServiceName& sender
, const std::string& objectPath , const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::string& signalName , const SignalName& signalName
, sd_bus_message_handler_t callback , sd_bus_message_handler_t callback
, void* userData ) override; , void* userData ) override;
@ -161,7 +172,8 @@ namespace sdbus::internal {
void wakeUpEventLoopIfMessagesInQueue(); void wakeUpEventLoopIfMessagesInQueue();
void joinWithEventLoop(); void joinWithEventLoop();
static std::vector</*const */char*> to_strv(const std::vector<std::string>& strings); template <typename StringBasedType>
static std::vector</*const */char*> to_strv(const std::vector<StringBasedType>& strings);
static int sdbus_match_callback(sd_bus_message *sdbusMessage, void *userData, sd_bus_error *retError); static int sdbus_match_callback(sd_bus_message *sdbusMessage, void *userData, sd_bus_error *retError);
static int sdbus_match_install_callback(sd_bus_message *sdbusMessage, void *userData, sd_bus_error *retError); static int sdbus_match_install_callback(sd_bus_message *sdbusMessage, void *userData, sd_bus_error *retError);

View File

@ -32,14 +32,18 @@
namespace sdbus namespace sdbus
{ {
sdbus::Error createError(int errNo, const std::string& customMsg) sdbus::Error createError(int errNo, std::string customMsg)
{ {
sd_bus_error sdbusError = SD_BUS_ERROR_NULL; sd_bus_error sdbusError = SD_BUS_ERROR_NULL;
sd_bus_error_set_errno(&sdbusError, errNo); sd_bus_error_set_errno(&sdbusError, errNo);
SCOPE_EXIT{ sd_bus_error_free(&sdbusError); }; SCOPE_EXIT{ sd_bus_error_free(&sdbusError); };
std::string name(sdbusError.name); Error::Name name(sdbusError.name);
std::string message(customMsg + " (" + sdbusError.message + ")"); std::string message(std::move(customMsg));
return sdbus::Error(name, message); message.append(" (");
message.append(sdbusError.message);
message.append(")");
return Error(std::move(name), std::move(message));
} }
} // namespace sdbus } // namespace sdbus

View File

@ -37,12 +37,20 @@
#include SDBUS_HEADER #include SDBUS_HEADER
#include <vector> #include <vector>
// Forward declaration // Forward declarations
namespace sdbus { namespace sdbus {
class MethodCall; class MethodCall;
class MethodReply; class MethodReply;
class Signal; class Signal;
class PlainMessage; class PlainMessage;
class ObjectPath;
class InterfaceName;
class BusName;
using ServiceName = BusName;
class MemberName;
using MethodName = MemberName;
using SignalName = MemberName;
using PropertyName = MemberName;
namespace internal { namespace internal {
class ISdBus; class ISdBus;
} }
@ -59,41 +67,41 @@ namespace sdbus::internal {
[[nodiscard]] virtual const ISdBus& getSdBusInterface() const = 0; [[nodiscard]] virtual const ISdBus& getSdBusInterface() const = 0;
[[nodiscard]] virtual ISdBus& getSdBusInterface() = 0; [[nodiscard]] virtual ISdBus& getSdBusInterface() = 0;
[[nodiscard]] virtual Slot addObjectVTable( const std::string& objectPath [[nodiscard]] virtual Slot addObjectVTable( const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const sd_bus_vtable* vtable , const sd_bus_vtable* vtable
, void* userData ) = 0; , void* userData ) = 0;
[[nodiscard]] virtual PlainMessage createPlainMessage() const = 0; [[nodiscard]] virtual PlainMessage createPlainMessage() const = 0;
[[nodiscard]] virtual MethodCall createMethodCall( const std::string& destination [[nodiscard]] virtual MethodCall createMethodCall( const ServiceName& destination
, const std::string& objectPath , const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::string& methodName ) const = 0; , const MethodName& methodName ) const = 0;
[[nodiscard]] virtual Signal createSignal( const std::string& objectPath [[nodiscard]] virtual Signal createSignal( const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::string& signalName ) const = 0; , const SignalName& signalName ) const = 0;
virtual MethodReply callMethod(const MethodCall& message, uint64_t timeout) = 0; virtual MethodReply callMethod(const MethodCall& message, uint64_t timeout) = 0;
virtual void callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout, floating_slot_t) = 0; virtual void callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout, floating_slot_t) = 0;
[[nodiscard]] virtual Slot callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout) = 0; [[nodiscard]] virtual Slot callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout) = 0;
virtual void emitPropertiesChangedSignal( const std::string& objectPath virtual void emitPropertiesChangedSignal( const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::vector<std::string>& propNames ) = 0; , const std::vector<PropertyName>& propNames ) = 0;
virtual void emitInterfacesAddedSignal(const std::string& objectPath) = 0; virtual void emitInterfacesAddedSignal(const ObjectPath& objectPath) = 0;
virtual void emitInterfacesAddedSignal( const std::string& objectPath virtual void emitInterfacesAddedSignal( const ObjectPath& objectPath
, const std::vector<std::string>& interfaces ) = 0; , const std::vector<InterfaceName>& interfaces ) = 0;
virtual void emitInterfacesRemovedSignal(const std::string& objectPath) = 0; virtual void emitInterfacesRemovedSignal(const ObjectPath& objectPath) = 0;
virtual void emitInterfacesRemovedSignal( const std::string& objectPath virtual void emitInterfacesRemovedSignal( const ObjectPath& objectPath
, const std::vector<std::string>& interfaces ) = 0; , const std::vector<InterfaceName>& interfaces ) = 0;
using sdbus::IConnection::addObjectManager; using sdbus::IConnection::addObjectManager;
[[nodiscard]] virtual Slot addObjectManager(const std::string& objectPath, return_slot_t) = 0; [[nodiscard]] virtual Slot addObjectManager(const ObjectPath& objectPath, return_slot_t) = 0;
[[nodiscard]] virtual Slot registerSignalHandler( const std::string& sender [[nodiscard]] virtual Slot registerSignalHandler( const ServiceName& sender
, const std::string& objectPath , const ObjectPath& objectPath
, const std::string& interfaceName , const InterfaceName& interfaceName
, const std::string& signalName , const SignalName& signalName
, sd_bus_message_handler_t callback , sd_bus_message_handler_t callback
, void* userData ) = 0; , void* userData ) = 0;
}; };

View File

@ -602,33 +602,34 @@ void Message::rewind(bool complete)
SDBUS_THROW_ERROR_IF(r < 0, "Failed to rewind the message", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to rewind the message", -r);
} }
std::string Message::getInterfaceName() const InterfaceName Message::getInterfaceName() const
{ {
auto interface = sd_bus_message_get_interface((sd_bus_message*)msg_); const auto* interface = sd_bus_message_get_interface((sd_bus_message*)msg_);
return interface != nullptr ? interface : ""; return interface != nullptr ? InterfaceName{interface} : InterfaceName{};
} }
std::string Message::getMemberName() const MemberName Message::getMemberName() const
{ {
auto member = sd_bus_message_get_member((sd_bus_message*)msg_); const auto* member = sd_bus_message_get_member((sd_bus_message*)msg_);
return member != nullptr ? member : ""; return member != nullptr ? MemberName{member} : MemberName{};
} }
std::string Message::getSender() const ConnectionName Message::getSender() const
{ {
return sd_bus_message_get_sender((sd_bus_message*)msg_); const auto* sender = sd_bus_message_get_sender((sd_bus_message*)msg_);
return ConnectionName{sender};
} }
std::string Message::getPath() const ObjectPath Message::getPath() const
{ {
auto path = sd_bus_message_get_path((sd_bus_message*)msg_); const auto* path = sd_bus_message_get_path((sd_bus_message*)msg_);
return path != nullptr ? path : ""; return path != nullptr ? ObjectPath{path} : ObjectPath{};
} }
std::string Message::getDestination() const ConnectionName Message::getDestination() const
{ {
auto destination = sd_bus_message_get_destination((sd_bus_message*)msg_); const auto* destination = sd_bus_message_get_destination((sd_bus_message*)msg_);
return destination != nullptr ? destination : ""; return destination != nullptr ? ConnectionName{destination} : ConnectionName{};
} }
void Message::peekType(std::string& type, std::string& contents) const void Message::peekType(std::string& type, std::string& contents) const
@ -801,7 +802,7 @@ MethodReply MethodCall::sendWithReply(uint64_t timeout) const
auto r = sdbus_->sd_bus_call(nullptr, (sd_bus_message*)msg_, timeout, &sdbusError, &sdbusReply); auto r = sdbus_->sd_bus_call(nullptr, (sd_bus_message*)msg_, timeout, &sdbusError, &sdbusReply);
if (sd_bus_error_is_set(&sdbusError)) if (sd_bus_error_is_set(&sdbusError))
throw sdbus::Error(sdbusError.name, sdbusError.message); throw Error(Error::Name{sdbusError.name}, sdbusError.message);
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r);
@ -866,7 +867,7 @@ void Signal::send() const
SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit signal", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit signal", -r);
} }
void Signal::setDestination(const std::string& destination) void Signal::setDestination(const ConnectionName& destination)
{ {
auto r = sdbus_->sd_bus_message_set_destination((sd_bus_message*)msg_, destination.c_str()); auto r = sdbus_->sd_bus_message_set_destination((sd_bus_message*)msg_, destination.c_str());
SDBUS_THROW_ERROR_IF(r < 0, "Failed to set signal destination", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to set signal destination", -r);

View File

@ -43,20 +43,20 @@
namespace sdbus::internal { namespace sdbus::internal {
Object::Object(sdbus::internal::IConnection& connection, std::string objectPath) Object::Object(sdbus::internal::IConnection& connection, ObjectPath objectPath)
: connection_(connection), objectPath_(std::move(objectPath)) : connection_(connection), objectPath_(std::move(objectPath))
{ {
SDBUS_CHECK_OBJECT_PATH(objectPath_); SDBUS_CHECK_OBJECT_PATH(objectPath_);
} }
void Object::addVTable(std::string interfaceName, std::vector<VTableItem> vtable) void Object::addVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable)
{ {
auto slot = Object::addVTable(std::move(interfaceName), std::move(vtable), return_slot); auto slot = Object::addVTable(std::move(interfaceName), std::move(vtable), return_slot);
vtables_.push_back(std::move(slot)); vtables_.push_back(std::move(slot));
} }
Slot Object::addVTable(std::string interfaceName, std::vector<VTableItem> vtable, return_slot_t) Slot Object::addVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable, return_slot_t)
{ {
SDBUS_CHECK_INTERFACE_NAME(interfaceName); SDBUS_CHECK_INTERFACE_NAME(interfaceName);
@ -79,7 +79,7 @@ void Object::unregister()
removeObjectManager(); removeObjectManager();
} }
sdbus::Signal Object::createSignal(const std::string& interfaceName, const std::string& signalName) sdbus::Signal Object::createSignal(const InterfaceName& interfaceName, const SignalName& signalName)
{ {
return connection_.createSignal(objectPath_, interfaceName, signalName); return connection_.createSignal(objectPath_, interfaceName, signalName);
} }
@ -91,12 +91,12 @@ void Object::emitSignal(const sdbus::Signal& message)
message.send(); message.send();
} }
void Object::emitPropertiesChangedSignal(const std::string& interfaceName, const std::vector<std::string>& propNames) void Object::emitPropertiesChangedSignal(const InterfaceName& interfaceName, const std::vector<PropertyName>& propNames)
{ {
connection_.emitPropertiesChangedSignal(objectPath_, interfaceName, propNames); connection_.emitPropertiesChangedSignal(objectPath_, interfaceName, propNames);
} }
void Object::emitPropertiesChangedSignal(const std::string& interfaceName) void Object::emitPropertiesChangedSignal(const InterfaceName& interfaceName)
{ {
Object::emitPropertiesChangedSignal(interfaceName, {}); Object::emitPropertiesChangedSignal(interfaceName, {});
} }
@ -106,7 +106,7 @@ void Object::emitInterfacesAddedSignal()
connection_.emitInterfacesAddedSignal(objectPath_); connection_.emitInterfacesAddedSignal(objectPath_);
} }
void Object::emitInterfacesAddedSignal(const std::vector<std::string>& interfaces) void Object::emitInterfacesAddedSignal(const std::vector<InterfaceName>& interfaces)
{ {
connection_.emitInterfacesAddedSignal(objectPath_, interfaces); connection_.emitInterfacesAddedSignal(objectPath_, interfaces);
} }
@ -116,7 +116,7 @@ void Object::emitInterfacesRemovedSignal()
connection_.emitInterfacesRemovedSignal(objectPath_); connection_.emitInterfacesRemovedSignal(objectPath_);
} }
void Object::emitInterfacesRemovedSignal(const std::vector<std::string>& interfaces) void Object::emitInterfacesRemovedSignal(const std::vector<InterfaceName>& interfaces)
{ {
connection_.emitInterfacesRemovedSignal(objectPath_, interfaces); connection_.emitInterfacesRemovedSignal(objectPath_, interfaces);
} }
@ -141,7 +141,7 @@ sdbus::IConnection& Object::getConnection() const
return connection_; return connection_;
} }
const std::string& Object::getObjectPath() const const ObjectPath& Object::getObjectPath() const
{ {
return objectPath_; return objectPath_;
} }
@ -151,7 +151,7 @@ Message Object::getCurrentlyProcessedMessage() const
return connection_.getCurrentlyProcessedMessage(); return connection_.getCurrentlyProcessedMessage();
} }
Object::VTable Object::createInternalVTable(std::string interfaceName, std::vector<VTableItem> vtable) Object::VTable Object::createInternalVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable)
{ {
VTable internalVTable; VTable internalVTable;
@ -241,8 +241,8 @@ void Object::startSdBusVTable(const Flags& interfaceFlags, std::vector<sd_bus_vt
void Object::writeMethodRecordToSdBusVTable(const VTable::MethodItem& method, std::vector<sd_bus_vtable>& vtable) void Object::writeMethodRecordToSdBusVTable(const VTable::MethodItem& method, std::vector<sd_bus_vtable>& vtable)
{ {
auto vtableItem = createSdBusVTableMethodItem( method.name.c_str() auto vtableItem = createSdBusVTableMethodItem( method.name.c_str()
, method.inputArgs.c_str() , method.inputSignature.c_str()
, method.outputArgs.c_str() , method.outputSignature.c_str()
, method.paramNames.c_str() , method.paramNames.c_str()
, &Object::sdbus_method_callback , &Object::sdbus_method_callback
, method.flags.toSdBusMethodFlags() ); , method.flags.toSdBusMethodFlags() );
@ -278,23 +278,27 @@ void Object::finalizeSdBusVTable(std::vector<sd_bus_vtable>& vtable)
vtable.push_back(createSdBusVTableEndItem()); vtable.push_back(createSdBusVTableEndItem());
} }
const Object::VTable::MethodItem* Object::findMethod(const VTable& vtable, const std::string& methodName) const Object::VTable::MethodItem* Object::findMethod(const VTable& vtable, std::string_view methodName)
{ {
auto it = std::lower_bound(vtable.methods.begin(), vtable.methods.end(), methodName, [](const auto& methodItem, const auto& methodName) auto it = std::lower_bound(vtable.methods.begin(), vtable.methods.end(), methodName, [](const auto& methodItem, const auto& methodName)
{ {
return methodItem.name < methodName; return methodItem.name < methodName;
}); });
(void)it;
return it != vtable.methods.end() && it->name == methodName ? &*it : nullptr; return it != vtable.methods.end() && it->name == methodName ? &*it : nullptr;
} }
const Object::VTable::PropertyItem* Object::findProperty(const VTable& vtable, const std::string& propertyName) const Object::VTable::PropertyItem* Object::findProperty(const VTable& vtable, std::string_view propertyName)
{ {
auto it = std::lower_bound(vtable.properties.begin(), vtable.properties.end(), propertyName, [](const auto& propertyItem, const auto& propertyName) auto it = std::lower_bound(vtable.properties.begin(), vtable.properties.end(), propertyName, [](const auto& propertyItem, const auto& propertyName)
{ {
return propertyItem.name < propertyName; return propertyItem.name < propertyName;
}); });
(void)it;
return it != vtable.properties.end() && it->name == propertyName ? &*it : nullptr; return it != vtable.properties.end() && it->name == propertyName ? &*it : nullptr;
} }
@ -314,7 +318,7 @@ int Object::sdbus_method_callback(sd_bus_message *sdbusMessage, void *userData,
auto message = Message::Factory::create<MethodCall>(sdbusMessage, &vtable->object->connection_.getSdBusInterface()); auto message = Message::Factory::create<MethodCall>(sdbusMessage, &vtable->object->connection_.getSdBusInterface());
const auto* methodItem = findMethod(*vtable, message.getMemberName()); const auto* methodItem = findMethod(*vtable, message.getMemberName()); // TODO: optimize the situation around getMemberName()
assert(methodItem != nullptr); assert(methodItem != nullptr);
assert(methodItem->callback); assert(methodItem->callback);
@ -379,7 +383,7 @@ int Object::sdbus_property_set_callback( sd_bus */*bus*/
namespace sdbus { namespace sdbus {
std::unique_ptr<sdbus::IObject> createObject(sdbus::IConnection& connection, std::string objectPath) std::unique_ptr<sdbus::IObject> createObject(sdbus::IConnection& connection, ObjectPath objectPath)
{ {
auto* sdbusConnection = dynamic_cast<sdbus::internal::IConnection*>(&connection); auto* sdbusConnection = dynamic_cast<sdbus::internal::IConnection*>(&connection);
SDBUS_THROW_ERROR_IF(!sdbusConnection, "Connection is not a real sdbus-c++ connection", EINVAL); SDBUS_THROW_ERROR_IF(!sdbusConnection, "Connection is not a real sdbus-c++ connection", EINVAL);

View File

@ -30,12 +30,14 @@
#include "sdbus-c++/IObject.h" #include "sdbus-c++/IObject.h"
#include "IConnection.h" #include "IConnection.h"
#include "sdbus-c++/Types.h"
#include <cassert> #include <cassert>
#include <functional> #include <functional>
#include <list> #include <list>
#include <memory> #include <memory>
#include <string> #include <string>
#include <string_view>
#include SDBUS_HEADER #include SDBUS_HEADER
#include <vector> #include <vector>
@ -45,27 +47,27 @@ namespace sdbus::internal {
: public IObject : public IObject
{ {
public: public:
Object(sdbus::internal::IConnection& connection, std::string objectPath); Object(sdbus::internal::IConnection& connection, ObjectPath objectPath);
void addVTable(std::string interfaceName, std::vector<VTableItem> vtable) override; void addVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable) override;
Slot addVTable(std::string interfaceName, std::vector<VTableItem> vtable, return_slot_t) override; Slot addVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable, return_slot_t) override;
void unregister() override; void unregister() override;
sdbus::Signal createSignal(const std::string& interfaceName, const std::string& signalName) override; sdbus::Signal createSignal(const InterfaceName& interfaceName, const SignalName& signalName) override;
void emitSignal(const sdbus::Signal& message) override; void emitSignal(const sdbus::Signal& message) override;
void emitPropertiesChangedSignal(const std::string& interfaceName, const std::vector<std::string>& propNames) override; void emitPropertiesChangedSignal(const InterfaceName& interfaceName, const std::vector<PropertyName>& propNames) override;
void emitPropertiesChangedSignal(const std::string& interfaceName) override; void emitPropertiesChangedSignal(const InterfaceName& interfaceName) override;
void emitInterfacesAddedSignal() override; void emitInterfacesAddedSignal() override;
void emitInterfacesAddedSignal(const std::vector<std::string>& interfaces) override; void emitInterfacesAddedSignal(const std::vector<InterfaceName>& interfaces) override;
void emitInterfacesRemovedSignal() override; void emitInterfacesRemovedSignal() override;
void emitInterfacesRemovedSignal(const std::vector<std::string>& interfaces) override; void emitInterfacesRemovedSignal(const std::vector<InterfaceName>& interfaces) override;
void addObjectManager() override; void addObjectManager() override;
void removeObjectManager() override; void removeObjectManager() override;
[[nodiscard]] bool hasObjectManager() const override; [[nodiscard]] bool hasObjectManager() const override;
[[nodiscard]] sdbus::IConnection& getConnection() const override; [[nodiscard]] sdbus::IConnection& getConnection() const override;
[[nodiscard]] const std::string& getObjectPath() const override; [[nodiscard]] const ObjectPath& getObjectPath() const override;
[[nodiscard]] Message getCurrentlyProcessedMessage() const override; [[nodiscard]] Message getCurrentlyProcessedMessage() const override;
private: private:
@ -74,14 +76,14 @@ namespace sdbus::internal {
// An interface can have any number of vtables attached to it, not only one. // An interface can have any number of vtables attached to it, not only one.
struct VTable struct VTable
{ {
std::string interfaceName; InterfaceName interfaceName;
Flags interfaceFlags; Flags interfaceFlags;
struct MethodItem struct MethodItem
{ {
std::string name; MethodName name;
std::string inputArgs; Signature inputSignature;
std::string outputArgs; Signature outputSignature;
std::string paramNames; std::string paramNames;
method_callback callback; method_callback callback;
Flags flags; Flags flags;
@ -91,8 +93,8 @@ namespace sdbus::internal {
struct SignalItem struct SignalItem
{ {
std::string name; SignalName name;
std::string signature; Signature signature;
std::string paramNames; std::string paramNames;
Flags flags; Flags flags;
}; };
@ -101,8 +103,8 @@ namespace sdbus::internal {
struct PropertyItem struct PropertyItem
{ {
std::string name; PropertyName name;
std::string signature; Signature signature;
property_get_callback getCallback; property_get_callback getCallback;
property_set_callback setCallback; property_set_callback setCallback;
Flags flags; Flags flags;
@ -121,7 +123,7 @@ namespace sdbus::internal {
Slot slot; Slot slot;
}; };
VTable createInternalVTable(std::string interfaceName, std::vector<VTableItem> vtable); VTable createInternalVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable);
void writeInterfaceFlagsToVTable(InterfaceFlagsVTableItem flags, VTable& vtable); void writeInterfaceFlagsToVTable(InterfaceFlagsVTableItem flags, VTable& vtable);
void writeMethodRecordToVTable(MethodVTableItem method, VTable& vtable); void writeMethodRecordToVTable(MethodVTableItem method, VTable& vtable);
void writeSignalRecordToVTable(SignalVTableItem signal, VTable& vtable); void writeSignalRecordToVTable(SignalVTableItem signal, VTable& vtable);
@ -134,8 +136,8 @@ namespace sdbus::internal {
static void writePropertyRecordToSdBusVTable(const VTable::PropertyItem& property, std::vector<sd_bus_vtable>& vtable); static void writePropertyRecordToSdBusVTable(const VTable::PropertyItem& property, std::vector<sd_bus_vtable>& vtable);
static void finalizeSdBusVTable(std::vector<sd_bus_vtable>& vtable); static void finalizeSdBusVTable(std::vector<sd_bus_vtable>& vtable);
static const VTable::MethodItem* findMethod(const VTable& vtable, const std::string& methodName); static const VTable::MethodItem* findMethod(const VTable& vtable, std::string_view methodName);
static const VTable::PropertyItem* findProperty(const VTable& vtable, const std::string& propertyName); static const VTable::PropertyItem* findProperty(const VTable& vtable, std::string_view propertyName);
static std::string paramNamesToString(const std::vector<std::string>& paramNames); static std::string paramNamesToString(const std::vector<std::string>& paramNames);
@ -157,7 +159,7 @@ namespace sdbus::internal {
private: private:
sdbus::internal::IConnection& connection_; sdbus::internal::IConnection& connection_;
std::string objectPath_; ObjectPath objectPath_;
std::vector<Slot> vtables_; std::vector<Slot> vtables_;
Slot objectManagerSlot_; Slot objectManagerSlot_;
}; };

View File

@ -41,7 +41,7 @@
namespace sdbus::internal { namespace sdbus::internal {
Proxy::Proxy(sdbus::internal::IConnection& connection, std::string destination, std::string objectPath) Proxy::Proxy(sdbus::internal::IConnection& connection, ServiceName destination, ObjectPath objectPath)
: connection_(&connection, [](sdbus::internal::IConnection *){ /* Intentionally left empty */ }) : connection_(&connection, [](sdbus::internal::IConnection *){ /* Intentionally left empty */ })
, destination_(std::move(destination)) , destination_(std::move(destination))
, objectPath_(std::move(objectPath)) , objectPath_(std::move(objectPath))
@ -54,8 +54,8 @@ Proxy::Proxy(sdbus::internal::IConnection& connection, std::string destination,
} }
Proxy::Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection Proxy::Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
, std::string destination , ServiceName destination
, std::string objectPath ) , ObjectPath objectPath )
: connection_(std::move(connection)) : connection_(std::move(connection))
, destination_(std::move(destination)) , destination_(std::move(destination))
, objectPath_(std::move(objectPath)) , objectPath_(std::move(objectPath))
@ -69,8 +69,8 @@ Proxy::Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
} }
Proxy::Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection Proxy::Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
, std::string destination , ServiceName destination
, std::string objectPath , ObjectPath objectPath
, dont_run_event_loop_thread_t ) , dont_run_event_loop_thread_t )
: connection_(std::move(connection)) : connection_(std::move(connection))
, destination_(std::move(destination)) , destination_(std::move(destination))
@ -83,7 +83,7 @@ Proxy::Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
// This proxy is meant to be created, used for simple synchronous D-Bus call(s) and then dismissed. // This proxy is meant to be created, used for simple synchronous D-Bus call(s) and then dismissed.
} }
MethodCall Proxy::createMethodCall(const std::string& interfaceName, const std::string& methodName) MethodCall Proxy::createMethodCall(const InterfaceName& interfaceName, const MethodName& methodName)
{ {
return connection_->createMethodCall(destination_, objectPath_, interfaceName, methodName); return connection_->createMethodCall(destination_, objectPath_, interfaceName, methodName);
} }
@ -134,8 +134,8 @@ std::future<MethodReply> Proxy::callMethodAsync(const MethodCall& message, uint6
return future; return future;
} }
void Proxy::registerSignalHandler( const std::string& interfaceName void Proxy::registerSignalHandler( const InterfaceName& interfaceName
, const std::string& signalName , const SignalName& signalName
, signal_handler signalHandler ) , signal_handler signalHandler )
{ {
auto slot = Proxy::registerSignalHandler(interfaceName, signalName, std::move(signalHandler), return_slot); auto slot = Proxy::registerSignalHandler(interfaceName, signalName, std::move(signalHandler), return_slot);
@ -143,8 +143,8 @@ void Proxy::registerSignalHandler( const std::string& interfaceName
floatingSignalSlots_.push_back(std::move(slot)); floatingSignalSlots_.push_back(std::move(slot));
} }
Slot Proxy::registerSignalHandler( const std::string& interfaceName Slot Proxy::registerSignalHandler( const InterfaceName& interfaceName
, const std::string& signalName , const SignalName& signalName
, signal_handler signalHandler , signal_handler signalHandler
, return_slot_t ) , return_slot_t )
{ {
@ -175,7 +175,7 @@ sdbus::IConnection& Proxy::getConnection() const
return *connection_; return *connection_;
} }
const std::string& Proxy::getObjectPath() const const ObjectPath& Proxy::getObjectPath() const
{ {
return objectPath_; return objectPath_;
} }
@ -211,7 +211,7 @@ int Proxy::sdbus_async_reply_handler(sd_bus_message *sdbusMessage, void *userDat
} }
else else
{ {
Error exception(error->name, error->message); Error exception(Error::Name{error->name}, error->message);
asyncCallData->callback(std::move(message), std::move(exception)); asyncCallData->callback(std::move(message), std::move(exception));
} }
}, retError); }, retError);
@ -266,8 +266,8 @@ bool PendingAsyncCall::isPending() const
namespace sdbus { namespace sdbus {
std::unique_ptr<sdbus::IProxy> createProxy( IConnection& connection std::unique_ptr<sdbus::IProxy> createProxy( IConnection& connection
, std::string destination , ServiceName destination
, std::string objectPath ) , ObjectPath objectPath )
{ {
auto* sdbusConnection = dynamic_cast<sdbus::internal::IConnection*>(&connection); auto* sdbusConnection = dynamic_cast<sdbus::internal::IConnection*>(&connection);
SDBUS_THROW_ERROR_IF(!sdbusConnection, "Connection is not a real sdbus-c++ connection", EINVAL); SDBUS_THROW_ERROR_IF(!sdbusConnection, "Connection is not a real sdbus-c++ connection", EINVAL);
@ -278,8 +278,8 @@ std::unique_ptr<sdbus::IProxy> createProxy( IConnection& connection
} }
std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<IConnection>&& connection std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<IConnection>&& connection
, std::string destination , ServiceName destination
, std::string objectPath ) , ObjectPath objectPath )
{ {
auto* sdbusConnection = dynamic_cast<sdbus::internal::IConnection*>(connection.get()); auto* sdbusConnection = dynamic_cast<sdbus::internal::IConnection*>(connection.get());
SDBUS_THROW_ERROR_IF(!sdbusConnection, "Connection is not a real sdbus-c++ connection", EINVAL); SDBUS_THROW_ERROR_IF(!sdbusConnection, "Connection is not a real sdbus-c++ connection", EINVAL);
@ -292,8 +292,8 @@ std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<IConnection>&& conne
} }
std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<IConnection>&& connection std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<IConnection>&& connection
, std::string destination , ServiceName destination
, std::string objectPath , ObjectPath objectPath
, dont_run_event_loop_thread_t ) , dont_run_event_loop_thread_t )
{ {
auto* sdbusConnection = dynamic_cast<sdbus::internal::IConnection*>(connection.get()); auto* sdbusConnection = dynamic_cast<sdbus::internal::IConnection*>(connection.get());
@ -307,8 +307,8 @@ std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<IConnection>&& conne
, dont_run_event_loop_thread ); , dont_run_event_loop_thread );
} }
std::unique_ptr<sdbus::IProxy> createProxy( std::string destination std::unique_ptr<sdbus::IProxy> createProxy( ServiceName destination
, std::string objectPath ) , ObjectPath objectPath )
{ {
auto connection = sdbus::createBusConnection(); auto connection = sdbus::createBusConnection();
@ -320,8 +320,8 @@ std::unique_ptr<sdbus::IProxy> createProxy( std::string destination
, std::move(objectPath) ); , std::move(objectPath) );
} }
std::unique_ptr<sdbus::IProxy> createProxy( std::string destination std::unique_ptr<sdbus::IProxy> createProxy( ServiceName destination
, std::string objectPath , ObjectPath objectPath
, dont_run_event_loop_thread_t ) , dont_run_event_loop_thread_t )
{ {
auto connection = sdbus::createBusConnection(); auto connection = sdbus::createBusConnection();

View File

@ -30,6 +30,7 @@
#include "sdbus-c++/IProxy.h" #include "sdbus-c++/IProxy.h"
#include "IConnection.h" #include "IConnection.h"
#include "sdbus-c++/Types.h"
#include <deque> #include <deque>
#include <memory> #include <memory>
@ -45,33 +46,33 @@ namespace sdbus::internal {
{ {
public: public:
Proxy( sdbus::internal::IConnection& connection Proxy( sdbus::internal::IConnection& connection
, std::string destination , ServiceName destination
, std::string objectPath ); , ObjectPath objectPath );
Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
, std::string destination , ServiceName destination
, std::string objectPath ); , ObjectPath objectPath );
Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
, std::string destination , ServiceName destination
, std::string objectPath , ObjectPath objectPath
, dont_run_event_loop_thread_t ); , dont_run_event_loop_thread_t );
MethodCall createMethodCall(const std::string& interfaceName, const std::string& methodName) override; MethodCall createMethodCall(const InterfaceName& interfaceName, const MethodName& methodName) override;
MethodReply callMethod(const MethodCall& message, uint64_t timeout) override; MethodReply callMethod(const MethodCall& message, uint64_t timeout) override;
PendingAsyncCall callMethodAsync(const MethodCall& message, async_reply_handler asyncReplyCallback, uint64_t timeout) override; PendingAsyncCall callMethodAsync(const MethodCall& message, async_reply_handler asyncReplyCallback, uint64_t timeout) override;
std::future<MethodReply> callMethodAsync(const MethodCall& message, with_future_t) override; std::future<MethodReply> callMethodAsync(const MethodCall& message, with_future_t) override;
std::future<MethodReply> callMethodAsync(const MethodCall& message, uint64_t timeout, with_future_t) override; std::future<MethodReply> callMethodAsync(const MethodCall& message, uint64_t timeout, with_future_t) override;
void registerSignalHandler( const std::string& interfaceName void registerSignalHandler( const InterfaceName& interfaceName
, const std::string& signalName , const SignalName& signalName
, signal_handler signalHandler ) override; , signal_handler signalHandler ) override;
Slot registerSignalHandler( const std::string& interfaceName Slot registerSignalHandler( const InterfaceName& interfaceName
, const std::string& signalName , const SignalName& signalName
, signal_handler signalHandler , signal_handler signalHandler
, return_slot_t ) override; , return_slot_t ) override;
void unregister() override; void unregister() override;
[[nodiscard]] sdbus::IConnection& getConnection() const override; [[nodiscard]] sdbus::IConnection& getConnection() const override;
[[nodiscard]] const std::string& getObjectPath() const override; [[nodiscard]] const ObjectPath& getObjectPath() const override;
[[nodiscard]] Message getCurrentlyProcessedMessage() const override; [[nodiscard]] Message getCurrentlyProcessedMessage() const override;
private: private:
@ -84,8 +85,8 @@ namespace sdbus::internal {
std::unique_ptr< sdbus::internal::IConnection std::unique_ptr< sdbus::internal::IConnection
, std::function<void(sdbus::internal::IConnection*)> , std::function<void(sdbus::internal::IConnection*)>
> connection_; > connection_;
std::string destination_; ServiceName destination_;
std::string objectPath_; ObjectPath objectPath_;
std::vector<Slot> floatingSignalSlots_; std::vector<Slot> floatingSignalSlots_;

View File

@ -41,7 +41,7 @@
SDBUS_THROW_ERROR_IF(!_NAME.empty() && !sd_bus_service_name_is_valid(_NAME.c_str()), "Invalid service name '" + _NAME + "' provided", EINVAL) \ SDBUS_THROW_ERROR_IF(!_NAME.empty() && !sd_bus_service_name_is_valid(_NAME.c_str()), "Invalid service name '" + _NAME + "' provided", EINVAL) \
/**/ /**/
#define SDBUS_CHECK_MEMBER_NAME(_NAME) \ #define SDBUS_CHECK_MEMBER_NAME(_NAME) \
SDBUS_THROW_ERROR_IF(!sd_bus_member_name_is_valid(_NAME.c_str()), "Invalid member name '" + _NAME + "' provided", EINVAL) \ SDBUS_THROW_ERROR_IF(!sd_bus_member_name_is_valid(_NAME.c_str()), std::string("Invalid member name '") + _NAME.c_str() + "' provided", EINVAL) \
/**/ /**/
#else #else
#define SDBUS_CHECK_OBJECT_PATH(_PATH) #define SDBUS_CHECK_OBJECT_PATH(_PATH)
@ -66,12 +66,12 @@ namespace sdbus::internal {
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
sd_bus_error_set(retError, SDBUSCPP_ERROR_NAME, e.what()); sd_bus_error_set(retError, SDBUSCPP_ERROR_NAME.c_str(), e.what());
return false; return false;
} }
catch (...) catch (...)
{ {
sd_bus_error_set(retError, SDBUSCPP_ERROR_NAME, "Unknown error occurred"); sd_bus_error_set(retError, SDBUSCPP_ERROR_NAME.c_str(), "Unknown error occurred");
return false; return false;
} }

View File

@ -96,7 +96,7 @@ TYPED_TEST(AsyncSdbusTestObject, RunsServerSideAsynchoronousMethodAsynchronously
std::atomic<int> startedCount{}; std::atomic<int> startedCount{};
auto call = [&](uint32_t param) auto call = [&](uint32_t param)
{ {
TestProxy proxy{BUS_NAME, OBJECT_PATH}; TestProxy proxy{SERVICE_NAME, OBJECT_PATH};
++startedCount; ++startedCount;
while (!invoke) ; while (!invoke) ;
auto result = proxy.doOperationAsync(param); auto result = proxy.doOperationAsync(param);
@ -119,7 +119,7 @@ TYPED_TEST(AsyncSdbusTestObject, HandlesCorrectlyABulkOfParallelServerSideAsyncM
std::atomic<int> startedCount{}; std::atomic<int> startedCount{};
auto call = [&]() auto call = [&]()
{ {
TestProxy proxy{BUS_NAME, OBJECT_PATH}; TestProxy proxy{SERVICE_NAME, OBJECT_PATH};
++startedCount; ++startedCount;
while (!invoke) ; while (!invoke) ;

View File

@ -51,38 +51,43 @@ TEST(Connection, CanBeDefaultConstructed)
ASSERT_NO_THROW(auto con = sdbus::createBusConnection()); ASSERT_NO_THROW(auto con = sdbus::createBusConnection());
} }
TEST(SystemBusConnection, CanRequestRegisteredDbusName) TEST(Connection, CanRequestName)
{ {
auto connection = sdbus::createSystemBusConnection(); auto connection = sdbus::createBusConnection();
ASSERT_NO_THROW(connection->requestName(BUS_NAME)) // In case of system bus connection, requesting may throw as we need to allow that first through a config file in /etc/dbus-1/system.d
ASSERT_NO_THROW(connection->requestName(SERVICE_NAME))
<< "Perhaps you've forgotten to copy `org.sdbuscpp.integrationtests.conf` file to `/etc/dbus-1/system.d` directory before running the tests?"; << "Perhaps you've forgotten to copy `org.sdbuscpp.integrationtests.conf` file to `/etc/dbus-1/system.d` directory before running the tests?";
} }
TEST(SystemBusConnection, CannotRequestNonregisteredDbusName) TEST(SystemBusConnection, CannotRequestNonregisteredDbusName)
{ {
auto connection = sdbus::createSystemBusConnection(); auto connection = sdbus::createSystemBusConnection();
ASSERT_THROW(connection->requestName("some.random.not.supported.dbus.name"), sdbus::Error); sdbus::ServiceName notSupportedBusName{"some.random.not.supported.dbus.name"};
ASSERT_THROW(connection->requestName(notSupportedBusName), sdbus::Error);
} }
TEST(Connection, CanReleasedRequestedName) TEST(Connection, CanReleaseRequestedName)
{ {
auto connection = sdbus::createBusConnection(); auto connection = sdbus::createBusConnection();
connection->requestName(SERVICE_NAME);
connection->requestName(BUS_NAME); ASSERT_NO_THROW(connection->releaseName(SERVICE_NAME));
ASSERT_NO_THROW(connection->releaseName(BUS_NAME));
} }
TEST(Connection, CannotReleaseNonrequestedName) TEST(Connection, CannotReleaseNonrequestedName)
{ {
auto connection = sdbus::createBusConnection(); auto connection = sdbus::createBusConnection();
ASSERT_THROW(connection->releaseName("some.random.nonrequested.name"), sdbus::Error); sdbus::ServiceName notAcquiredBusName{"some.random.unacquired.name"};
ASSERT_THROW(connection->releaseName(notAcquiredBusName), sdbus::Error);
} }
TEST(Connection, CanEnterAndLeaveInternalEventLoop) TEST(Connection, CanEnterAndLeaveInternalEventLoop)
{ {
auto connection = sdbus::createBusConnection(); auto connection = sdbus::createBusConnection();
connection->requestName(BUS_NAME); connection->requestName(SERVICE_NAME);
std::thread t([&](){ connection->enterEventLoop(); }); std::thread t([&](){ connection->enterEventLoop(); });
connection->leaveEventLoop(); connection->leaveEventLoop();

View File

@ -54,12 +54,12 @@ using ADirectConnection = TestFixtureWithDirectConnection;
TEST(AdaptorAndProxy, CanBeConstructedSuccesfully) TEST(AdaptorAndProxy, CanBeConstructedSuccesfully)
{ {
auto connection = sdbus::createBusConnection(); auto connection = sdbus::createBusConnection();
connection->requestName(BUS_NAME); connection->requestName(SERVICE_NAME);
ASSERT_NO_THROW(TestAdaptor adaptor(*connection, OBJECT_PATH)); ASSERT_NO_THROW(TestAdaptor adaptor(*connection, OBJECT_PATH));
ASSERT_NO_THROW(TestProxy proxy(BUS_NAME, OBJECT_PATH)); ASSERT_NO_THROW(TestProxy proxy(SERVICE_NAME, OBJECT_PATH));
connection->releaseName(BUS_NAME); connection->releaseName(SERVICE_NAME);
} }
TEST(AProxy, SupportsMoveSemantics) TEST(AProxy, SupportsMoveSemantics)
@ -76,7 +76,7 @@ TEST(AnAdaptor, SupportsMoveSemantics)
TYPED_TEST(AConnection, WillCallCallbackHandlerForIncomingMessageMatchingMatchRule) TYPED_TEST(AConnection, WillCallCallbackHandlerForIncomingMessageMatchingMatchRule)
{ {
auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'"; auto matchRule = "sender='" + SERVICE_NAME + "',path='" + OBJECT_PATH + "'";
std::atomic<bool> matchingMessageReceived{false}; std::atomic<bool> matchingMessageReceived{false};
auto slot = this->s_proxyConnection->addMatch(matchRule, [&](sdbus::Message msg) auto slot = this->s_proxyConnection->addMatch(matchRule, [&](sdbus::Message msg)
{ {
@ -91,7 +91,7 @@ TYPED_TEST(AConnection, WillCallCallbackHandlerForIncomingMessageMatchingMatchRu
TYPED_TEST(AConnection, CanInstallMatchRuleAsynchronously) TYPED_TEST(AConnection, CanInstallMatchRuleAsynchronously)
{ {
auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'"; auto matchRule = "sender='" + SERVICE_NAME + "',path='" + OBJECT_PATH + "'";
std::atomic<bool> matchingMessageReceived{false}; std::atomic<bool> matchingMessageReceived{false};
std::atomic<bool> matchRuleInstalled{false}; std::atomic<bool> matchRuleInstalled{false};
auto slot = this->s_proxyConnection->addMatchAsync( matchRule auto slot = this->s_proxyConnection->addMatchAsync( matchRule
@ -114,7 +114,7 @@ TYPED_TEST(AConnection, CanInstallMatchRuleAsynchronously)
TYPED_TEST(AConnection, WillUnsubscribeMatchRuleWhenClientDestroysTheAssociatedSlot) TYPED_TEST(AConnection, WillUnsubscribeMatchRuleWhenClientDestroysTheAssociatedSlot)
{ {
auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'"; auto matchRule = "sender='" + SERVICE_NAME + "',path='" + OBJECT_PATH + "'";
std::atomic<bool> matchingMessageReceived{false}; std::atomic<bool> matchingMessageReceived{false};
auto slot = this->s_proxyConnection->addMatch(matchRule, [&](sdbus::Message msg) auto slot = this->s_proxyConnection->addMatch(matchRule, [&](sdbus::Message msg)
{ {
@ -130,7 +130,7 @@ TYPED_TEST(AConnection, WillUnsubscribeMatchRuleWhenClientDestroysTheAssociatedS
TYPED_TEST(AConnection, CanAddFloatingMatchRule) TYPED_TEST(AConnection, CanAddFloatingMatchRule)
{ {
auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'"; auto matchRule = "sender='" + SERVICE_NAME + "',path='" + OBJECT_PATH + "'";
std::atomic<bool> matchingMessageReceived{false}; std::atomic<bool> matchingMessageReceived{false};
auto con = sdbus::createBusConnection(); auto con = sdbus::createBusConnection();
con->enterEventLoopAsync(); con->enterEventLoopAsync();

View File

@ -231,13 +231,13 @@ TYPED_TEST(SdbusTestObject, FailsCallingMethodOnNonexistentInterface)
TYPED_TEST(SdbusTestObject, FailsCallingMethodOnNonexistentDestination) TYPED_TEST(SdbusTestObject, FailsCallingMethodOnNonexistentDestination)
{ {
TestProxy proxy("sdbuscpp.destination.that.does.not.exist", OBJECT_PATH); TestProxy proxy(sdbus::ServiceName{"sdbuscpp.destination.that.does.not.exist"}, OBJECT_PATH);
ASSERT_THROW(proxy.getInt(), sdbus::Error); ASSERT_THROW(proxy.getInt(), sdbus::Error);
} }
TYPED_TEST(SdbusTestObject, FailsCallingMethodOnNonexistentObject) TYPED_TEST(SdbusTestObject, FailsCallingMethodOnNonexistentObject)
{ {
TestProxy proxy(BUS_NAME, "/sdbuscpp/path/that/does/not/exist"); TestProxy proxy(SERVICE_NAME, sdbus::ObjectPath{"/sdbuscpp/path/that/does/not/exist"});
ASSERT_THROW(proxy.getInt(), sdbus::Error); ASSERT_THROW(proxy.getInt(), sdbus::Error);
} }
@ -254,7 +254,7 @@ TYPED_TEST(SdbusTestObject, CanAccessAssociatedMethodCallMessageInMethodCallHand
this->m_proxy->doOperation(10); // This will save pointer to method call message on server side this->m_proxy->doOperation(10); // This will save pointer to method call message on server side
ASSERT_THAT(this->m_adaptor->m_methodCallMsg, NotNull()); ASSERT_THAT(this->m_adaptor->m_methodCallMsg, NotNull());
ASSERT_THAT(this->m_adaptor->m_methodCallMemberName, Eq("doOperation")); ASSERT_THAT(this->m_adaptor->m_methodName, Eq("doOperation"));
} }
TYPED_TEST(SdbusTestObject, CanAccessAssociatedMethodCallMessageInAsyncMethodCallHandler) TYPED_TEST(SdbusTestObject, CanAccessAssociatedMethodCallMessageInAsyncMethodCallHandler)
@ -262,7 +262,7 @@ TYPED_TEST(SdbusTestObject, CanAccessAssociatedMethodCallMessageInAsyncMethodCal
this->m_proxy->doOperationAsync(10); // This will save pointer to method call message on server side this->m_proxy->doOperationAsync(10); // This will save pointer to method call message on server side
ASSERT_THAT(this->m_adaptor->m_methodCallMsg, NotNull()); ASSERT_THAT(this->m_adaptor->m_methodCallMsg, NotNull());
ASSERT_THAT(this->m_adaptor->m_methodCallMemberName, Eq("doOperationAsync")); ASSERT_THAT(this->m_adaptor->m_methodName, Eq("doOperationAsync"));
} }
#if LIBSYSTEMD_VERSION>=240 #if LIBSYSTEMD_VERSION>=240
@ -281,7 +281,7 @@ TYPED_TEST(SdbusTestObject, CannotSetGeneralMethodTimeoutWithLibsystemdVersionLe
TYPED_TEST(SdbusTestObject, CanCallMethodSynchronouslyWithoutAnEventLoopThread) TYPED_TEST(SdbusTestObject, CanCallMethodSynchronouslyWithoutAnEventLoopThread)
{ {
auto proxy = std::make_unique<TestProxy>(BUS_NAME, OBJECT_PATH, sdbus::dont_run_event_loop_thread); auto proxy = std::make_unique<TestProxy>(SERVICE_NAME, OBJECT_PATH, sdbus::dont_run_event_loop_thread);
auto multiplyRes = proxy->multiply(INT64_VALUE, DOUBLE_VALUE); auto multiplyRes = proxy->multiply(INT64_VALUE, DOUBLE_VALUE);
@ -291,15 +291,16 @@ TYPED_TEST(SdbusTestObject, CanCallMethodSynchronouslyWithoutAnEventLoopThread)
TYPED_TEST(SdbusTestObject, CanRegisterAdditionalVTableDynamicallyAtAnyTime) TYPED_TEST(SdbusTestObject, CanRegisterAdditionalVTableDynamicallyAtAnyTime)
{ {
auto& object = this->m_adaptor->getObject(); auto& object = this->m_adaptor->getObject();
auto vtableSlot = object.addVTable( "org.sdbuscpp.integrationtests2" sdbus::InterfaceName interfaceName{"org.sdbuscpp.integrationtests2"};
auto vtableSlot = object.addVTable( interfaceName
, { sdbus::registerMethod("add").implementedAs([](const int64_t& a, const double& b){ return a + b; }) , { sdbus::registerMethod("add").implementedAs([](const int64_t& a, const double& b){ return a + b; })
, sdbus::registerMethod("subtract").implementedAs([](const int& a, const int& b){ return a - b; }) } , sdbus::registerMethod("subtract").implementedAs([](const int& a, const int& b){ return a - b; }) }
, sdbus::return_slot ); , sdbus::return_slot );
// The new remote vtable is registered as long as we keep vtableSlot, so remote method calls now should pass // The new remote vtable is registered as long as we keep vtableSlot, so remote method calls now should pass
auto proxy = sdbus::createProxy(BUS_NAME, OBJECT_PATH, sdbus::dont_run_event_loop_thread); auto proxy = sdbus::createProxy(SERVICE_NAME, OBJECT_PATH, sdbus::dont_run_event_loop_thread);
int result{}; int result{};
proxy->callMethod("subtract").onInterface("org.sdbuscpp.integrationtests2").withArguments(10, 2).storeResultsTo(result); proxy->callMethod("subtract").onInterface(interfaceName).withArguments(10, 2).storeResultsTo(result);
ASSERT_THAT(result, Eq(8)); ASSERT_THAT(result, Eq(8));
} }
@ -307,14 +308,15 @@ TYPED_TEST(SdbusTestObject, CanRegisterAdditionalVTableDynamicallyAtAnyTime)
TYPED_TEST(SdbusTestObject, CanUnregisterAdditionallyRegisteredVTableAtAnyTime) TYPED_TEST(SdbusTestObject, CanUnregisterAdditionallyRegisteredVTableAtAnyTime)
{ {
auto& object = this->m_adaptor->getObject(); auto& object = this->m_adaptor->getObject();
sdbus::InterfaceName interfaceName{"org.sdbuscpp.integrationtests2"};
auto vtableSlot = object.addVTable( "org.sdbuscpp.integrationtests2" auto vtableSlot = object.addVTable( interfaceName
, { sdbus::registerMethod("add").implementedAs([](const int64_t& a, const double& b){ return a + b; }) , { sdbus::registerMethod("add").implementedAs([](const int64_t& a, const double& b){ return a + b; })
, sdbus::registerMethod("subtract").implementedAs([](const int& a, const int& b){ return a - b; }) } , sdbus::registerMethod("subtract").implementedAs([](const int& a, const int& b){ return a - b; }) }
, sdbus::return_slot ); , sdbus::return_slot );
vtableSlot.reset(); // Letting the slot go means letting go the associated vtable registration vtableSlot.reset(); // Letting the slot go means letting go the associated vtable registration
// No such remote D-Bus method under given interface exists anymore... // No such remote D-Bus method under given interface exists anymore...
auto proxy = sdbus::createProxy(BUS_NAME, OBJECT_PATH, sdbus::dont_run_event_loop_thread); auto proxy = sdbus::createProxy(SERVICE_NAME, OBJECT_PATH, sdbus::dont_run_event_loop_thread);
ASSERT_THROW(proxy->callMethod("subtract").onInterface("org.sdbuscpp.integrationtests2").withArguments(10, 2), sdbus::Error); ASSERT_THROW(proxy->callMethod("subtract").onInterface(interfaceName).withArguments(10, 2), sdbus::Error);
} }

View File

@ -57,8 +57,8 @@ TYPED_TEST(SdbusTestObject, EmitsSimpleSignalSuccesfully)
TYPED_TEST(SdbusTestObject, EmitsSimpleSignalToMultipleProxiesSuccesfully) TYPED_TEST(SdbusTestObject, EmitsSimpleSignalToMultipleProxiesSuccesfully)
{ {
auto proxy1 = std::make_unique<TestProxy>(*this->s_adaptorConnection, BUS_NAME, OBJECT_PATH); auto proxy1 = std::make_unique<TestProxy>(*this->s_adaptorConnection, SERVICE_NAME, OBJECT_PATH);
auto proxy2 = std::make_unique<TestProxy>(*this->s_adaptorConnection, BUS_NAME, OBJECT_PATH); auto proxy2 = std::make_unique<TestProxy>(*this->s_adaptorConnection, SERVICE_NAME, OBJECT_PATH);
this->m_adaptor->emitSimpleSignal(); this->m_adaptor->emitSimpleSignal();
@ -69,7 +69,7 @@ TYPED_TEST(SdbusTestObject, EmitsSimpleSignalToMultipleProxiesSuccesfully)
TYPED_TEST(SdbusTestObject, ProxyDoesNotReceiveSignalFromOtherBusName) TYPED_TEST(SdbusTestObject, ProxyDoesNotReceiveSignalFromOtherBusName)
{ {
auto otherBusName = BUS_NAME + "2"; sdbus::ServiceName otherBusName{SERVICE_NAME + "2"};
auto connection2 = sdbus::createBusConnection(otherBusName); auto connection2 = sdbus::createBusConnection(otherBusName);
auto adaptor2 = std::make_unique<TestAdaptor>(*connection2, OBJECT_PATH); auto adaptor2 = std::make_unique<TestAdaptor>(*connection2, OBJECT_PATH);
@ -110,10 +110,10 @@ TYPED_TEST(SdbusTestObject, EmitsSignalWithVariantSuccesfully)
TYPED_TEST(SdbusTestObject, EmitsSignalWithoutRegistrationSuccesfully) TYPED_TEST(SdbusTestObject, EmitsSignalWithoutRegistrationSuccesfully)
{ {
this->m_adaptor->emitSignalWithoutRegistration({"platform", {"av"}}); this->m_adaptor->emitSignalWithoutRegistration({"platform", sdbus::Signature{"av"}});
ASSERT_TRUE(waitUntil(this->m_proxy->m_gotSignalWithSignature)); ASSERT_TRUE(waitUntil(this->m_proxy->m_gotSignalWithSignature));
ASSERT_THAT(this->m_proxy->m_signatureFromSignal["platform"], Eq("av")); ASSERT_THAT(this->m_proxy->m_signatureFromSignal["platform"], Eq(sdbus::Signature{"av"}));
} }
TYPED_TEST(SdbusTestObject, CanAccessAssociatedSignalMessageInSignalHandler) TYPED_TEST(SdbusTestObject, CanAccessAssociatedSignalMessageInSignalHandler)
@ -123,7 +123,7 @@ TYPED_TEST(SdbusTestObject, CanAccessAssociatedSignalMessageInSignalHandler)
waitUntil(this->m_proxy->m_gotSimpleSignal); waitUntil(this->m_proxy->m_gotSimpleSignal);
ASSERT_THAT(this->m_proxy->m_signalMsg, NotNull()); ASSERT_THAT(this->m_proxy->m_signalMsg, NotNull());
ASSERT_THAT(this->m_proxy->m_signalMemberName, Eq("simpleSignal")); ASSERT_THAT(this->m_proxy->m_signalName, Eq(std::string("simpleSignal")));
} }
TYPED_TEST(SdbusTestObject, UnregistersSignalHandler) TYPED_TEST(SdbusTestObject, UnregistersSignalHandler)
@ -137,8 +137,8 @@ TYPED_TEST(SdbusTestObject, UnregistersSignalHandler)
TYPED_TEST(SdbusTestObject, UnregistersSignalHandlerForSomeProxies) TYPED_TEST(SdbusTestObject, UnregistersSignalHandlerForSomeProxies)
{ {
auto proxy1 = std::make_unique<TestProxy>(*this->s_adaptorConnection, BUS_NAME, OBJECT_PATH); auto proxy1 = std::make_unique<TestProxy>(*this->s_adaptorConnection, SERVICE_NAME, OBJECT_PATH);
auto proxy2 = std::make_unique<TestProxy>(*this->s_adaptorConnection, BUS_NAME, OBJECT_PATH); auto proxy2 = std::make_unique<TestProxy>(*this->s_adaptorConnection, SERVICE_NAME, OBJECT_PATH);
ASSERT_NO_THROW(this->m_proxy->unregisterSimpleSignalHandler()); ASSERT_NO_THROW(this->m_proxy->unregisterSimpleSignalHandler());

View File

@ -142,17 +142,17 @@ TYPED_TEST(SdbusTestObject, GetsAllPropertiesViaPropertiesInterface)
const auto properties = this->m_proxy->GetAll(INTERFACE_NAME); const auto properties = this->m_proxy->GetAll(INTERFACE_NAME);
ASSERT_THAT(properties, SizeIs(3)); ASSERT_THAT(properties, SizeIs(3));
EXPECT_THAT(properties.at("state").template get<std::string>(), Eq(DEFAULT_STATE_VALUE)); EXPECT_THAT(properties.at(STATE_PROPERTY).template get<std::string>(), Eq(DEFAULT_STATE_VALUE));
EXPECT_THAT(properties.at("action").template get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE)); EXPECT_THAT(properties.at(ACTION_PROPERTY).template get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE));
EXPECT_THAT(properties.at("blocking").template get<bool>(), Eq(DEFAULT_BLOCKING_VALUE)); EXPECT_THAT(properties.at(BLOCKING_PROPERTY).template get<bool>(), Eq(DEFAULT_BLOCKING_VALUE));
} }
TYPED_TEST(SdbusTestObject, GetsAllPropertiesAsynchronouslyViaPropertiesInterface) TYPED_TEST(SdbusTestObject, GetsAllPropertiesAsynchronouslyViaPropertiesInterface)
{ {
std::promise<std::map<std::string, sdbus::Variant>> promise; std::promise<std::map<sdbus::PropertyName, sdbus::Variant>> promise;
auto future = promise.get_future(); auto future = promise.get_future();
this->m_proxy->GetAllAsync(INTERFACE_NAME, [&](std::optional<sdbus::Error> err, std::map<std::string, sdbus::Variant> value) this->m_proxy->GetAllAsync(INTERFACE_NAME, [&](std::optional<sdbus::Error> err, std::map<sdbus::PropertyName, sdbus::Variant> value)
{ {
if (!err) if (!err)
promise.set_value(std::move(value)); promise.set_value(std::move(value));
@ -162,9 +162,9 @@ TYPED_TEST(SdbusTestObject, GetsAllPropertiesAsynchronouslyViaPropertiesInterfac
const auto properties = future.get(); const auto properties = future.get();
ASSERT_THAT(properties, SizeIs(3)); ASSERT_THAT(properties, SizeIs(3));
EXPECT_THAT(properties.at("state").get<std::string>(), Eq(DEFAULT_STATE_VALUE)); EXPECT_THAT(properties.at(STATE_PROPERTY).get<std::string>(), Eq(DEFAULT_STATE_VALUE));
EXPECT_THAT(properties.at("action").get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE)); EXPECT_THAT(properties.at(ACTION_PROPERTY).get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE));
EXPECT_THAT(properties.at("blocking").get<bool>(), Eq(DEFAULT_BLOCKING_VALUE)); EXPECT_THAT(properties.at(BLOCKING_PROPERTY).get<bool>(), Eq(DEFAULT_BLOCKING_VALUE));
} }
TYPED_TEST(SdbusTestObject, GetsAllPropertiesAsynchronouslyViaPropertiesInterfaceWithFuture) TYPED_TEST(SdbusTestObject, GetsAllPropertiesAsynchronouslyViaPropertiesInterfaceWithFuture)
@ -174,27 +174,27 @@ TYPED_TEST(SdbusTestObject, GetsAllPropertiesAsynchronouslyViaPropertiesInterfac
auto properties = future.get(); auto properties = future.get();
ASSERT_THAT(properties, SizeIs(3)); ASSERT_THAT(properties, SizeIs(3));
EXPECT_THAT(properties.at("state").template get<std::string>(), Eq(DEFAULT_STATE_VALUE)); EXPECT_THAT(properties.at(STATE_PROPERTY).template get<std::string>(), Eq(DEFAULT_STATE_VALUE));
EXPECT_THAT(properties.at("action").template get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE)); EXPECT_THAT(properties.at(ACTION_PROPERTY).template get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE));
EXPECT_THAT(properties.at("blocking").template get<bool>(), Eq(DEFAULT_BLOCKING_VALUE)); EXPECT_THAT(properties.at(BLOCKING_PROPERTY).template get<bool>(), Eq(DEFAULT_BLOCKING_VALUE));
} }
TYPED_TEST(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties) TYPED_TEST(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties)
{ {
std::atomic<bool> signalReceived{false}; std::atomic<bool> signalReceived{false};
this->m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName this->m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const sdbus::InterfaceName& interfaceName
, const std::map<std::string, sdbus::Variant>& changedProperties , const std::map<sdbus::PropertyName, sdbus::Variant>& changedProperties
, const std::vector<std::string>& /*invalidatedProperties*/ ) , const std::vector<sdbus::PropertyName>& /*invalidatedProperties*/ )
{ {
EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME)); EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME));
EXPECT_THAT(changedProperties, SizeIs(1)); EXPECT_THAT(changedProperties, SizeIs(1));
EXPECT_THAT(changedProperties.at("blocking").get<bool>(), Eq(!DEFAULT_BLOCKING_VALUE)); EXPECT_THAT(changedProperties.at(BLOCKING_PROPERTY).get<bool>(), Eq(!DEFAULT_BLOCKING_VALUE));
signalReceived = true; signalReceived = true;
}; };
this->m_proxy->blocking(!DEFAULT_BLOCKING_VALUE); this->m_proxy->blocking(!DEFAULT_BLOCKING_VALUE);
this->m_proxy->action(DEFAULT_ACTION_VALUE*2); this->m_proxy->action(DEFAULT_ACTION_VALUE*2);
this->m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME, {"blocking"}); this->m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME, {BLOCKING_PROPERTY});
ASSERT_TRUE(waitUntil(signalReceived)); ASSERT_TRUE(waitUntil(signalReceived));
} }
@ -202,13 +202,13 @@ TYPED_TEST(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties)
TYPED_TEST(SdbusTestObject, EmitsPropertyChangedSignalForAllProperties) TYPED_TEST(SdbusTestObject, EmitsPropertyChangedSignalForAllProperties)
{ {
std::atomic<bool> signalReceived{false}; std::atomic<bool> signalReceived{false};
this->m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName this->m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const sdbus::InterfaceName& interfaceName
, const std::map<std::string, sdbus::Variant>& changedProperties , const std::map<sdbus::PropertyName, sdbus::Variant>& changedProperties
, const std::vector<std::string>& invalidatedProperties ) , const std::vector<sdbus::PropertyName>& invalidatedProperties )
{ {
EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME)); EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME));
EXPECT_THAT(changedProperties, SizeIs(1)); EXPECT_THAT(changedProperties, SizeIs(1));
EXPECT_THAT(changedProperties.at("blocking").get<bool>(), Eq(DEFAULT_BLOCKING_VALUE)); EXPECT_THAT(changedProperties.at(BLOCKING_PROPERTY).get<bool>(), Eq(DEFAULT_BLOCKING_VALUE));
ASSERT_THAT(invalidatedProperties, SizeIs(1)); ASSERT_THAT(invalidatedProperties, SizeIs(1));
EXPECT_THAT(invalidatedProperties[0], Eq("action")); EXPECT_THAT(invalidatedProperties[0], Eq("action"));
signalReceived = true; signalReceived = true;
@ -235,17 +235,17 @@ TYPED_TEST(SdbusTestObject, GetsManagedObjectsSuccessfully)
ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(2)); ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(2));
EXPECT_THAT(objectsInterfacesAndProperties.at(OBJECT_PATH) EXPECT_THAT(objectsInterfacesAndProperties.at(OBJECT_PATH)
.at(org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME) .at(org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME)
.at("action").template get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE)); .at(ACTION_PROPERTY).template get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE));
EXPECT_THAT(objectsInterfacesAndProperties.at(OBJECT_PATH_2) EXPECT_THAT(objectsInterfacesAndProperties.at(OBJECT_PATH_2)
.at(org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME) .at(org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME)
.at("action").template get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE)); .at(ACTION_PROPERTY).template get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE));
} }
TYPED_TEST(SdbusTestObject, EmitsInterfacesAddedSignalForSelectedObjectInterfaces) TYPED_TEST(SdbusTestObject, EmitsInterfacesAddedSignalForSelectedObjectInterfaces)
{ {
std::atomic<bool> signalReceived{false}; std::atomic<bool> signalReceived{false};
this->m_objectManagerProxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath this->m_objectManagerProxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath
, const std::map<std::string, std::map<std::string, sdbus::Variant>>& interfacesAndProperties ) , const std::map<sdbus::InterfaceName, std::map<sdbus::PropertyName, sdbus::Variant>>& interfacesAndProperties )
{ {
EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); EXPECT_THAT(objectPath, Eq(OBJECT_PATH));
EXPECT_THAT(interfacesAndProperties, SizeIs(1)); EXPECT_THAT(interfacesAndProperties, SizeIs(1));
@ -253,16 +253,16 @@ TYPED_TEST(SdbusTestObject, EmitsInterfacesAddedSignalForSelectedObjectInterface
#if LIBSYSTEMD_VERSION<=244 #if LIBSYSTEMD_VERSION<=244
// Up to sd-bus v244, all properties are added to the list, i.e. `state', `action', and `blocking' in this case. // Up to sd-bus v244, all properties are added to the list, i.e. `state', `action', and `blocking' in this case.
EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3)); EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("state")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(STATE_PROPERTY));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("action")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(ACTION_PROPERTY));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("blocking")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(BLOCKING_PROPERTY));
#else #else
// Since v245 sd-bus does not add to the InterfacesAdded signal message the values of properties marked only // Since v245 sd-bus does not add to the InterfacesAdded signal message the values of properties marked only
// for invalidation on change, which makes the behavior consistent with the PropertiesChangedSignal. // for invalidation on change, which makes the behavior consistent with the PropertiesChangedSignal.
// So in this specific instance, `action' property is no more added to the list. // So in this specific instance, `action' property is no more added to the list.
EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(2)); EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(2));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("state")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(STATE_PROPERTY));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("blocking")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(BLOCKING_PROPERTY));
#endif #endif
signalReceived = true; signalReceived = true;
}; };
@ -276,7 +276,7 @@ TYPED_TEST(SdbusTestObject, EmitsInterfacesAddedSignalForAllObjectInterfaces)
{ {
std::atomic<bool> signalReceived{false}; std::atomic<bool> signalReceived{false};
this->m_objectManagerProxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath this->m_objectManagerProxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath
, const std::map<std::string, std::map<std::string, sdbus::Variant>>& interfacesAndProperties ) , const std::map<sdbus::InterfaceName, std::map<sdbus::PropertyName, sdbus::Variant>>& interfacesAndProperties )
{ {
EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); EXPECT_THAT(objectPath, Eq(OBJECT_PATH));
#if LIBSYSTEMD_VERSION<=250 #if LIBSYSTEMD_VERSION<=250
@ -289,16 +289,16 @@ TYPED_TEST(SdbusTestObject, EmitsInterfacesAddedSignalForAllObjectInterfaces)
#if LIBSYSTEMD_VERSION<=244 #if LIBSYSTEMD_VERSION<=244
// Up to sd-bus v244, all properties are added to the list, i.e. `state', `action', and `blocking' in this case. // Up to sd-bus v244, all properties are added to the list, i.e. `state', `action', and `blocking' in this case.
EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3)); EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("state")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(STATE_PROPERTY));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("action")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(ACTION_PROPERTY));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("blocking")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(BLOCKING_PROPERTY));
#else #else
// Since v245 sd-bus does not add to the InterfacesAdded signal message the values of properties marked only // Since v245 sd-bus does not add to the InterfacesAdded signal message the values of properties marked only
// for invalidation on change, which makes the behavior consistent with the PropertiesChangedSignal. // for invalidation on change, which makes the behavior consistent with the PropertiesChangedSignal.
// So in this specific instance, `action' property is no more added to the list. // So in this specific instance, `action' property is no more added to the list.
EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(2)); EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(2));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("state")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(STATE_PROPERTY));
EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count("blocking")); EXPECT_TRUE(interfacesAndProperties.at(INTERFACE_NAME).count(BLOCKING_PROPERTY));
#endif #endif
signalReceived = true; signalReceived = true;
}; };
@ -312,7 +312,7 @@ TYPED_TEST(SdbusTestObject, EmitsInterfacesRemovedSignalForSelectedObjectInterfa
{ {
std::atomic<bool> signalReceived{false}; std::atomic<bool> signalReceived{false};
this->m_objectManagerProxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath this->m_objectManagerProxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath
, const std::vector<std::string>& interfaces ) , const std::vector<sdbus::InterfaceName>& interfaces )
{ {
EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); EXPECT_THAT(objectPath, Eq(OBJECT_PATH));
ASSERT_THAT(interfaces, SizeIs(1)); ASSERT_THAT(interfaces, SizeIs(1));
@ -329,7 +329,7 @@ TYPED_TEST(SdbusTestObject, EmitsInterfacesRemovedSignalForAllObjectInterfaces)
{ {
std::atomic<bool> signalReceived{false}; std::atomic<bool> signalReceived{false};
this->m_objectManagerProxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath this->m_objectManagerProxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath
, const std::vector<std::string>& interfaces ) , const std::vector<sdbus::InterfaceName>& interfaces )
{ {
EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); EXPECT_THAT(objectPath, Eq(OBJECT_PATH));
#if LIBSYSTEMD_VERSION<=250 #if LIBSYSTEMD_VERSION<=250

View File

@ -34,12 +34,15 @@
namespace sdbus { namespace test { namespace sdbus { namespace test {
const std::string INTERFACE_NAME{"org.sdbuscpp.integrationtests"}; const InterfaceName INTERFACE_NAME{"org.sdbuscpp.integrationtests"};
const std::string BUS_NAME = INTERFACE_NAME; const ServiceName SERVICE_NAME{"org.sdbuscpp.integrationtests"};
const std::string EMPTY_DESTINATION; const ServiceName EMPTY_DESTINATION;
const std::string MANAGER_PATH {"/org/sdbuscpp/integrationtests"}; const ObjectPath MANAGER_PATH {"/org/sdbuscpp/integrationtests"};
const std::string OBJECT_PATH {"/org/sdbuscpp/integrationtests/ObjectA1"}; const ObjectPath OBJECT_PATH {"/org/sdbuscpp/integrationtests/ObjectA1"};
const std::string OBJECT_PATH_2{"/org/sdbuscpp/integrationtests/ObjectB1"}; const ObjectPath OBJECT_PATH_2{"/org/sdbuscpp/integrationtests/ObjectB1"};
const PropertyName STATE_PROPERTY{"state"};
const PropertyName ACTION_PROPERTY{"action"};
const PropertyName BLOCKING_PROPERTY{"blocking"};
const std::string DIRECT_CONNECTION_SOCKET_PATH{std::filesystem::temp_directory_path() / "sdbus-cpp-direct-connection-test"}; const std::string DIRECT_CONNECTION_SOCKET_PATH{std::filesystem::temp_directory_path() / "sdbus-cpp-direct-connection-test"};
constexpr const uint8_t UINT8_VALUE{1}; constexpr const uint8_t UINT8_VALUE{1};
@ -49,8 +52,8 @@ constexpr const int32_t INT32_VALUE{-42};
constexpr const int32_t INT64_VALUE{-1024}; constexpr const int32_t INT64_VALUE{-1024};
const std::string STRING_VALUE{"sdbus-c++-testing"}; const std::string STRING_VALUE{"sdbus-c++-testing"};
const sdbus::Signature SIGNATURE_VALUE{"a{is}"}; const Signature SIGNATURE_VALUE{"a{is}"};
const sdbus::ObjectPath OBJECT_PATH_VALUE{"/"}; const ObjectPath OBJECT_PATH_VALUE{"/"};
const int UNIX_FD_VALUE = 0; const int UNIX_FD_VALUE = 0;
const std::string DEFAULT_STATE_VALUE{"default-state-value"}; const std::string DEFAULT_STATE_VALUE{"default-state-value"};

View File

@ -31,8 +31,8 @@
namespace sdbus { namespace test { namespace sdbus { namespace test {
TestAdaptor::TestAdaptor(sdbus::IConnection& connection, const std::string& path) : TestAdaptor::TestAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath path) :
AdaptorInterfaces(connection, path) AdaptorInterfaces(connection, std::move(path))
{ {
registerAdaptor(); registerAdaptor();
} }
@ -123,7 +123,7 @@ uint32_t TestAdaptor::doOperation(const uint32_t& param)
std::this_thread::sleep_for(std::chrono::milliseconds(param)); std::this_thread::sleep_for(std::chrono::milliseconds(param));
m_methodCallMsg = std::make_unique<const Message>(getObject().getCurrentlyProcessedMessage()); m_methodCallMsg = std::make_unique<const Message>(getObject().getCurrentlyProcessedMessage());
m_methodCallMemberName = m_methodCallMsg->getMemberName(); m_methodName = m_methodCallMsg->getMemberName();
return param; return param;
} }
@ -131,7 +131,7 @@ uint32_t TestAdaptor::doOperation(const uint32_t& param)
void TestAdaptor::doOperationAsync(sdbus::Result<uint32_t>&& result, uint32_t param) void TestAdaptor::doOperationAsync(sdbus::Result<uint32_t>&& result, uint32_t param)
{ {
m_methodCallMsg = std::make_unique<const Message>(getObject().getCurrentlyProcessedMessage()); m_methodCallMsg = std::make_unique<const Message>(getObject().getCurrentlyProcessedMessage());
m_methodCallMemberName = m_methodCallMsg->getMemberName(); m_methodName = m_methodCallMsg->getMemberName();
if (param == 0) if (param == 0)
{ {
@ -173,7 +173,7 @@ std::unordered_map<uint64_t, sdbus::Struct<std::map<uint8_t, std::vector<sdbus::
23, // uint8_t 23, // uint8_t
{ // vector { // vector
{ // struct { // struct
"/object/path", // object path sdbus::ObjectPath{"/object/path"}, // object path
false, false,
Variant{3.14}, Variant{3.14},
{ // map { // map
@ -183,7 +183,7 @@ std::unordered_map<uint64_t, sdbus::Struct<std::map<uint8_t, std::vector<sdbus::
} }
} }
}, },
"a{t(a{ya(obva{is})}gs)}", // signature sdbus::Signature{"a{t(a{ya(obva{is})}gs)}"}, // signature
std::string{} std::string{}
} }
} }

View File

@ -40,7 +40,7 @@ namespace sdbus { namespace test {
class ObjectManagerTestAdaptor final : public sdbus::AdaptorInterfaces< sdbus::ObjectManager_adaptor > class ObjectManagerTestAdaptor final : public sdbus::AdaptorInterfaces< sdbus::ObjectManager_adaptor >
{ {
public: public:
ObjectManagerTestAdaptor(sdbus::IConnection& connection, std::string path) : ObjectManagerTestAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath path) :
AdaptorInterfaces(connection, std::move(path)) AdaptorInterfaces(connection, std::move(path))
{ {
registerAdaptor(); registerAdaptor();
@ -57,7 +57,7 @@ class TestAdaptor final : public sdbus::AdaptorInterfaces< org::sdbuscpp::integr
, sdbus::ManagedObject_adaptor > , sdbus::ManagedObject_adaptor >
{ {
public: public:
TestAdaptor(sdbus::IConnection& connection, const std::string& path); TestAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath path);
~TestAdaptor(); ~TestAdaptor();
protected: protected:
@ -105,7 +105,7 @@ public: // for tests
mutable std::atomic<bool> m_wasThrowErrorCalled{false}; mutable std::atomic<bool> m_wasThrowErrorCalled{false};
std::unique_ptr<const Message> m_methodCallMsg; std::unique_ptr<const Message> m_methodCallMsg;
std::string m_methodCallMemberName; MethodName m_methodName;
std::unique_ptr<const Message> m_propertySetMsg; std::unique_ptr<const Message> m_propertySetMsg;
std::string m_propertySetSender; std::string m_propertySetSender;
}; };
@ -115,7 +115,9 @@ class DummyTestAdaptor final : public sdbus::AdaptorInterfaces< org::sdbuscpp::i
, sdbus::ManagedObject_adaptor > , sdbus::ManagedObject_adaptor >
{ {
public: public:
DummyTestAdaptor(sdbus::IConnection& connection, const std::string& path) : AdaptorInterfaces(connection, path) {} DummyTestAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath path)
: AdaptorInterfaces(connection, std::move(path))
{}
protected: protected:
void noArgNoReturn() override {} void noArgNoReturn() override {}

View File

@ -55,19 +55,19 @@ class BaseTestFixture : public ::testing::Test
public: public:
static void SetUpTestCase() static void SetUpTestCase()
{ {
s_adaptorConnection->requestName(BUS_NAME); s_adaptorConnection->requestName(SERVICE_NAME);
} }
static void TearDownTestCase() static void TearDownTestCase()
{ {
s_adaptorConnection->releaseName(BUS_NAME); s_adaptorConnection->releaseName(SERVICE_NAME);
} }
private: private:
void SetUp() override void SetUp() override
{ {
m_objectManagerProxy = std::make_unique<ObjectManagerTestProxy>(*s_proxyConnection, BUS_NAME, MANAGER_PATH); m_objectManagerProxy = std::make_unique<ObjectManagerTestProxy>(*s_proxyConnection, SERVICE_NAME, MANAGER_PATH);
m_proxy = std::make_unique<TestProxy>(*s_proxyConnection, BUS_NAME, OBJECT_PATH); m_proxy = std::make_unique<TestProxy>(*s_proxyConnection, SERVICE_NAME, OBJECT_PATH);
m_objectManagerAdaptor = std::make_unique<ObjectManagerTestAdaptor>(*s_adaptorConnection, MANAGER_PATH); m_objectManagerAdaptor = std::make_unique<ObjectManagerTestAdaptor>(*s_adaptorConnection, MANAGER_PATH);
m_adaptor = std::make_unique<TestAdaptor>(*s_adaptorConnection, OBJECT_PATH); m_adaptor = std::make_unique<TestAdaptor>(*s_adaptorConnection, OBJECT_PATH);

View File

@ -31,7 +31,7 @@
namespace sdbus { namespace test { namespace sdbus { namespace test {
TestProxy::TestProxy(std::string destination, std::string objectPath) TestProxy::TestProxy(ServiceName destination, ObjectPath objectPath)
: ProxyInterfaces(std::move(destination), std::move(objectPath)) : ProxyInterfaces(std::move(destination), std::move(objectPath))
{ {
getProxy().uponSignal("signalWithoutRegistration").onInterface(sdbus::test::INTERFACE_NAME).call([this](const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s){ this->onSignalWithoutRegistration(s); }); getProxy().uponSignal("signalWithoutRegistration").onInterface(sdbus::test::INTERFACE_NAME).call([this](const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s){ this->onSignalWithoutRegistration(s); });
@ -39,14 +39,14 @@ TestProxy::TestProxy(std::string destination, std::string objectPath)
registerProxy(); registerProxy();
} }
TestProxy::TestProxy(std::string destination, std::string objectPath, dont_run_event_loop_thread_t) TestProxy::TestProxy(ServiceName destination, ObjectPath objectPath, dont_run_event_loop_thread_t)
: ProxyInterfaces(std::move(destination), std::move(objectPath), dont_run_event_loop_thread) : ProxyInterfaces(std::move(destination), std::move(objectPath), dont_run_event_loop_thread)
{ {
// It doesn't make sense to register any signals here since proxy upon a D-Bus connection with no event loop thread // It doesn't make sense to register any signals here since proxy upon a D-Bus connection with no event loop thread
// will not receive any incoming messages except replies to synchronous D-Bus calls. // will not receive any incoming messages except replies to synchronous D-Bus calls.
} }
TestProxy::TestProxy(sdbus::IConnection& connection, std::string destination, std::string objectPath) TestProxy::TestProxy(sdbus::IConnection& connection, ServiceName destination, ObjectPath objectPath)
: ProxyInterfaces(connection, std::move(destination), std::move(objectPath)) : ProxyInterfaces(connection, std::move(destination), std::move(objectPath))
{ {
getProxy().uponSignal("signalWithoutRegistration").onInterface(sdbus::test::INTERFACE_NAME).call([this](const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s){ this->onSignalWithoutRegistration(s); }); getProxy().uponSignal("signalWithoutRegistration").onInterface(sdbus::test::INTERFACE_NAME).call([this](const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s){ this->onSignalWithoutRegistration(s); });
@ -62,7 +62,7 @@ TestProxy::~TestProxy()
void TestProxy::onSimpleSignal() void TestProxy::onSimpleSignal()
{ {
m_signalMsg = std::make_unique<sdbus::Message>(getProxy().getCurrentlyProcessedMessage()); m_signalMsg = std::make_unique<sdbus::Message>(getProxy().getCurrentlyProcessedMessage());
m_signalMemberName = m_signalMsg->getMemberName(); m_signalName = m_signalMsg->getMemberName();
m_gotSimpleSignal = true; m_gotSimpleSignal = true;
} }
@ -81,6 +81,7 @@ void TestProxy::onSignalWithVariant(const sdbus::Variant& aVariant)
void TestProxy::onSignalWithoutRegistration(const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s) void TestProxy::onSignalWithoutRegistration(const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s)
{ {
// Static cast to std::string is a workaround for gcc 11.4 false positive warning (which later gcc versions nor Clang emit)
m_signatureFromSignal[std::get<0>(s)] = static_cast<std::string>(std::get<0>(std::get<1>(s))); m_signatureFromSignal[std::get<0>(s)] = static_cast<std::string>(std::get<0>(std::get<1>(s)));
m_gotSignalWithSignature = true; m_gotSignalWithSignature = true;
} }
@ -91,9 +92,9 @@ void TestProxy::onDoOperationReply(uint32_t returnValue, std::optional<sdbus::Er
m_DoOperationClientSideAsyncReplyHandler(returnValue, error); m_DoOperationClientSideAsyncReplyHandler(returnValue, error);
} }
void TestProxy::onPropertiesChanged( const std::string& interfaceName void TestProxy::onPropertiesChanged( const sdbus::InterfaceName& interfaceName
, const std::map<std::string, sdbus::Variant>& changedProperties , const std::map<PropertyName, sdbus::Variant>& changedProperties
, const std::vector<std::string>& invalidatedProperties ) , const std::vector<PropertyName>& invalidatedProperties )
{ {
if (m_onPropertiesChangedHandler) if (m_onPropertiesChangedHandler)
m_onPropertiesChangedHandler(interfaceName, changedProperties, invalidatedProperties); m_onPropertiesChangedHandler(interfaceName, changedProperties, invalidatedProperties);
@ -133,7 +134,7 @@ std::future<uint32_t> TestProxy::doOperationClientSideAsync(uint32_t param, with
std::future<MethodReply> TestProxy::doOperationClientSideAsyncOnBasicAPILevel(uint32_t param) std::future<MethodReply> TestProxy::doOperationClientSideAsyncOnBasicAPILevel(uint32_t param)
{ {
auto methodCall = getProxy().createMethodCall(sdbus::test::INTERFACE_NAME, "doOperation"); auto methodCall = getProxy().createMethodCall(sdbus::test::INTERFACE_NAME, sdbus::MethodName{"doOperation"});
methodCall << param; methodCall << param;
return getProxy().callMethodAsync(methodCall, sdbus::with_future); return getProxy().callMethodAsync(methodCall, sdbus::with_future);
@ -178,8 +179,9 @@ int32_t TestProxy::callNonexistentMethod()
int32_t TestProxy::callMethodOnNonexistentInterface() int32_t TestProxy::callMethodOnNonexistentInterface()
{ {
sdbus::InterfaceName nonexistentInterfaceName{"sdbuscpp.interface.that.does.not.exist"};
int32_t result; int32_t result;
getProxy().callMethod("someMethod").onInterface("sdbuscpp.interface.that.does.not.exist").storeResultsTo(result); getProxy().callMethod("someMethod").onInterface(nonexistentInterfaceName).storeResultsTo(result);
return result; return result;
} }

View File

@ -40,7 +40,7 @@ namespace sdbus { namespace test {
class ObjectManagerTestProxy final : public sdbus::ProxyInterfaces< sdbus::ObjectManager_proxy > class ObjectManagerTestProxy final : public sdbus::ProxyInterfaces< sdbus::ObjectManager_proxy >
{ {
public: public:
ObjectManagerTestProxy(sdbus::IConnection& connection, std::string destination, std::string objectPath) ObjectManagerTestProxy(sdbus::IConnection& connection, ServiceName destination, ObjectPath objectPath)
: ProxyInterfaces(connection, std::move(destination), std::move(objectPath)) : ProxyInterfaces(connection, std::move(destination), std::move(objectPath))
{ {
registerProxy(); registerProxy();
@ -51,21 +51,21 @@ public:
unregisterProxy(); unregisterProxy();
} }
protected: protected:
void onInterfacesAdded(const sdbus::ObjectPath& objectPath, const std::map<std::string, std::map<std::string, sdbus::Variant>>& interfacesAndProperties) override void onInterfacesAdded(const sdbus::ObjectPath& objectPath, const std::map<sdbus::InterfaceName, std::map<PropertyName, sdbus::Variant>>& interfacesAndProperties) override
{ {
if (m_onInterfacesAddedHandler) if (m_onInterfacesAddedHandler)
m_onInterfacesAddedHandler(objectPath, interfacesAndProperties); m_onInterfacesAddedHandler(objectPath, interfacesAndProperties);
} }
void onInterfacesRemoved(const sdbus::ObjectPath& objectPath, const std::vector<std::string>& interfaces) override void onInterfacesRemoved(const sdbus::ObjectPath& objectPath, const std::vector<sdbus::InterfaceName>& interfaces) override
{ {
if (m_onInterfacesRemovedHandler) if (m_onInterfacesRemovedHandler)
m_onInterfacesRemovedHandler(objectPath, interfaces); m_onInterfacesRemovedHandler(objectPath, interfaces);
} }
public: // for tests public: // for tests
std::function<void(const sdbus::ObjectPath&, const std::map<std::string, std::map<std::string, sdbus::Variant>>&)> m_onInterfacesAddedHandler; std::function<void(const sdbus::ObjectPath&, const std::map<sdbus::InterfaceName, std::map<PropertyName, sdbus::Variant>>&)> m_onInterfacesAddedHandler;
std::function<void(const sdbus::ObjectPath&, const std::vector<std::string>&)> m_onInterfacesRemovedHandler; std::function<void(const sdbus::ObjectPath&, const std::vector<sdbus::InterfaceName>&)> m_onInterfacesRemovedHandler;
}; };
class TestProxy final : public sdbus::ProxyInterfaces< org::sdbuscpp::integrationtests_proxy class TestProxy final : public sdbus::ProxyInterfaces< org::sdbuscpp::integrationtests_proxy
@ -74,9 +74,9 @@ class TestProxy final : public sdbus::ProxyInterfaces< org::sdbuscpp::integratio
, sdbus::Properties_proxy > , sdbus::Properties_proxy >
{ {
public: public:
TestProxy(std::string destination, std::string objectPath); TestProxy(ServiceName destination, ObjectPath objectPath);
TestProxy(std::string destination, std::string objectPath, dont_run_event_loop_thread_t); TestProxy(ServiceName destination, ObjectPath objectPath, dont_run_event_loop_thread_t);
TestProxy(sdbus::IConnection& connection, std::string destination, std::string objectPath); TestProxy(sdbus::IConnection& connection, ServiceName destination, ObjectPath objectPath);
~TestProxy(); ~TestProxy();
protected: protected:
@ -88,9 +88,9 @@ protected:
void onDoOperationReply(uint32_t returnValue, std::optional<sdbus::Error> error); void onDoOperationReply(uint32_t returnValue, std::optional<sdbus::Error> error);
// Signals of standard D-Bus interfaces // Signals of standard D-Bus interfaces
void onPropertiesChanged( const std::string& interfaceName void onPropertiesChanged( const sdbus::InterfaceName& interfaceName
, const std::map<std::string, sdbus::Variant>& changedProperties , const std::map<PropertyName, sdbus::Variant>& changedProperties
, const std::vector<std::string>& invalidatedProperties ) override; , const std::vector<PropertyName>& invalidatedProperties ) override;
public: public:
void installDoOperationClientSideAsyncReplyHandler(std::function<void(uint32_t res, std::optional<sdbus::Error> err)> handler); void installDoOperationClientSideAsyncReplyHandler(std::function<void(uint32_t res, std::optional<sdbus::Error> err)> handler);
@ -114,13 +114,13 @@ public: // for tests
std::atomic<bool> m_gotSignalWithVariant{false}; std::atomic<bool> m_gotSignalWithVariant{false};
double m_variantFromSignal; double m_variantFromSignal;
std::atomic<bool> m_gotSignalWithSignature{false}; std::atomic<bool> m_gotSignalWithSignature{false};
std::map<std::string, std::string> m_signatureFromSignal; std::map<std::string, Signature> m_signatureFromSignal;
std::function<void(uint32_t res, std::optional<sdbus::Error> err)> m_DoOperationClientSideAsyncReplyHandler; std::function<void(uint32_t res, std::optional<sdbus::Error> err)> m_DoOperationClientSideAsyncReplyHandler;
std::function<void(const std::string&, const std::map<std::string, sdbus::Variant>&, const std::vector<std::string>&)> m_onPropertiesChangedHandler; std::function<void(const sdbus::InterfaceName&, const std::map<PropertyName, sdbus::Variant>&, const std::vector<PropertyName>&)> m_onPropertiesChangedHandler;
std::unique_ptr<const Message> m_signalMsg; std::unique_ptr<const Message> m_signalMsg;
std::string m_signalMemberName; SignalName m_signalName;
}; };
class DummyTestProxy final : public sdbus::ProxyInterfaces< org::sdbuscpp::integrationtests_proxy class DummyTestProxy final : public sdbus::ProxyInterfaces< org::sdbuscpp::integrationtests_proxy
@ -129,7 +129,7 @@ class DummyTestProxy final : public sdbus::ProxyInterfaces< org::sdbuscpp::integ
, sdbus::Properties_proxy > , sdbus::Properties_proxy >
{ {
public: public:
DummyTestProxy(std::string destination, std::string objectPath) DummyTestProxy(ServiceName destination, ObjectPath objectPath)
: ProxyInterfaces(destination, objectPath) : ProxyInterfaces(destination, objectPath)
{ {
} }
@ -143,7 +143,7 @@ protected:
void onDoOperationReply(uint32_t, std::optional<sdbus::Error>) {} void onDoOperationReply(uint32_t, std::optional<sdbus::Error>) {}
// Signals of standard D-Bus interfaces // Signals of standard D-Bus interfaces
void onPropertiesChanged( const std::string&, const std::map<std::string, sdbus::Variant>&, const std::vector<std::string>& ) override {} void onPropertiesChanged(const InterfaceName&, const std::map<PropertyName, sdbus::Variant>&, const std::vector<PropertyName>&) override {}
}; };
}} }}

View File

@ -16,7 +16,7 @@ namespace sdbuscpp {
class integrationtests_adaptor class integrationtests_adaptor
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.integrationtests"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.integrationtests"};
protected: protected:
integrationtests_adaptor(sdbus::IObject& object) integrationtests_adaptor(sdbus::IObject& object)

View File

@ -16,7 +16,7 @@ namespace sdbuscpp {
class integrationtests_proxy class integrationtests_proxy
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.integrationtests"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.integrationtests"};
protected: protected:
integrationtests_proxy(sdbus::IProxy& proxy) integrationtests_proxy(sdbus::IProxy& proxy)

View File

@ -43,7 +43,7 @@ uint64_t totalDuration = 0;
class PerftestProxy final : public sdbus::ProxyInterfaces<org::sdbuscpp::perftests_proxy> class PerftestProxy final : public sdbus::ProxyInterfaces<org::sdbuscpp::perftests_proxy>
{ {
public: public:
PerftestProxy(std::string destination, std::string objectPath) PerftestProxy(sdbus::ServiceName destination, sdbus::ObjectPath objectPath)
: ProxyInterfaces(std::move(destination), std::move(objectPath)) : ProxyInterfaces(std::move(destination), std::move(objectPath))
{ {
registerProxy(); registerProxy();
@ -101,9 +101,9 @@ std::string createRandomString(size_t length)
//----------------------------------------- //-----------------------------------------
int main(int /*argc*/, char */*argv*/[]) int main(int /*argc*/, char */*argv*/[])
{ {
const char* destinationName = "org.sdbuscpp.perftests"; sdbus::ServiceName destination{"org.sdbuscpp.perftests"};
const char* objectPath = "/org/sdbuscpp/perftests"; sdbus::ObjectPath objectPath{"/org/sdbuscpp/perftests"};
PerftestProxy client(destinationName, objectPath); PerftestProxy client(std::move(destination), std::move(objectPath));
const unsigned int repetitions{20}; const unsigned int repetitions{20};
unsigned int msgCount = 1000; unsigned int msgCount = 1000;

View File

@ -16,7 +16,7 @@ namespace sdbuscpp {
class perftests_adaptor class perftests_adaptor
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.perftests"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.perftests"};
protected: protected:
perftests_adaptor(sdbus::IObject& object) perftests_adaptor(sdbus::IObject& object)

View File

@ -16,7 +16,7 @@ namespace sdbuscpp {
class perftests_proxy class perftests_proxy
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.perftests"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.perftests"};
protected: protected:
perftests_proxy(sdbus::IProxy& proxy) perftests_proxy(sdbus::IProxy& proxy)

View File

@ -40,7 +40,7 @@ std::string createRandomString(size_t length);
class PerftestAdaptor final : public sdbus::AdaptorInterfaces<org::sdbuscpp::perftests_adaptor> class PerftestAdaptor final : public sdbus::AdaptorInterfaces<org::sdbuscpp::perftests_adaptor>
{ {
public: public:
PerftestAdaptor(sdbus::IConnection& connection, std::string objectPath) PerftestAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath objectPath)
: AdaptorInterfaces(connection, std::move(objectPath)) : AdaptorInterfaces(connection, std::move(objectPath))
{ {
registerAdaptor(); registerAdaptor();
@ -92,11 +92,11 @@ std::string createRandomString(size_t length)
//----------------------------------------- //-----------------------------------------
int main(int /*argc*/, char */*argv*/[]) int main(int /*argc*/, char */*argv*/[])
{ {
const char* serviceName = "org.sdbuscpp.perftests"; sdbus::ServiceName serviceName{"org.sdbuscpp.perftests"};
auto connection = sdbus::createSystemBusConnection(serviceName); auto connection = sdbus::createSystemBusConnection(serviceName);
const char* objectPath = "/org/sdbuscpp/perftests"; sdbus::ObjectPath objectPath{"/org/sdbuscpp/perftests"};
PerftestAdaptor server(*connection, objectPath); PerftestAdaptor server(*connection, std::move(objectPath));
connection->enterEventLoop(); connection->enterEventLoop();
} }

View File

@ -18,7 +18,7 @@ namespace celsius {
class thermometer_adaptor class thermometer_adaptor
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.celsius.thermometer"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.celsius.thermometer"};
protected: protected:
thermometer_adaptor(sdbus::IObject& object) thermometer_adaptor(sdbus::IObject& object)

View File

@ -18,7 +18,7 @@ namespace celsius {
class thermometer_proxy class thermometer_proxy
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.celsius.thermometer"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.celsius.thermometer"};
protected: protected:
thermometer_proxy(sdbus::IProxy& proxy) thermometer_proxy(sdbus::IProxy& proxy)

View File

@ -17,7 +17,7 @@ namespace stresstests {
class concatenator_adaptor class concatenator_adaptor
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.concatenator"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.concatenator"};
protected: protected:
concatenator_adaptor(sdbus::IObject& object) concatenator_adaptor(sdbus::IObject& object)

View File

@ -17,7 +17,7 @@ namespace stresstests {
class concatenator_proxy class concatenator_proxy
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.concatenator"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.concatenator"};
protected: protected:
concatenator_proxy(sdbus::IProxy& proxy) concatenator_proxy(sdbus::IProxy& proxy)

View File

@ -18,7 +18,7 @@ namespace fahrenheit {
class thermometer_adaptor class thermometer_adaptor
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.fahrenheit.thermometer"};
protected: protected:
thermometer_adaptor(sdbus::IObject& object) thermometer_adaptor(sdbus::IObject& object)
@ -56,7 +56,7 @@ namespace thermometer {
class factory_adaptor class factory_adaptor
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.fahrenheit.thermometer.factory"};
protected: protected:
factory_adaptor(sdbus::IObject& object) factory_adaptor(sdbus::IObject& object)

View File

@ -18,7 +18,7 @@ namespace fahrenheit {
class thermometer_proxy class thermometer_proxy
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.fahrenheit.thermometer"};
protected: protected:
thermometer_proxy(sdbus::IProxy& proxy) thermometer_proxy(sdbus::IProxy& proxy)
@ -60,7 +60,7 @@ namespace thermometer {
class factory_proxy class factory_proxy
{ {
public: public:
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory"; static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.fahrenheit.thermometer.factory"};
protected: protected:
factory_proxy(sdbus::IProxy& proxy) factory_proxy(sdbus::IProxy& proxy)

View File

@ -46,18 +46,17 @@
#include <queue> #include <queue>
using namespace std::chrono_literals; using namespace std::chrono_literals;
using namespace std::string_literals;
#define SERVICE_1_BUS_NAME "org.sdbuscpp.stresstests.service1"s const sdbus::ServiceName SERVICE_1_BUS_NAME{"org.sdbuscpp.stresstests.service1"};
#define SERVICE_2_BUS_NAME "org.sdbuscpp.stresstests.service2"s const sdbus::ServiceName SERVICE_2_BUS_NAME{"org.sdbuscpp.stresstests.service2"};
#define CELSIUS_THERMOMETER_OBJECT_PATH "/org/sdbuscpp/stresstests/celsius/thermometer"s const sdbus::ObjectPath CELSIUS_THERMOMETER_OBJECT_PATH{"/org/sdbuscpp/stresstests/celsius/thermometer"};
#define FAHRENHEIT_THERMOMETER_OBJECT_PATH "/org/sdbuscpp/stresstests/fahrenheit/thermometer"s const sdbus::ObjectPath FAHRENHEIT_THERMOMETER_OBJECT_PATH{"/org/sdbuscpp/stresstests/fahrenheit/thermometer"};
#define CONCATENATOR_OBJECT_PATH "/org/sdbuscpp/stresstests/concatenator"s const sdbus::ObjectPath CONCATENATOR_OBJECT_PATH{"/org/sdbuscpp/stresstests/concatenator"};
class CelsiusThermometerAdaptor final : public sdbus::AdaptorInterfaces<org::sdbuscpp::stresstests::celsius::thermometer_adaptor> class CelsiusThermometerAdaptor final : public sdbus::AdaptorInterfaces<org::sdbuscpp::stresstests::celsius::thermometer_adaptor>
{ {
public: public:
CelsiusThermometerAdaptor(sdbus::IConnection& connection, std::string objectPath) CelsiusThermometerAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath objectPath)
: AdaptorInterfaces(connection, std::move(objectPath)) : AdaptorInterfaces(connection, std::move(objectPath))
{ {
registerAdaptor(); registerAdaptor();
@ -81,7 +80,7 @@ private:
class CelsiusThermometerProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstests::celsius::thermometer_proxy> class CelsiusThermometerProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstests::celsius::thermometer_proxy>
{ {
public: public:
CelsiusThermometerProxy(sdbus::IConnection& connection, std::string destination, std::string objectPath) CelsiusThermometerProxy(sdbus::IConnection& connection, sdbus::ServiceName destination, sdbus::ObjectPath objectPath)
: ProxyInterfaces(connection, std::move(destination), std::move(objectPath)) : ProxyInterfaces(connection, std::move(destination), std::move(objectPath))
{ {
registerProxy(); registerProxy();
@ -97,7 +96,7 @@ class FahrenheitThermometerAdaptor final : public sdbus::AdaptorInterfaces< org:
, org::sdbuscpp::stresstests::fahrenheit::thermometer::factory_adaptor > , org::sdbuscpp::stresstests::fahrenheit::thermometer::factory_adaptor >
{ {
public: public:
FahrenheitThermometerAdaptor(sdbus::IConnection& connection, std::string objectPath, bool isDelegate) FahrenheitThermometerAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath objectPath, bool isDelegate)
: AdaptorInterfaces(connection, std::move(objectPath)) : AdaptorInterfaces(connection, std::move(objectPath))
, celsiusProxy_(connection, SERVICE_2_BUS_NAME, CELSIUS_THERMOMETER_OBJECT_PATH) , celsiusProxy_(connection, SERVICE_2_BUS_NAME, CELSIUS_THERMOMETER_OBJECT_PATH)
{ {
@ -128,7 +127,7 @@ public:
{ {
// Create new delegate object // Create new delegate object
auto& connection = getObject().getConnection(); auto& connection = getObject().getConnection();
sdbus::ObjectPath newObjectPath = FAHRENHEIT_THERMOMETER_OBJECT_PATH + "/" + std::to_string(request.objectNr); sdbus::ObjectPath newObjectPath{FAHRENHEIT_THERMOMETER_OBJECT_PATH + "/" + std::to_string(request.objectNr)};
// Here we are testing dynamic creation of a D-Bus object in an async way // Here we are testing dynamic creation of a D-Bus object in an async way
auto adaptor = std::make_unique<FahrenheitThermometerAdaptor>(connection, newObjectPath, true); auto adaptor = std::make_unique<FahrenheitThermometerAdaptor>(connection, newObjectPath, true);
@ -176,7 +175,7 @@ protected:
objectCounter++; objectCounter++;
std::unique_lock<std::mutex> lock(mutex_); std::unique_lock<std::mutex> lock(mutex_);
requests_.push(WorkItem{objectCounter, std::string{}, std::move(result)}); requests_.push(WorkItem{objectCounter, {}, std::move(result)});
lock.unlock(); lock.unlock();
cond_.notify_one(); cond_.notify_one();
} }
@ -191,7 +190,7 @@ protected:
private: private:
CelsiusThermometerProxy celsiusProxy_; CelsiusThermometerProxy celsiusProxy_;
std::map<std::string, std::unique_ptr<FahrenheitThermometerAdaptor>> children_; std::map<sdbus::ObjectPath, std::unique_ptr<FahrenheitThermometerAdaptor>> children_;
std::mutex childrenMutex_; std::mutex childrenMutex_;
struct WorkItem struct WorkItem
@ -211,7 +210,7 @@ class FahrenheitThermometerProxy : public sdbus::ProxyInterfaces< org::sdbuscpp:
, org::sdbuscpp::stresstests::fahrenheit::thermometer::factory_proxy > , org::sdbuscpp::stresstests::fahrenheit::thermometer::factory_proxy >
{ {
public: public:
FahrenheitThermometerProxy(sdbus::IConnection& connection, std::string destination, std::string objectPath) FahrenheitThermometerProxy(sdbus::IConnection& connection, sdbus::ServiceName destination, sdbus::ObjectPath objectPath)
: ProxyInterfaces(connection, std::move(destination), std::move(objectPath)) : ProxyInterfaces(connection, std::move(destination), std::move(objectPath))
{ {
registerProxy(); registerProxy();
@ -226,7 +225,7 @@ public:
class ConcatenatorAdaptor final : public sdbus::AdaptorInterfaces<org::sdbuscpp::stresstests::concatenator_adaptor> class ConcatenatorAdaptor final : public sdbus::AdaptorInterfaces<org::sdbuscpp::stresstests::concatenator_adaptor>
{ {
public: public:
ConcatenatorAdaptor(sdbus::IConnection& connection, std::string objectPath) ConcatenatorAdaptor(sdbus::IConnection& connection, sdbus::ObjectPath objectPath)
: AdaptorInterfaces(connection, std::move(objectPath)) : AdaptorInterfaces(connection, std::move(objectPath))
{ {
unsigned int workers = std::thread::hardware_concurrency(); unsigned int workers = std::thread::hardware_concurrency();
@ -298,7 +297,7 @@ private:
class ConcatenatorProxy final : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstests::concatenator_proxy> class ConcatenatorProxy final : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstests::concatenator_proxy>
{ {
public: public:
ConcatenatorProxy(sdbus::IConnection& connection, std::string destination, std::string objectPath) ConcatenatorProxy(sdbus::IConnection& connection, sdbus::ServiceName destination, sdbus::ObjectPath objectPath)
: ProxyInterfaces(connection, std::move(destination), std::move(objectPath)) : ProxyInterfaces(connection, std::move(destination), std::move(objectPath))
{ {
registerProxy(); registerProxy();

View File

@ -26,6 +26,7 @@
*/ */
#include "Connection.h" #include "Connection.h"
#include "sdbus-c++/Types.h"
#include "unittests/mocks/SdBusMock.h" #include "unittests/mocks/SdBusMock.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -207,12 +208,16 @@ TYPED_TEST_SUITE(AConnectionNameRequest, BusTypeTags);
TYPED_TEST(AConnectionNameRequest, DoesNotThrowOnSuccess) TYPED_TEST(AConnectionNameRequest, DoesNotThrowOnSuccess)
{ {
EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(1)); EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(1));
this->con_->requestName("org.sdbuscpp.somename"); sdbus::ConnectionName name{"org.sdbuscpp.somename"};
this->con_->requestName(name);
} }
TYPED_TEST(AConnectionNameRequest, ThrowsOnFail) TYPED_TEST(AConnectionNameRequest, ThrowsOnFail)
{ {
sdbus::ConnectionName name{"org.sdbuscpp.somename"};
EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(-1)); EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(-1));
ASSERT_THROW(this->con_->requestName("org.sdbuscpp.somename"), sdbus::Error); ASSERT_THROW(this->con_->requestName(name), sdbus::Error);
} }

View File

@ -270,7 +270,7 @@ TEST(AMessage, CanCarryDBusArrayOfNontrivialTypesGivenAsStdVector)
{ {
auto msg = sdbus::createPlainMessage(); auto msg = sdbus::createPlainMessage();
const std::vector<sdbus::Signature> dataWritten{"s", "u", "b"}; const std::vector dataWritten{sdbus::Signature{"s"}, sdbus::Signature{"u"}, sdbus::Signature{"b"}};
msg << dataWritten; msg << dataWritten;
msg.seal(); msg.seal();
@ -300,7 +300,7 @@ TEST(AMessage, CanCarryDBusArrayOfNontrivialTypesGivenAsStdArray)
{ {
auto msg = sdbus::createPlainMessage(); auto msg = sdbus::createPlainMessage();
const std::array<sdbus::Signature, 3> dataWritten{"s", "u", "b"}; const std::array dataWritten{sdbus::Signature{"s"}, sdbus::Signature{"u"}, sdbus::Signature{"b"}};
msg << dataWritten; msg << dataWritten;
msg.seal(); msg.seal();
@ -333,7 +333,7 @@ TEST(AMessage, CanCarryDBusArrayOfNontrivialTypesGivenAsStdSpan)
{ {
auto msg = sdbus::createPlainMessage(); auto msg = sdbus::createPlainMessage();
const std::array<sdbus::Signature, 3> sourceArray{"s", "u", "b"}; const std::array sourceArray{sdbus::Signature{"s"}, sdbus::Signature{"u"}, sdbus::Signature{"b"}};
const std::span dataWritten{sourceArray}; const std::span dataWritten{sourceArray};
msg << dataWritten; msg << dataWritten;
@ -433,7 +433,7 @@ TEST(AMessage, CanCarryAComplexType)
> >
>; >;
ComplexType dataWritten = { {1, {{{5, {{"/some/object", true, 45, {{6, "hello"}, {7, "world"}}}}}}, "av", 3.14}}}; ComplexType dataWritten = { {1, {{{5, {{sdbus::ObjectPath{"/some/object"}, true, 45, {{6, "hello"}, {7, "world"}}}}}}, sdbus::Signature{"av"}, 3.14}}};
msg << dataWritten; msg << dataWritten;
msg.seal(); msg.seal();

View File

@ -85,6 +85,9 @@ namespace
TYPE(double)HAS_DBUS_TYPE_SIGNATURE("d") TYPE(double)HAS_DBUS_TYPE_SIGNATURE("d")
TYPE(const char*)HAS_DBUS_TYPE_SIGNATURE("s") TYPE(const char*)HAS_DBUS_TYPE_SIGNATURE("s")
TYPE(std::string)HAS_DBUS_TYPE_SIGNATURE("s") TYPE(std::string)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")
TYPE(sdbus::ObjectPath)HAS_DBUS_TYPE_SIGNATURE("o") TYPE(sdbus::ObjectPath)HAS_DBUS_TYPE_SIGNATURE("o")
TYPE(sdbus::Signature)HAS_DBUS_TYPE_SIGNATURE("g") TYPE(sdbus::Signature)HAS_DBUS_TYPE_SIGNATURE("g")
TYPE(sdbus::Variant)HAS_DBUS_TYPE_SIGNATURE("v") TYPE(sdbus::Variant)HAS_DBUS_TYPE_SIGNATURE("v")
@ -135,6 +138,9 @@ namespace
, double , double
, const char* , const char*
, std::string , std::string
, sdbus::BusName
, sdbus::InterfaceName
, sdbus::MemberName
, sdbus::ObjectPath , sdbus::ObjectPath
, sdbus::Signature , sdbus::Signature
, sdbus::Variant , sdbus::Variant

View File

@ -322,7 +322,6 @@ TEST(ASignature, CanBeMovedLikeAStdString)
sdbus::Signature oSignature{aSignature}; sdbus::Signature oSignature{aSignature};
ASSERT_THAT(sdbus::Signature{std::move(oSignature)}, Eq(sdbus::Signature(std::move(aSignature)))); ASSERT_THAT(sdbus::Signature{std::move(oSignature)}, Eq(sdbus::Signature(std::move(aSignature))));
ASSERT_THAT(std::string(oSignature), Eq(aSignature));
} }
TEST(AUnixFd, DuplicatesAndOwnsFdUponStandardConstruction) TEST(AUnixFd, DuplicatesAndOwnsFdUponStandardConstruction)
@ -428,17 +427,17 @@ TEST(AUnixFd, TakesOverNewFdAndClosesOriginalFdOnAdoptingReset)
TEST(AnError, CanBeConstructedFromANameAndAMessage) TEST(AnError, CanBeConstructedFromANameAndAMessage)
{ {
auto error = sdbus::Error("name", "message"); auto error = sdbus::Error(sdbus::Error::Name{"org.sdbuscpp.error"}, "message");
EXPECT_THAT(error.getName(), Eq<std::string>("name")); EXPECT_THAT(error.getName(), Eq<std::string>("org.sdbuscpp.error"));
EXPECT_THAT(error.getMessage(), Eq<std::string>("message")); EXPECT_THAT(error.getMessage(), Eq<std::string>("message"));
} }
TEST(AnError, CanBeConstructedFromANameOnly) TEST(AnError, CanBeConstructedFromANameOnly)
{ {
auto error1 = sdbus::Error("name"); auto error1 = sdbus::Error(sdbus::Error::Name{"org.sdbuscpp.error"});
auto error2 = sdbus::Error("name", nullptr); auto error2 = sdbus::Error(sdbus::Error::Name{"org.sdbuscpp.error"}, nullptr);
EXPECT_THAT(error1.getName(), Eq<std::string>("name")); EXPECT_THAT(error1.getName(), Eq<std::string>("org.sdbuscpp.error"));
EXPECT_THAT(error2.getName(), Eq<std::string>("name")); EXPECT_THAT(error2.getName(), Eq<std::string>("org.sdbuscpp.error"));
EXPECT_THAT(error1.getMessage(), Eq<std::string>("")); EXPECT_THAT(error1.getMessage(), Eq<std::string>(""));
EXPECT_THAT(error2.getMessage(), Eq<std::string>("")); EXPECT_THAT(error2.getMessage(), Eq<std::string>(""));

View File

@ -82,7 +82,7 @@ std::string AdaptorGenerator::processInterface(Node& interface) const
body << "class " << className << endl body << "class " << className << endl
<< "{" << endl << "{" << endl
<< "public:" << endl << "public:" << endl
<< tab << "static constexpr const char* INTERFACE_NAME = \"" << ifaceName << "\";" << endl << endl << tab << "static inline const sdbus::InterfaceName INTERFACE_NAME{\"" << ifaceName << "\"};" << endl << endl
<< "protected:" << endl << "protected:" << endl
<< tab << className << "(sdbus::IObject& object)" << endl << tab << className << "(sdbus::IObject& object)" << endl
<< tab << tab << ": object_(&object)" << endl << tab << tab << ": object_(&object)" << endl

View File

@ -81,7 +81,7 @@ std::string ProxyGenerator::processInterface(Node& interface) const
body << "class " << className << endl body << "class " << className << endl
<< "{" << endl << "{" << endl
<< "public:" << endl << "public:" << endl
<< tab << "static constexpr const char* INTERFACE_NAME = \"" << ifaceName << "\";" << endl << endl << tab << "static inline const sdbus::InterfaceName INTERFACE_NAME{\"" << ifaceName << "\"};" << endl << endl
<< "protected:" << endl << "protected:" << endl
<< tab << className << "(sdbus::IProxy& proxy)" << endl << tab << className << "(sdbus::IProxy& proxy)" << endl
<< tab << tab << ": proxy_(&proxy)" << endl << tab << tab << ": proxy_(&proxy)" << endl