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>
13 #include <dbus-cxx/callmessage.h>
15 #include <dbus-cxx/errormessage.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 
32 namespace DBus {
33 
34 class Connection;
35 class Message;
36 class ReturnMessage;
37 
48 class MethodBase {
49 protected:
50 
51  MethodBase( const std::string& name );
52 
53 protected:
54  uint32_t sendMessage( std::shared_ptr<Connection> connection, const std::shared_ptr<const Message> );
55 
56 public:
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 space_depth = 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 
72 private:
73  class priv_data;
74 
75  DBUS_CXX_PROPAGATE_CONST( std::unique_ptr<priv_data> ) m_priv;
76 };
77 
78 template <typename T_type>
79 class Method : public MethodBase {
80 private:
81  Method( const std::string& name ) : MethodBase( name ) {}
82 
83 public:
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 = ErrorMessage::create( message, DBUSCXX_ERROR_INVALID_SIGNATURE, e.what() );
125 
126  if( !errmsg ) { return HandlerResult::Not_Handled; }
127 
128  sendMessage( connection, errmsg );
129  } catch( const std::exception& e ) {
130  std::shared_ptr<ErrorMessage> errmsg = ErrorMessage::create( message, DBUSCXX_ERROR_FAILED, e.what() );
131 
132  if( !errmsg ) { return HandlerResult::Not_Handled; }
133 
134  sendMessage( connection, errmsg );
135  } catch( ... ) {
136  std::ostringstream stream;
137  stream << "DBus-cxx " << DBUS_CXX_PACKAGE_MAJOR_VERSION << "."
140  << ": unknown error(uncaught exception)";
141  std::shared_ptr<ErrorMessage> errmsg = ErrorMessage::create( message, DBUSCXX_ERROR_FAILED, stream.str() );
142 
143  if( !errmsg ) { return HandlerResult::Not_Handled; }
144 
145  sendMessage( connection, errmsg );
146  }
147 
148  return HandlerResult::Handled;
149  }
150 
151 
152 private:
153  sigc::slot<T_type> m_slot;
154 };
155 
156 }
157 
158 #endif
static std::shared_ptr< ErrorMessage > create()
Definition: errormessage.cpp:31
Base class for all methods(proxy and local).
Definition: methodbase.h:48
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
virtual std::string introspect(int space_depth=0) const
Returns a DBus XML description of this interface.
Definition: methodbase.h:64
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
static std::shared_ptr< Method< T_type > > create(const std::string &name)
Definition: methodbase.h:84
virtual std::string introspect(int space_depth=0) const
Definition: methodbase.h:90
Method(const std::string &name)
Definition: methodbase.h:81
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:153
#define DBUS_CXX_PACKAGE_MAJOR_VERSION
Definition: dbus-cxx-config.h:25
#define DBUS_CXX_PACKAGE_MINOR_VERSION
Definition: dbus-cxx-config.h:26
#define DBUS_CXX_PACKAGE_MICRO_VERSION
Definition: dbus-cxx-config.h:27
#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:234