dbus-cxx
methodbase.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-3.0-or-later OR BSD-3-Clause
2/***************************************************************************
3 * Copyright (C) 2009,2010 by Rick L. Vinyard, Jr. *
4 * rvinyard@cs.nmsu.edu *
5 * Copyright (C) 2019-2020 by Robert Middleton *
6 * robert.middleton@rm5248.com *
7 * *
8 * *
9 * This file is part of the dbus-cxx library. *
10 ***************************************************************************/
11#include <exception>
12#include <stdint.h>
14#include <dbus-cxx/dbus-cxx-config.h>
16#include <dbus-cxx/headerlog.h>
17#include <dbus-cxx/utility.h>
18#include <stddef.h>
19#include <functional>
20#include <memory>
21#include <mutex>
22#include <sstream>
23#include <string>
24#include <vector>
25#include "enums.h"
26#include "error.h"
27#include <sigc++/sigc++.h>
28
29#ifndef DBUSCXX_METHODBASE_H
30#define DBUSCXX_METHODBASE_H
31
32namespace DBus {
33
34class Connection;
35class Message;
36class ReturnMessage;
37
49protected:
50
51 MethodBase( const std::string& name );
52
53protected:
54 uint32_t sendMessage( std::shared_ptr<Connection> connection, const std::shared_ptr<const Message> );
55
56public:
57 virtual ~MethodBase();
58
59 const std::string& name() const;
60
61 virtual HandlerResult handle_call_message( std::shared_ptr<Connection> connection, std::shared_ptr<const CallMessage> message ) = 0;
62
64 virtual std::string introspect( int = 0 ) const { return std::string(); };
65
66 std::string arg_name( size_t i ) const;
67
68 void set_arg_name( size_t i, const std::string& name );
69
70 const std::vector<std::string>& arg_names() const;
71
72private:
73 class priv_data;
74
75 DBUS_CXX_PROPAGATE_CONST( std::unique_ptr<priv_data> ) m_priv;
76};
77
78template <typename T_type>
79class Method : public MethodBase {
80private:
81 Method( const std::string& name ) : MethodBase( name ) {}
82
83public:
84 static std::shared_ptr<Method<T_type>> create( const std::string& name ) {
85 return std::shared_ptr<Method<T_type>>( new Method<T_type>( name ) );
86 }
87
88 void set_method( sigc::slot<T_type> slot ) { m_slot = slot; }
89
90 virtual std::string introspect( int space_depth = 0 ) const {
91 std::ostringstream sout;
92 std::string spaces;
94
95 for( int i = 0; i < space_depth; i++ ) { spaces += " "; }
96
97 sout << spaces << "<method name=\"" << name() << "\">\n";
98 sout << method_sig_gen.introspect( arg_names(), 0, spaces + " " );
99 sout << spaces << "</method>\n";
100 return sout.str();
101 }
102
103 virtual HandlerResult handle_call_message( std::shared_ptr<Connection> connection, std::shared_ptr<const CallMessage> message ) {
104 std::ostringstream debug_str;
106
107 debug_str << "DBus::Method<";
108 debug_str << method_sig_gen.debug_string();
109 debug_str << ">::handle_call_message method=";
110 debug_str << name();
111 DBUSCXX_DEBUG_STDSTR( "DBus.Method", debug_str.str() );
112
113 if( !connection || !message ) { return HandlerResult::Not_Handled; }
114
115 try {
116 std::shared_ptr<ReturnMessage> retmsg = message->create_reply();
117
118 if( !retmsg ) { return HandlerResult::Not_Handled; }
119
120 method_sig_gen.extractAndCall( message, retmsg, m_slot );
121
122 sendMessage( connection, retmsg );
123 } catch( ErrorInvalidTypecast& e ) {
124 std::shared_ptr<ErrorMessage> errmsg = message->create_error_reply();
125
126 if( !errmsg ) { return HandlerResult::Not_Handled; }
127
128 errmsg->set_name(DBUSCXX_ERROR_INVALID_SIGNATURE);
129 if( e.what() ){
130 errmsg << e.what();
131 }
132
133 sendMessage( connection, errmsg );
134 } catch( const std::exception& e ) {
135 std::shared_ptr<ErrorMessage> errmsg = message->create_error_reply();
136
137 if( !errmsg ) { return HandlerResult::Not_Handled; }
138
139 errmsg->set_name(DBUSCXX_ERROR_FAILED);
140 if( e.what() ){
141 errmsg << e.what();
142 }
143
144 sendMessage( connection, errmsg );
145 } catch( ... ) {
146 std::ostringstream stream;
147 stream << "DBus-cxx " << DBUS_CXX_PACKAGE_MAJOR_VERSION << "."
148 << DBUS_CXX_PACKAGE_MINOR_VERSION << "."
149 << DBUS_CXX_PACKAGE_MICRO_VERSION
150 << ": unknown error(uncaught exception)";
151 std::shared_ptr<ErrorMessage> errmsg = message->create_error_reply();
152
153 if( !errmsg ) { return HandlerResult::Not_Handled; }
154
155 errmsg->set_name(DBUSCXX_ERROR_FAILED);
156 errmsg << stream.str();
157
158 sendMessage( connection, errmsg );
159 }
160
162 }
163
164
165private:
166 sigc::slot<T_type> m_slot;
167};
168
169}
170
171#endif
Definition: error.h:341
const char * what() const noexcept
Definition: error.cpp:47
Base class for all methods(proxy and local).
Definition: methodbase.h:48
virtual std::string introspect(int=0) const
Returns a DBus XML description of this interface.
Definition: methodbase.h:64
std::string arg_name(size_t i) const
Definition: methodbase.cpp:43
const std::vector< std::string > & arg_names() const
Definition: methodbase.cpp:56
virtual HandlerResult handle_call_message(std::shared_ptr< Connection > connection, std::shared_ptr< const CallMessage > message)=0
MethodBase(const std::string &name)
Definition: methodbase.cpp:24
uint32_t sendMessage(std::shared_ptr< Connection > connection, const std::shared_ptr< const Message >)
Definition: methodbase.cpp:51
const std::string & name() const
Definition: methodbase.cpp:31
DBUS_CXX_PROPAGATE_CONST(std::unique_ptr< priv_data >) m_priv
void set_arg_name(size_t i, const std::string &name)
Definition: methodbase.cpp:35
virtual ~MethodBase()
Definition: methodbase.cpp:29
Definition: methodbase.h:79
virtual std::string introspect(int space_depth=0) const
Definition: methodbase.h:90
Method(const std::string &name)
Definition: methodbase.h:81
static std::shared_ptr< Method< T_type > > create(const std::string &name)
Definition: methodbase.h:84
void set_method(sigc::slot< T_type > slot)
Definition: methodbase.h:88
virtual HandlerResult handle_call_message(std::shared_ptr< Connection > connection, std::shared_ptr< const CallMessage > message)
Definition: methodbase.h:103
sigc::slot< T_type > m_slot
Definition: methodbase.h:166
#define DBUSCXX_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
Definition: dbus-error.h:17
#define DBUSCXX_ERROR_INVALID_SIGNATURE
A type signature is not valid.
Definition: dbus-error.h:104
#define DBUSCXX_DEBUG_STDSTR(logger, message)
Definition: headerlog.h:27
Global DBus namespace, where everything happens.
Definition: callmessage.cpp:18
HandlerResult
Definition: enums.h:95
@ Not_Handled
This message was not handled for some reason.
@ Handled
This message was handled appropriately.
Definition: utility.h:235