forked from Kistler-Group/sdbus-cpp
Move C++17 uncaught_exceptions to public API
This commit is contained in:
@@ -37,7 +37,6 @@ set(SDBUSCPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/${SDBUSCPP_INCLUDE_
|
|||||||
|
|
||||||
set(SDBUSCPP_CPP_SRCS
|
set(SDBUSCPP_CPP_SRCS
|
||||||
${SDBUSCPP_SOURCE_DIR}/Connection.cpp
|
${SDBUSCPP_SOURCE_DIR}/Connection.cpp
|
||||||
${SDBUSCPP_SOURCE_DIR}/ConvenienceApiClasses.cpp
|
|
||||||
${SDBUSCPP_SOURCE_DIR}/Error.cpp
|
${SDBUSCPP_SOURCE_DIR}/Error.cpp
|
||||||
${SDBUSCPP_SOURCE_DIR}/Message.cpp
|
${SDBUSCPP_SOURCE_DIR}/Message.cpp
|
||||||
${SDBUSCPP_SOURCE_DIR}/Object.cpp
|
${SDBUSCPP_SOURCE_DIR}/Object.cpp
|
||||||
|
@@ -53,7 +53,7 @@ namespace sdbus {
|
|||||||
MethodRegistrator& operator=(MethodRegistrator&& other) = default;
|
MethodRegistrator& operator=(MethodRegistrator&& other) = default;
|
||||||
~MethodRegistrator() noexcept(false);
|
~MethodRegistrator() noexcept(false);
|
||||||
|
|
||||||
MethodRegistrator& onInterface(const std::string& interfaceName);
|
MethodRegistrator& onInterface(std::string interfaceName);
|
||||||
template <typename _Function>
|
template <typename _Function>
|
||||||
std::enable_if_t<!is_async_method_v<_Function>, MethodRegistrator&> implementedAs(_Function&& callback);
|
std::enable_if_t<!is_async_method_v<_Function>, MethodRegistrator&> implementedAs(_Function&& callback);
|
||||||
template <typename _Function>
|
template <typename _Function>
|
||||||
@@ -102,7 +102,7 @@ namespace sdbus {
|
|||||||
PropertyRegistrator& operator=(PropertyRegistrator&& other) = default;
|
PropertyRegistrator& operator=(PropertyRegistrator&& other) = default;
|
||||||
~PropertyRegistrator() noexcept(false);
|
~PropertyRegistrator() noexcept(false);
|
||||||
|
|
||||||
PropertyRegistrator& onInterface(const std::string& interfaceName);
|
PropertyRegistrator& onInterface(std::string interfaceName);
|
||||||
template <typename _Function> PropertyRegistrator& withGetter(_Function&& callback);
|
template <typename _Function> PropertyRegistrator& withGetter(_Function&& callback);
|
||||||
template <typename _Function> PropertyRegistrator& withSetter(_Function&& callback);
|
template <typename _Function> PropertyRegistrator& withSetter(_Function&& callback);
|
||||||
PropertyRegistrator& markAsDeprecated();
|
PropertyRegistrator& markAsDeprecated();
|
||||||
@@ -205,12 +205,12 @@ namespace sdbus {
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SignalSubscriber(IProxy& proxy, const std::string& signalName);
|
SignalSubscriber(IProxy& proxy, const std::string& signalName);
|
||||||
SignalSubscriber& onInterface(const std::string& interfaceName);
|
SignalSubscriber& onInterface(std::string interfaceName);
|
||||||
template <typename _Function> void call(_Function&& callback);
|
template <typename _Function> void call(_Function&& callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IProxy& proxy_;
|
IProxy& proxy_;
|
||||||
std::string signalName_;
|
const std::string& signalName_;
|
||||||
std::string interfaceName_;
|
std::string interfaceName_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -222,14 +222,14 @@ namespace sdbus {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
IProxy& proxy_;
|
IProxy& proxy_;
|
||||||
std::string propertyName_;
|
const std::string& propertyName_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PropertySetter
|
class PropertySetter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PropertySetter(IProxy& proxy, const std::string& propertyName);
|
PropertySetter(IProxy& proxy, const std::string& propertyName);
|
||||||
PropertySetter& onInterface(const std::string& interfaceName);
|
PropertySetter& onInterface(std::string interfaceName);
|
||||||
template <typename _Value> void toValue(const _Value& value);
|
template <typename _Value> void toValue(const _Value& value);
|
||||||
void toValue(const sdbus::Variant& value);
|
void toValue(const sdbus::Variant& value);
|
||||||
|
|
||||||
|
@@ -36,7 +36,8 @@
|
|||||||
#include <sdbus-c++/Error.h>
|
#include <sdbus-c++/Error.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
/*#include <exception>*/
|
#include <exception>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace sdbus {
|
namespace sdbus {
|
||||||
|
|
||||||
@@ -44,12 +45,10 @@ namespace sdbus {
|
|||||||
/*** MethodRegistrator ***/
|
/*** MethodRegistrator ***/
|
||||||
/*** ----------------- ***/
|
/*** ----------------- ***/
|
||||||
|
|
||||||
// Moved into the library to isolate from C++17 dependency
|
|
||||||
/*
|
|
||||||
inline MethodRegistrator::MethodRegistrator(IObject& object, const std::string& methodName)
|
inline MethodRegistrator::MethodRegistrator(IObject& object, const std::string& methodName)
|
||||||
: object_(object)
|
: object_(object)
|
||||||
, methodName_(methodName)
|
, methodName_(methodName)
|
||||||
, exceptions_(std::uncaught_exceptions()) // Needs C++17
|
, exceptions_(std::uncaught_exceptions())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,8 +58,8 @@ namespace sdbus {
|
|||||||
if (std::uncaught_exceptions() != exceptions_)
|
if (std::uncaught_exceptions() != exceptions_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when registering a DBus method", EINVAL);
|
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
|
||||||
SDBUS_THROW_ERROR_IF(!methodCallback_, "Method handler not specified when registering a DBus method", EINVAL);
|
assert(methodCallback_); // implementedAs() must be placed/called prior to this function
|
||||||
|
|
||||||
// registerMethod() can throw. But as the MethodRegistrator shall always be used as an unnamed,
|
// registerMethod() can throw. But as the MethodRegistrator shall always be used as an unnamed,
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
||||||
@@ -73,11 +72,10 @@ namespace sdbus {
|
|||||||
// to the exception thrown from here if the caller is a destructor itself.
|
// to the exception thrown from here if the caller is a destructor itself.
|
||||||
object_.registerMethod(interfaceName_, methodName_, inputSignature_, outputSignature_, std::move(methodCallback_), flags_);
|
object_.registerMethod(interfaceName_, methodName_, inputSignature_, outputSignature_, std::move(methodCallback_), flags_);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
inline MethodRegistrator& MethodRegistrator::onInterface(const std::string& interfaceName)
|
inline MethodRegistrator& MethodRegistrator::onInterface(std::string interfaceName)
|
||||||
{
|
{
|
||||||
interfaceName_ = interfaceName;
|
interfaceName_ = std::move(interfaceName);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -157,11 +155,9 @@ namespace sdbus {
|
|||||||
/*** SignalRegistrator ***/
|
/*** SignalRegistrator ***/
|
||||||
/*** ----------------- ***/
|
/*** ----------------- ***/
|
||||||
|
|
||||||
// Moved into the library to isolate from C++17 dependency
|
inline SignalRegistrator::SignalRegistrator(IObject& object, const std::string& signalName)
|
||||||
/*
|
|
||||||
inline SignalRegistrator::SignalRegistrator(IObject& object, std::string signalName)
|
|
||||||
: object_(object)
|
: object_(object)
|
||||||
, signalName_(std::move(signalName))
|
, signalName_(signalName)
|
||||||
, exceptions_(std::uncaught_exceptions())
|
, exceptions_(std::uncaught_exceptions())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -172,8 +168,7 @@ namespace sdbus {
|
|||||||
if (std::uncaught_exceptions() != exceptions_)
|
if (std::uncaught_exceptions() != exceptions_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (interfaceName_.empty())
|
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
|
||||||
throw sdbus::Exception("DBus interface not specified when registering a DBus signal");
|
|
||||||
|
|
||||||
// registerSignal() can throw. But as the SignalRegistrator shall always be used as an unnamed,
|
// registerSignal() can throw. But as the SignalRegistrator shall always be used as an unnamed,
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
||||||
@@ -184,9 +179,8 @@ namespace sdbus {
|
|||||||
// Therefore, we can allow registerSignal() to throw even if we are in the destructor.
|
// Therefore, we can allow registerSignal() to throw even if we are in the destructor.
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
// to the exception thrown from here if the caller is a destructor itself.
|
||||||
object_.registerSignal(interfaceName_, signalName_, signalSignature_);
|
object_.registerSignal(interfaceName_, signalName_, signalSignature_, flags_);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
inline SignalRegistrator& SignalRegistrator::onInterface(std::string interfaceName)
|
inline SignalRegistrator& SignalRegistrator::onInterface(std::string interfaceName)
|
||||||
{
|
{
|
||||||
@@ -214,11 +208,9 @@ namespace sdbus {
|
|||||||
/*** PropertyRegistrator ***/
|
/*** PropertyRegistrator ***/
|
||||||
/*** ------------------- ***/
|
/*** ------------------- ***/
|
||||||
|
|
||||||
// Moved into the library to isolate from C++17 dependency
|
inline PropertyRegistrator::PropertyRegistrator(IObject& object, const std::string& propertyName)
|
||||||
/*
|
|
||||||
inline PropertyRegistrator::PropertyRegistrator(IObject& object, std::string propertyName)
|
|
||||||
: object_(object)
|
: object_(object)
|
||||||
, propertyName_(std::move(propertyName))
|
, propertyName_(propertyName)
|
||||||
, exceptions_(std::uncaught_exceptions())
|
, exceptions_(std::uncaught_exceptions())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -229,7 +221,7 @@ namespace sdbus {
|
|||||||
if (std::uncaught_exceptions() != exceptions_)
|
if (std::uncaught_exceptions() != exceptions_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when registering a DBus property", EINVAL);
|
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
|
||||||
|
|
||||||
// registerProperty() can throw. But as the PropertyRegistrator shall always be used as an unnamed,
|
// registerProperty() can throw. But as the PropertyRegistrator shall always be used as an unnamed,
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
||||||
@@ -240,17 +232,17 @@ namespace sdbus {
|
|||||||
// Therefore, we can allow registerProperty() to throw even if we are in the destructor.
|
// Therefore, we can allow registerProperty() to throw even if we are in the destructor.
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
// to the exception thrown from here if the caller is a destructor itself.
|
||||||
object_.registerProperty( std::move(interfaceName_)
|
object_.registerProperty( interfaceName_
|
||||||
, std::move(propertyName_)
|
, propertyName_
|
||||||
, std::move(propertySignature_)
|
, propertySignature_
|
||||||
, std::move(getter_)
|
, std::move(getter_)
|
||||||
, std::move(setter_) );
|
, std::move(setter_)
|
||||||
|
, flags_ );
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
inline PropertyRegistrator& PropertyRegistrator::onInterface(const std::string& interfaceName)
|
inline PropertyRegistrator& PropertyRegistrator::onInterface(std::string interfaceName)
|
||||||
{
|
{
|
||||||
interfaceName_ = interfaceName;
|
interfaceName_ = std::move(interfaceName);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -323,8 +315,6 @@ namespace sdbus {
|
|||||||
/*** InterfaceFlagsSetter ***/
|
/*** InterfaceFlagsSetter ***/
|
||||||
/*** -------------------- ***/
|
/*** -------------------- ***/
|
||||||
|
|
||||||
// Moved into the library to isolate from C++17 dependency
|
|
||||||
/*
|
|
||||||
inline InterfaceFlagsSetter::InterfaceFlagsSetter(IObject& object, const std::string& interfaceName)
|
inline InterfaceFlagsSetter::InterfaceFlagsSetter(IObject& object, const std::string& interfaceName)
|
||||||
: object_(object)
|
: object_(object)
|
||||||
, interfaceName_(interfaceName)
|
, interfaceName_(interfaceName)
|
||||||
@@ -338,8 +328,6 @@ namespace sdbus {
|
|||||||
if (std::uncaught_exceptions() != exceptions_)
|
if (std::uncaught_exceptions() != exceptions_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when setting its flags", EINVAL);
|
|
||||||
|
|
||||||
// setInterfaceFlags() can throw. But as the InterfaceFlagsSetter shall always be used as an unnamed,
|
// setInterfaceFlags() can throw. But as the InterfaceFlagsSetter shall always be used as an unnamed,
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
||||||
// shall never happen. I.e. it should not happen that this destructor is directly called
|
// shall never happen. I.e. it should not happen that this destructor is directly called
|
||||||
@@ -349,10 +337,8 @@ namespace sdbus {
|
|||||||
// Therefore, we can allow setInterfaceFlags() to throw even if we are in the destructor.
|
// Therefore, we can allow setInterfaceFlags() to throw even if we are in the destructor.
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
// to the exception thrown from here if the caller is a destructor itself.
|
||||||
object_.setInterfaceFlags( std::move(interfaceName_)
|
object_.setInterfaceFlags(interfaceName_, std::move(flags_));
|
||||||
, std::move(flags_) );
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
inline InterfaceFlagsSetter& InterfaceFlagsSetter::markAsDeprecated()
|
inline InterfaceFlagsSetter& InterfaceFlagsSetter::markAsDeprecated()
|
||||||
{
|
{
|
||||||
@@ -386,8 +372,6 @@ namespace sdbus {
|
|||||||
/*** SignalEmitter ***/
|
/*** SignalEmitter ***/
|
||||||
/*** ------------- ***/
|
/*** ------------- ***/
|
||||||
|
|
||||||
// Moved into the library to isolate from C++17 dependency
|
|
||||||
/*
|
|
||||||
inline SignalEmitter::SignalEmitter(IObject& object, const std::string& signalName)
|
inline SignalEmitter::SignalEmitter(IObject& object, const std::string& signalName)
|
||||||
: object_(object)
|
: object_(object)
|
||||||
, signalName_(signalName)
|
, signalName_(signalName)
|
||||||
@@ -401,9 +385,6 @@ namespace sdbus {
|
|||||||
if (std::uncaught_exceptions() != exceptions_)
|
if (std::uncaught_exceptions() != exceptions_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!signal_.isValid())
|
|
||||||
throw sdbus::Exception("DBus interface not specified when emitting a DBus signal");
|
|
||||||
|
|
||||||
// emitSignal() can throw. But as the SignalEmitter shall always be used as an unnamed,
|
// emitSignal() can throw. But as the SignalEmitter shall always be used as an unnamed,
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
||||||
// shall never happen. I.e. it should not happen that this destructor is directly called
|
// shall never happen. I.e. it should not happen that this destructor is directly called
|
||||||
@@ -415,7 +396,6 @@ namespace sdbus {
|
|||||||
// to the exception thrown from here if the caller is a destructor itself.
|
// to the exception thrown from here if the caller is a destructor itself.
|
||||||
object_.emitSignal(signal_);
|
object_.emitSignal(signal_);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
inline SignalEmitter& SignalEmitter::onInterface(const std::string& interfaceName)
|
inline SignalEmitter& SignalEmitter::onInterface(const std::string& interfaceName)
|
||||||
{
|
{
|
||||||
@@ -427,7 +407,7 @@ namespace sdbus {
|
|||||||
template <typename... _Args>
|
template <typename... _Args>
|
||||||
inline void SignalEmitter::withArguments(_Args&&... args)
|
inline void SignalEmitter::withArguments(_Args&&... args)
|
||||||
{
|
{
|
||||||
SDBUS_THROW_ERROR_IF(!signal_.isValid(), "DBus interface not specified when emitting a DBus signal", EINVAL);
|
assert(signal_.isValid()); // onInterface() must be placed/called prior to withArguments()
|
||||||
|
|
||||||
detail::serialize_pack(signal_, std::forward<_Args>(args)...);
|
detail::serialize_pack(signal_, std::forward<_Args>(args)...);
|
||||||
}
|
}
|
||||||
@@ -436,9 +416,7 @@ namespace sdbus {
|
|||||||
/*** MethodInvoker ***/
|
/*** MethodInvoker ***/
|
||||||
/*** ------------- ***/
|
/*** ------------- ***/
|
||||||
|
|
||||||
// Moved into the library to isolate from C++17 dependency
|
inline MethodInvoker::MethodInvoker(IProxy& proxy, const std::string& methodName)
|
||||||
/*
|
|
||||||
inline MethodInvoker::MethodInvoker(IProxy& proxyObject, const std::string& methodName)
|
|
||||||
: proxy_(proxy)
|
: proxy_(proxy)
|
||||||
, methodName_(methodName)
|
, methodName_(methodName)
|
||||||
, exceptions_(std::uncaught_exceptions())
|
, exceptions_(std::uncaught_exceptions())
|
||||||
@@ -452,9 +430,6 @@ namespace sdbus {
|
|||||||
if (methodCalled_ || std::uncaught_exceptions() != exceptions_)
|
if (methodCalled_ || std::uncaught_exceptions() != exceptions_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!method_.isValid())
|
|
||||||
throw sdbus::Exception("DBus interface not specified when calling a DBus method");
|
|
||||||
|
|
||||||
// callMethod() can throw. But as the MethodInvoker shall always be used as an unnamed,
|
// callMethod() can throw. But as the MethodInvoker shall always be used as an unnamed,
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
||||||
// shall never happen. I.e. it should not happen that this destructor is directly called
|
// shall never happen. I.e. it should not happen that this destructor is directly called
|
||||||
@@ -464,9 +439,8 @@ namespace sdbus {
|
|||||||
// Therefore, we can allow callMethod() to throw even if we are in the destructor.
|
// Therefore, we can allow callMethod() to throw even if we are in the destructor.
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
// to the exception thrown from here if the caller is a destructor itself.
|
||||||
proxy_.callMethod(method_);
|
proxy_.callMethod(method_, timeout_);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
inline MethodInvoker& MethodInvoker::onInterface(const std::string& interfaceName)
|
inline MethodInvoker& MethodInvoker::onInterface(const std::string& interfaceName)
|
||||||
{
|
{
|
||||||
@@ -492,7 +466,7 @@ namespace sdbus {
|
|||||||
template <typename... _Args>
|
template <typename... _Args>
|
||||||
inline MethodInvoker& MethodInvoker::withArguments(_Args&&... args)
|
inline MethodInvoker& MethodInvoker::withArguments(_Args&&... args)
|
||||||
{
|
{
|
||||||
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
|
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
|
||||||
|
|
||||||
detail::serialize_pack(method_, std::forward<_Args>(args)...);
|
detail::serialize_pack(method_, std::forward<_Args>(args)...);
|
||||||
|
|
||||||
@@ -502,7 +476,7 @@ namespace sdbus {
|
|||||||
template <typename... _Args>
|
template <typename... _Args>
|
||||||
inline void MethodInvoker::storeResultsTo(_Args&... args)
|
inline void MethodInvoker::storeResultsTo(_Args&... args)
|
||||||
{
|
{
|
||||||
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
|
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
|
||||||
|
|
||||||
auto reply = proxy_.callMethod(method_, timeout_);
|
auto reply = proxy_.callMethod(method_, timeout_);
|
||||||
methodCalled_ = true;
|
methodCalled_ = true;
|
||||||
@@ -512,7 +486,7 @@ namespace sdbus {
|
|||||||
|
|
||||||
inline void MethodInvoker::dontExpectReply()
|
inline void MethodInvoker::dontExpectReply()
|
||||||
{
|
{
|
||||||
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
|
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
|
||||||
|
|
||||||
method_.dontExpectReply();
|
method_.dontExpectReply();
|
||||||
}
|
}
|
||||||
@@ -551,7 +525,7 @@ namespace sdbus {
|
|||||||
template <typename... _Args>
|
template <typename... _Args>
|
||||||
inline AsyncMethodInvoker& AsyncMethodInvoker::withArguments(_Args&&... args)
|
inline AsyncMethodInvoker& AsyncMethodInvoker::withArguments(_Args&&... args)
|
||||||
{
|
{
|
||||||
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
|
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
|
||||||
|
|
||||||
detail::serialize_pack(method_, std::forward<_Args>(args)...);
|
detail::serialize_pack(method_, std::forward<_Args>(args)...);
|
||||||
|
|
||||||
@@ -561,7 +535,7 @@ namespace sdbus {
|
|||||||
template <typename _Function>
|
template <typename _Function>
|
||||||
void AsyncMethodInvoker::uponReplyInvoke(_Function&& callback)
|
void AsyncMethodInvoker::uponReplyInvoke(_Function&& callback)
|
||||||
{
|
{
|
||||||
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
|
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
|
||||||
|
|
||||||
auto asyncReplyHandler = [callback = std::forward<_Function>(callback)](MethodReply& reply, const Error* error)
|
auto asyncReplyHandler = [callback = std::forward<_Function>(callback)](MethodReply& reply, const Error* error)
|
||||||
{
|
{
|
||||||
@@ -590,9 +564,9 @@ namespace sdbus {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SignalSubscriber& SignalSubscriber::onInterface(const std::string& interfaceName)
|
inline SignalSubscriber& SignalSubscriber::onInterface(std::string interfaceName)
|
||||||
{
|
{
|
||||||
interfaceName_ = interfaceName;
|
interfaceName_ = std::move(interfaceName);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -600,7 +574,7 @@ namespace sdbus {
|
|||||||
template <typename _Function>
|
template <typename _Function>
|
||||||
inline void SignalSubscriber::call(_Function&& callback)
|
inline void SignalSubscriber::call(_Function&& callback)
|
||||||
{
|
{
|
||||||
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when subscribing to a signal", EINVAL);
|
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
|
||||||
|
|
||||||
proxy_.registerSignalHandler( interfaceName_
|
proxy_.registerSignalHandler( interfaceName_
|
||||||
, signalName_
|
, signalName_
|
||||||
@@ -649,9 +623,9 @@ namespace sdbus {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PropertySetter& PropertySetter::onInterface(const std::string& interfaceName)
|
inline PropertySetter& PropertySetter::onInterface(std::string interfaceName)
|
||||||
{
|
{
|
||||||
interfaceName_ = interfaceName;
|
interfaceName_ = std::move(interfaceName);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -664,7 +638,7 @@ namespace sdbus {
|
|||||||
|
|
||||||
inline void PropertySetter::toValue(const sdbus::Variant& value)
|
inline void PropertySetter::toValue(const sdbus::Variant& value)
|
||||||
{
|
{
|
||||||
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when setting a property", EINVAL);
|
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
|
||||||
|
|
||||||
proxy_
|
proxy_
|
||||||
.callMethod("Set")
|
.callMethod("Set")
|
||||||
|
@@ -1,209 +0,0 @@
|
|||||||
/**
|
|
||||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
|
||||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
|
||||||
*
|
|
||||||
* @file ConvenienceApiClasses.cpp
|
|
||||||
*
|
|
||||||
* Created on: Jan 19, 2017
|
|
||||||
* Project: sdbus-c++
|
|
||||||
* Description: High-level D-Bus IPC C++ library based on sd-bus
|
|
||||||
*
|
|
||||||
* This file is part of sdbus-c++.
|
|
||||||
*
|
|
||||||
* sdbus-c++ is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2.1 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* sdbus-c++ is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with sdbus-c++. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sdbus-c++/ConvenienceApiClasses.h"
|
|
||||||
#include "sdbus-c++/IObject.h"
|
|
||||||
#include "sdbus-c++/IProxy.h"
|
|
||||||
#include <string>
|
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
namespace sdbus {
|
|
||||||
|
|
||||||
MethodRegistrator::MethodRegistrator(IObject& object, const std::string& methodName)
|
|
||||||
: object_(object)
|
|
||||||
, methodName_(methodName)
|
|
||||||
, exceptions_(std::uncaught_exceptions()) // Needs C++17
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodRegistrator::~MethodRegistrator() noexcept(false) // since C++11, destructors must
|
|
||||||
{ // explicitly be allowed to throw
|
|
||||||
// Don't register the method if MethodRegistrator threw an exception in one of its methods
|
|
||||||
if (std::uncaught_exceptions() != exceptions_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when registering a DBus method", EINVAL);
|
|
||||||
SDBUS_THROW_ERROR_IF(!methodCallback_, "Method handler not specified when registering a DBus method", EINVAL);
|
|
||||||
|
|
||||||
// registerMethod() can throw. But as the MethodRegistrator shall always be used as an unnamed,
|
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
|
||||||
// shall never happen. I.e. it should not happen that this destructor is directly called
|
|
||||||
// in the stack-unwinding process of another flying exception (which would lead to immediate
|
|
||||||
// termination). It can be called indirectly in the destructor of another object, but that's
|
|
||||||
// fine and safe provided that the caller catches exceptions thrown from here.
|
|
||||||
// Therefore, we can allow registerMethod() to throw even if we are in the destructor.
|
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
|
||||||
object_.registerMethod(interfaceName_, methodName_, inputSignature_, outputSignature_, std::move(methodCallback_), flags_);
|
|
||||||
}
|
|
||||||
|
|
||||||
SignalRegistrator::SignalRegistrator(IObject& object, const std::string& signalName)
|
|
||||||
: object_(object)
|
|
||||||
, signalName_(signalName)
|
|
||||||
, exceptions_(std::uncaught_exceptions()) // Needs C++17
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SignalRegistrator::~SignalRegistrator() noexcept(false) // since C++11, destructors must
|
|
||||||
{ // explicitly be allowed to throw
|
|
||||||
// Don't register the signal if SignalRegistrator threw an exception in one of its methods
|
|
||||||
if (std::uncaught_exceptions() != exceptions_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when registering a DBus signal", EINVAL);
|
|
||||||
|
|
||||||
// registerSignal() can throw. But as the SignalRegistrator shall always be used as an unnamed,
|
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
|
||||||
// shall never happen. I.e. it should not happen that this destructor is directly called
|
|
||||||
// in the stack-unwinding process of another flying exception (which would lead to immediate
|
|
||||||
// termination). It can be called indirectly in the destructor of another object, but that's
|
|
||||||
// fine and safe provided that the caller catches exceptions thrown from here.
|
|
||||||
// Therefore, we can allow registerSignal() to throw even if we are in the destructor.
|
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
|
||||||
object_.registerSignal(interfaceName_, signalName_, signalSignature_, flags_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PropertyRegistrator::PropertyRegistrator(IObject& object, const std::string& propertyName)
|
|
||||||
: object_(object)
|
|
||||||
, propertyName_(propertyName)
|
|
||||||
, exceptions_(std::uncaught_exceptions())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyRegistrator::~PropertyRegistrator() noexcept(false) // since C++11, destructors must
|
|
||||||
{ // explicitly be allowed to throw
|
|
||||||
// Don't register the property if PropertyRegistrator threw an exception in one of its methods
|
|
||||||
if (std::uncaught_exceptions() != exceptions_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when registering a DBus property", EINVAL);
|
|
||||||
|
|
||||||
// registerProperty() can throw. But as the PropertyRegistrator shall always be used as an unnamed,
|
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
|
||||||
// shall never happen. I.e. it should not happen that this destructor is directly called
|
|
||||||
// in the stack-unwinding process of another flying exception (which would lead to immediate
|
|
||||||
// termination). It can be called indirectly in the destructor of another object, but that's
|
|
||||||
// fine and safe provided that the caller catches exceptions thrown from here.
|
|
||||||
// Therefore, we can allow registerProperty() to throw even if we are in the destructor.
|
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
|
||||||
object_.registerProperty( std::move(interfaceName_)
|
|
||||||
, std::move(propertyName_)
|
|
||||||
, std::move(propertySignature_)
|
|
||||||
, std::move(getter_)
|
|
||||||
, std::move(setter_)
|
|
||||||
, flags_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
InterfaceFlagsSetter::InterfaceFlagsSetter(IObject& object, const std::string& interfaceName)
|
|
||||||
: object_(object)
|
|
||||||
, interfaceName_(interfaceName)
|
|
||||||
, exceptions_(std::uncaught_exceptions())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceFlagsSetter::~InterfaceFlagsSetter() noexcept(false) // since C++11, destructors must
|
|
||||||
{ // explicitly be allowed to throw
|
|
||||||
// Don't set any flags if InterfaceFlagsSetter threw an exception in one of its methods
|
|
||||||
if (std::uncaught_exceptions() != exceptions_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when setting its flags", EINVAL);
|
|
||||||
|
|
||||||
// setInterfaceFlags() can throw. But as the InterfaceFlagsSetter shall always be used as an unnamed,
|
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
|
||||||
// shall never happen. I.e. it should not happen that this destructor is directly called
|
|
||||||
// in the stack-unwinding process of another flying exception (which would lead to immediate
|
|
||||||
// termination). It can be called indirectly in the destructor of another object, but that's
|
|
||||||
// fine and safe provided that the caller catches exceptions thrown from here.
|
|
||||||
// Therefore, we can allow setInterfaceFlags() to throw even if we are in the destructor.
|
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
|
||||||
object_.setInterfaceFlags( std::move(interfaceName_)
|
|
||||||
, std::move(flags_) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SignalEmitter::SignalEmitter(IObject& object, const std::string& signalName)
|
|
||||||
: object_(object)
|
|
||||||
, signalName_(signalName)
|
|
||||||
, exceptions_(std::uncaught_exceptions()) // Needs C++17
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SignalEmitter::~SignalEmitter() noexcept(false) // since C++11, destructors must
|
|
||||||
{ // explicitly be allowed to throw
|
|
||||||
// Don't emit the signal if SignalEmitter threw an exception in one of its methods
|
|
||||||
if (std::uncaught_exceptions() != exceptions_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(!signal_.isValid(), "DBus interface not specified when emitting a DBus signal", EINVAL);
|
|
||||||
|
|
||||||
// emitSignal() can throw. But as the SignalEmitter shall always be used as an unnamed,
|
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
|
||||||
// shall never happen. I.e. it should not happen that this destructor is directly called
|
|
||||||
// in the stack-unwinding process of another flying exception (which would lead to immediate
|
|
||||||
// termination). It can be called indirectly in the destructor of another object, but that's
|
|
||||||
// fine and safe provided that the caller catches exceptions thrown from here.
|
|
||||||
// Therefore, we can allow emitSignal() to throw even if we are in the destructor.
|
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
|
||||||
object_.emitSignal(signal_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MethodInvoker::MethodInvoker(IProxy& proxy, const std::string& methodName)
|
|
||||||
: proxy_(proxy)
|
|
||||||
, methodName_(methodName)
|
|
||||||
, exceptions_(std::uncaught_exceptions()) // Needs C++17
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodInvoker::~MethodInvoker() noexcept(false) // since C++11, destructors must
|
|
||||||
{ // explicitly be allowed to throw
|
|
||||||
// Don't call the method if it has been called already or if MethodInvoker
|
|
||||||
// threw an exception in one of its methods
|
|
||||||
if (methodCalled_ || std::uncaught_exceptions() != exceptions_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
|
|
||||||
|
|
||||||
// callMethod() can throw. But as the MethodInvoker shall always be used as an unnamed,
|
|
||||||
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
|
|
||||||
// shall never happen. I.e. it should not happen that this destructor is directly called
|
|
||||||
// in the stack-unwinding process of another flying exception (which would lead to immediate
|
|
||||||
// termination). It can be called indirectly in the destructor of another object, but that's
|
|
||||||
// fine and safe provided that the caller catches exceptions thrown from here.
|
|
||||||
// Therefore, we can allow callMethod() to throw even if we are in the destructor.
|
|
||||||
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
|
|
||||||
// to the exception thrown from here if the caller is a destructor itself.
|
|
||||||
proxy_.callMethod(method_, timeout_);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -134,6 +134,8 @@ sdbus::Signal Object::createSignal(const std::string& interfaceName, const std::
|
|||||||
|
|
||||||
void Object::emitSignal(const sdbus::Signal& message)
|
void Object::emitSignal(const sdbus::Signal& message)
|
||||||
{
|
{
|
||||||
|
SDBUS_THROW_ERROR_IF(!message.isValid(), "Invalid signal message provided", EINVAL);
|
||||||
|
|
||||||
message.send();
|
message.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,11 +71,15 @@ AsyncMethodCall Proxy::createAsyncMethodCall(const std::string& interfaceName, c
|
|||||||
|
|
||||||
MethodReply Proxy::callMethod(const MethodCall& message, uint64_t timeout)
|
MethodReply Proxy::callMethod(const MethodCall& message, uint64_t timeout)
|
||||||
{
|
{
|
||||||
|
SDBUS_THROW_ERROR_IF(!message.isValid(), "Invalid method call message provided", EINVAL);
|
||||||
|
|
||||||
return message.send(timeout);
|
return message.send(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Proxy::callMethod(const AsyncMethodCall& message, async_reply_handler asyncReplyCallback, uint64_t timeout)
|
void Proxy::callMethod(const AsyncMethodCall& message, async_reply_handler asyncReplyCallback, uint64_t timeout)
|
||||||
{
|
{
|
||||||
|
SDBUS_THROW_ERROR_IF(!message.isValid(), "Invalid async method call message provided", EINVAL);
|
||||||
|
|
||||||
auto callback = (void*)&Proxy::sdbus_async_reply_handler;
|
auto callback = (void*)&Proxy::sdbus_async_reply_handler;
|
||||||
auto callData = std::make_unique<AsyncCalls::CallData>(AsyncCalls::CallData{*this, std::move(asyncReplyCallback), {}});
|
auto callData = std::make_unique<AsyncCalls::CallData>(AsyncCalls::CallData{*this, std::move(asyncReplyCallback), {}});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user