From c7489c8aa852b5dfc1e565743102b7ca058ca286 Mon Sep 17 00:00:00 2001 From: ruglory Date: Wed, 25 Feb 2009 21:50:48 +0000 Subject: [PATCH] Message handling moved to object interface git-svn-id: https://svn.code.sf.net/p/qlscribe/svn/trunk@97 cac9541e-1b8d-4bfa-827e-589bba606050 --- lscribed/CMakeLists.txt | 3 +- lscribed/dbuscpp.cpp | 62 ++++++++++++++++- lscribed/dbuscpp.h | 35 ++++++++-- lscribed/{drive.cpp => drivehandler.cpp} | 42 ++++------- lscribed/drivehandler.h | 35 ++++++++++ lscribed/lscribed.h.in | 3 - lscribed/lscribed.pro | 10 ++- lscribed/main.cpp | 78 +++------------------ lscribed/manager.cpp | 89 ------------------------ lscribed/managerhandler.cpp | 71 +++++++++++++++++++ lscribed/managerhandler.h | 35 ++++++++++ 11 files changed, 263 insertions(+), 200 deletions(-) rename lscribed/{drive.cpp => drivehandler.cpp} (74%) create mode 100644 lscribed/drivehandler.h delete mode 100644 lscribed/manager.cpp create mode 100644 lscribed/managerhandler.cpp create mode 100644 lscribed/managerhandler.h diff --git a/lscribed/CMakeLists.txt b/lscribed/CMakeLists.txt index cdeb88a..8c0b26e 100644 --- a/lscribed/CMakeLists.txt +++ b/lscribed/CMakeLists.txt @@ -30,7 +30,8 @@ IF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_COMPILER_IS_GNUCXX ) SET( CMAKE_EXE_LINKER_FLAGS "-m32 -pthread ${CMAKE_EXE_LINKER_FLAGS}" ) ENDIF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_COMPILER_IS_GNUCXX ) -SET( LSCRIBED_SRCS main.cpp dbuscpp.cpp manager.cpp drive.cpp ) +SET( LSCRIBED_SRCS main.cpp dbuscpp.cpp managerhandler.cpp drivehandler.cpp + introspecthandler.cpp ) ADD_DEFINITIONS( -Wall ) diff --git a/lscribed/dbuscpp.cpp b/lscribed/dbuscpp.cpp index 4c7e5c9..416c345 100644 --- a/lscribed/dbuscpp.cpp +++ b/lscribed/dbuscpp.cpp @@ -22,6 +22,51 @@ using namespace DBusCpp; +MessageHandler::~MessageHandler() +{ +} + +std::string MessageHandler::generateInrospectHeader( const std::string &nodename ) +{ + std::string rez = ""; + + rez += " " + " " + " " + " " + ""; + return rez; +} + +namespace { + DBusObjectPathVTable vtable; + DBusHandlerResult processMessage( DBusConnection *connPtr, + DBusMessage *messagePtr, + void *data ) + { + Message message = Message::parameter( messagePtr ); + return reinterpret_cast< MessageHandler * >( data )->processMessage( message ); + } + } + +Connection::Connection( DBusConnection *conn ) + : m_connection( conn ) +{ + vtable.message_function = processMessage; +} + +Connection::~Connection() +{ + for( Handlers::iterator it = m_handlers.begin(); it != m_handlers.end(); ++it ) { + dbus_connection_unregister_object_path( m_connection, it->first.c_str() ); + delete it->second; + } +} + dbus_uint32_t Connection::send( const Message &msg ) { dbus_uint32_t rez; @@ -29,6 +74,17 @@ dbus_uint32_t Connection::send( const Message &msg ) return rez; } +void Connection::registerHandler( const std::string &path, MessageHandler *handler, bool fallback ) +{ + handler->m_connection = this; + m_handlers.insert( std::make_pair( path, handler ) ); + if( fallback ) + dbus_connection_register_fallback( m_connection, path.c_str(), &vtable, handler ); + else + dbus_connection_register_object_path( m_connection, path.c_str(), &vtable, handler ); +} + + MessageIter::MessageIter( const MessageIter &an ) : m_iter( an.m_iter ), m_container( an.m_container ) { @@ -74,12 +130,12 @@ Message::Message( DBusMessage *msg, bool ownership ) dbus_message_ref( m_message ); } -Message Message::newMethodReturn() +Message Message::newMethodReturn() const { return Message( dbus_message_new_method_return( m_message ), true ); } -Message Message::newError( const char *error, const char *message ) +Message Message::newError( const char *error, const char *message ) const { return Message( dbus_message_new_error( m_message, error, message ), true ); } @@ -96,7 +152,7 @@ void Message::append( const char *str ) dbus_message_append_args( m_message, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID ); } -const char *Message::path() +const char *Message::path() const { return dbus_message_get_path( m_message ); } diff --git a/lscribed/dbuscpp.h b/lscribed/dbuscpp.h index 16fe8fd..481f2e0 100644 --- a/lscribed/dbuscpp.h +++ b/lscribed/dbuscpp.h @@ -23,19 +23,44 @@ #include #include +#include namespace DBusCpp { class Message; +class Connection; + +class MessageHandler { +public: + MessageHandler() : m_connection( 0 ) {} + virtual ~MessageHandler(); + + virtual DBusHandlerResult processMessage( const Message &msg ) = 0; + + Connection *connection() const { return m_connection; } + + static std::string generateInrospectHeader( const std::string &nodename = std::string() ); + + friend class Connection; + +private: + Connection *m_connection; +}; class Connection { public: - Connection( DBusConnection *conn ) : m_connection( conn ) {} + Connection( DBusConnection *conn ); + ~Connection(); dbus_uint32_t send( const Message &msg ); + void registerHandler( const std::string &path, MessageHandler *handler, bool fallback ); + DBusConnection *ptr() const { return m_connection; } private: + typedef std::map< std::string, MessageHandler * > Handlers; + DBusConnection *m_connection; + Handlers m_handlers; }; class MessageIter { @@ -63,17 +88,17 @@ public: static Message parameter( DBusMessage *msg ) { return Message( msg, false ); } - Message newMethodReturn(); - Message newError( const char *error, const char *message ); + Message newMethodReturn() const; + Message newError( const char *error, const char *message ) const; - bool isMethodCall( const char *interface, const char *method ) + bool isMethodCall( const char *interface, const char *method ) const { return dbus_message_is_method_call( m_message, interface, method ); } MessageIter appendIter(); void append( const std::string &str ) { append( str.c_str() ); } void append( const char *str ); - const char *path(); + const char *path() const; friend class Connection; private: diff --git a/lscribed/drive.cpp b/lscribed/drivehandler.cpp similarity index 74% rename from lscribed/drive.cpp rename to lscribed/drivehandler.cpp index 2e56713..8043122 100644 --- a/lscribed/drive.cpp +++ b/lscribed/drivehandler.cpp @@ -20,19 +20,15 @@ #include -#include "dbuscpp.h" +#include "drivehandler.h" #include "lscribed.h" +using namespace DBusCpp; + Drives drives; static const char *strDriveIntrospect = -"\ - \ - \ - \ - \ - \ - \ +"\ \ \ \ @@ -62,19 +58,14 @@ static const char *strDriveIntrospect = \ \ \ - \ -"; + "; -DBusHandlerResult processDriveMessage( DBusConnection *connPtr, DBusMessage *messagePtr, void *data ) +DBusHandlerResult DriveHandler::processMessage( const Message &msg ) { DBusHandlerResult rez = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - using namespace DBusCpp; - Connection conn( connPtr ); - Message message = Message::parameter( messagePtr ); - - const char *path = message.path(); + const char *path = msg.path(); if( !path ) return rez; @@ -84,23 +75,20 @@ DBusHandlerResult processDriveMessage( DBusConnection *connPtr, DBusMessage *mes if( item[ 0 ] == '/' ) ++item; - if( message.isMethodCall( "org.freedesktop.DBus.Introspectable", "Introspect" ) ) { + if( msg.isMethodCall( "org.freedesktop.DBus.Introspectable", "Introspect" ) ) { - - std::string introspect = introspectHeader; + std::string introspect = generateInrospectHeader(); if( strcmp( item, "drives" ) == 0 ) { - introspect += ""; - putIntrospectInterface( introspect ); for( Drives::const_iterator it = drives.begin(); it != drives.end(); ++it ) introspect += "first + "\"/>"; - introspect += ""; } else introspect += strDriveIntrospect; + introspect += ""; - Message reply = message.newMethodReturn(); + Message reply = msg.newMethodReturn(); reply.append( introspect ); - conn.send( reply ); + connection()->send( reply ); return rez = DBUS_HANDLER_RESULT_HANDLED; } @@ -109,10 +97,10 @@ DBusHandlerResult processDriveMessage( DBusConnection *connPtr, DBusMessage *mes return rez; std::cout << "calling method on item " << item << std::endl; - if( message.isMethodCall( "org.lightscribe.drive", "name" ) ) { - Message reply = message.newMethodReturn(); + if( msg.isMethodCall( "org.lightscribe.drive", "name" ) ) { + Message reply = msg.newMethodReturn(); reply.append( f->second ); - conn.send( reply ); + connection()->send( reply ); return rez = DBUS_HANDLER_RESULT_HANDLED; } return rez; diff --git a/lscribed/drivehandler.h b/lscribed/drivehandler.h new file mode 100644 index 0000000..a79291b --- /dev/null +++ b/lscribed/drivehandler.h @@ -0,0 +1,35 @@ +/* qlscribe - Qt based application to print lightScribe discs + + Copyright (C) 2009 Vyacheslav Kononenko + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + $Id$ */ + +#ifndef DRIVEHANDLER_H +#define DRIVEHANDLER_H + +#include "dbuscpp.h" + +namespace DBusCpp { + +class DriveHandler : public MessageHandler { +public: + virtual DBusHandlerResult processMessage( const Message &msg ); +}; + +} + +#endif // DRIVEHANDLER_H diff --git a/lscribed/lscribed.h.in b/lscribed/lscribed.h.in index fc0987d..92d3823 100644 --- a/lscribed/lscribed.h.in +++ b/lscribed/lscribed.h.in @@ -27,9 +27,6 @@ typedef std::map< std::string, std::string > Drives; extern Drives drives; -extern const char *introspectHeader; -void putIntrospectInterface( std::string &str ); - const char * const DBusServiceName = "@QLSCRIBE_DBUS_SERVICE@"; const char * const DBusManagerPath = "@QLSCRIBE_DBUS_MANAGER@"; const char * const DBusDrivesPath = "@QLSCRIBE_DBUS_DRIVES@"; diff --git a/lscribed/lscribed.pro b/lscribed/lscribed.pro index 9c91a10..e784e8f 100644 --- a/lscribed/lscribed.pro +++ b/lscribed/lscribed.pro @@ -9,6 +9,10 @@ INCLUDEPATH += /usr/include/dbus-1.0/ CONFIG += staticlib SOURCES += main.cpp \ dbuscpp.cpp \ - manager.cpp \ - drive.cpp -HEADERS += dbuscpp.h + managerhandler.cpp \ + drivehandler.cpp \ + introspecthandler.cpp +HEADERS += dbuscpp.h \ + drivehandler.h \ + managerhandler.h \ + introspecthandler.h diff --git a/lscribed/main.cpp b/lscribed/main.cpp index 10a8cdc..2ccfbcf 100644 --- a/lscribed/main.cpp +++ b/lscribed/main.cpp @@ -23,75 +23,22 @@ #include "lscribed.h" #include "dbuscpp.h" - -DBusHandlerResult processManagerMessage( DBusConnection *connPtr, DBusMessage *messagePtr, void *data ); -DBusHandlerResult processDriveMessage( DBusConnection *connPtr, DBusMessage *messagePtr, void *data ); - -const char *introspectHeader = -""; - -void putIntrospectInterface( std::string &str ) -{ - str += "" - " " - " " - " " - ""; -} - -DBusHandlerResult processIntrospectMessage( DBusConnection *connPtr, DBusMessage *messagePtr, void *data ) -{ - using namespace DBusCpp; - - Connection conn( connPtr ); - Message message = Message::parameter( messagePtr ); - - if( message.isMethodCall( "org.freedesktop.DBus.Introspectable", "Introspect" ) ) { - const char *path = message.path(); - if( !path ) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - int pathlen = strlen( path ); - - std::string introspect = introspectHeader; - introspect += ""; - putIntrospectInterface( introspect ); - - if( strncmp( path, DBusManagerPath, pathlen ) == 0 ) { - if( pathlen != 1 ) ++pathlen; - const char *end = strchr( DBusManagerPath + pathlen, '/' ); - if( end ) { - char sub[128]; - const int sublen = end - DBusManagerPath - pathlen; - strncpy( sub, DBusManagerPath + pathlen, sublen ); - sub[ sublen ] = 0; - introspect += std::string( ""; - } else - introspect += ""; - } - introspect += ""; - - Message reply = message.newMethodReturn(); - reply.append( introspect ); - conn.send( reply ); - return DBUS_HANDLER_RESULT_HANDLED; - } - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} +#include "introspecthandler.h" +#include "managerhandler.h" +#include "drivehandler.h" int main( int argc, char **argv ) { DBusError err; dbus_error_init( &err ); - DBusConnection *conn = dbus_bus_get( DBUS_BUS_SYSTEM, &err ); + DBusCpp::Connection conn ( dbus_bus_get( DBUS_BUS_SYSTEM, &err ) ); if( dbus_error_is_set( &err ) ) { std::cerr << "dbus_bus_get() error: " << err.message << std::endl; dbus_error_free( &err ); return 1; } - int ret = dbus_bus_request_name( conn, DBusServiceName, DBUS_NAME_FLAG_REPLACE_EXISTING, &err ); + int ret = dbus_bus_request_name( conn.ptr(), DBusServiceName, DBUS_NAME_FLAG_REPLACE_EXISTING, &err ); if( dbus_error_is_set( &err ) ) { std::cerr << "dbus_bus_request_name error: " << err.message << std::endl; dbus_error_free( &err ); @@ -101,22 +48,15 @@ int main( int argc, char **argv ) std::cerr << "could not get ownership of \"" << DBusServiceName << "\" terminating" << std::endl; return 3; } - DBusObjectPathVTable vtable; - ::memset( &vtable, 0, sizeof( vtable ) ); - vtable.message_function = processIntrospectMessage; - dbus_connection_register_fallback( conn, "/", &vtable, 0 ); - - vtable.message_function = processManagerMessage; - dbus_connection_register_object_path( conn, DBusManagerPath, &vtable, 0 ); - - vtable.message_function = processDriveMessage; - dbus_connection_register_fallback( conn, DBusDrivesPath, &vtable, 0 ); + conn.registerHandler( "/", new DBusCpp::IntrospectHandler, true ); + conn.registerHandler( DBusManagerPath, new DBusCpp::ManagerHandler, false ); + conn.registerHandler( DBusDrivesPath, new DBusCpp::DriveHandler, true ); drives.insert( std::make_pair( "drive0", "DRIVE 0" ) ); drives.insert( std::make_pair( "drive1", "DRIVE 1" ) ); - while( dbus_connection_read_write_dispatch( conn, -1 ) ); + while( dbus_connection_read_write_dispatch( conn.ptr(), -1 ) ); return 0; } diff --git a/lscribed/manager.cpp b/lscribed/manager.cpp deleted file mode 100644 index a061bcc..0000000 --- a/lscribed/manager.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* qlscribe - Qt based application to print lightScribe discs - - Copyright (C) 2009 Vyacheslav Kononenko - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - $Id$ */ - -#include "dbuscpp.h" -#include "lscribed.h" - -#include - -static const char *strManagerIntrospect = -"\ -\ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ -"; - - -DBusHandlerResult processManagerMessage( DBusConnection *connPtr, DBusMessage *messagePtr, void *data ) -{ - using namespace DBusCpp; - - Connection conn( connPtr ); - Message message = Message::parameter( messagePtr ); - - /*std::cout << "message received" - << "type" << dbus_message_get_type (message) - << " path "<< ( dbus_message_get_path (message) ? dbus_message_get_path (message) : "no path" ) - << " interface " << ( dbus_message_get_interface (message) ? dbus_message_get_interface (message) : "no interface" ) - << " member " << ( dbus_message_get_member (message) ? dbus_message_get_member (message) : "no member" ) - << " destination " << ( dbus_message_get_destination (message) ? dbus_message_get_destination (message) : "null" )<< std::endl;*/ - - - if( message.isMethodCall( "org.freedesktop.DBus.Introspectable", "Introspect" ) ) { - Message reply = message.newMethodReturn(); - reply.append( strManagerIntrospect ); - conn.send( reply ); - return DBUS_HANDLER_RESULT_HANDLED; - } - - if( message.isMethodCall( "org.lightscribe.printManager", "getDrives" ) ) { - Message reply = message.newMethodReturn(); - - MessageIter args = reply.appendIter(); - { - MessageIter sub = args.openContainer( DBUS_TYPE_ARRAY, "{ss}" ); - - for( Drives::const_iterator it = drives.begin(); it != drives.end(); ++it ) { - MessageIter itemIterator = sub.openContainer( DBUS_TYPE_DICT_ENTRY, 0 ); - - itemIterator.append( std::string( DBusDrivesPath ) + "/" + it->first ); - itemIterator.append( it->second ); - } - } - - conn.send( reply ); - return DBUS_HANDLER_RESULT_HANDLED; - } - - //Message reply = message.newError( DBUS_ERROR_NOT_SUPPORTED, "method is not supported" ); - //conn.send( reply ); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - - diff --git a/lscribed/managerhandler.cpp b/lscribed/managerhandler.cpp new file mode 100644 index 0000000..051ea8e --- /dev/null +++ b/lscribed/managerhandler.cpp @@ -0,0 +1,71 @@ +/* qlscribe - Qt based application to print lightScribe discs + + Copyright (C) 2009 Vyacheslav Kononenko + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + $Id$ */ + +#include "managerhandler.h" +#include "lscribed.h" + +using namespace DBusCpp; + +#include + +static const char *strManagerIntrospect = +"\ + \ + \ + \ + "; + + +DBusHandlerResult ManagerHandler::processMessage( const Message &msg ) +{ + if( msg.isMethodCall( "org.freedesktop.DBus.Introspectable", "Introspect" ) ) { + Message reply = msg.newMethodReturn(); + std::string introspect = generateInrospectHeader(); + introspect += strManagerIntrospect; + introspect += ""; + reply.append( introspect ); + + connection()->send( reply ); + return DBUS_HANDLER_RESULT_HANDLED; + } + + if( msg.isMethodCall( "org.lightscribe.printManager", "getDrives" ) ) { + Message reply = msg.newMethodReturn(); + + MessageIter args = reply.appendIter(); + { + MessageIter sub = args.openContainer( DBUS_TYPE_ARRAY, "{ss}" ); + + for( Drives::const_iterator it = drives.begin(); it != drives.end(); ++it ) { + MessageIter itemIterator = sub.openContainer( DBUS_TYPE_DICT_ENTRY, 0 ); + + itemIterator.append( std::string( DBusDrivesPath ) + "/" + it->first ); + itemIterator.append( it->second ); + } + } + + connection()->send( reply ); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + + diff --git a/lscribed/managerhandler.h b/lscribed/managerhandler.h new file mode 100644 index 0000000..b42c022 --- /dev/null +++ b/lscribed/managerhandler.h @@ -0,0 +1,35 @@ +/* qlscribe - Qt based application to print lightScribe discs + + Copyright (C) 2009 Vyacheslav Kononenko + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + $Id$ */ + +#ifndef MANAGERHANDLER_H +#define MANAGERHANDLER_H + +#include "dbuscpp.h" + +namespace DBusCpp { + +class ManagerHandler : public MessageHandler { +public: + virtual DBusHandlerResult processMessage( const Message &msg ); +}; + +} + +#endif // INTROSPECTHANDLER_H