From f9c9e15267bd0319a8190ba146d7be95c37dac2e Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Sat, 27 Apr 2019 00:21:43 +0900 Subject: Moved source files to "src" folder. Signed-off-by: Michele Calgaro --- CMakeLists.txt | 67 +- dbus-1-tqt.Doxyfile.in | 4 +- src/CMakeLists.txt | 73 ++ src/tools/dbusxml2qt3/LICENSE | 18 + src/tools/dbusxml2qt3/classgen.cpp | 1091 +++++++++++++++++++++ src/tools/dbusxml2qt3/classgen.h | 54 ++ src/tools/dbusxml2qt3/main.cpp | 637 +++++++++++++ src/tools/dbusxml2qt3/methodgen.cpp | 1793 +++++++++++++++++++++++++++++++++++ src/tools/dbusxml2qt3/methodgen.h | 153 +++ src/tqdbusatomic.h | 40 + src/tqdbusconnection.cpp | 408 ++++++++ src/tqdbusconnection.h | 663 +++++++++++++ src/tqdbusconnection_p.h | 177 ++++ src/tqdbusdata.cpp | 1121 ++++++++++++++++++++++ src/tqdbusdata.h | 1223 ++++++++++++++++++++++++ src/tqdbusdataconverter.cpp | 143 +++ src/tqdbusdataconverter.h | 207 ++++ src/tqdbusdatalist.cpp | 786 +++++++++++++++ src/tqdbusdatalist.h | 758 +++++++++++++++ src/tqdbusdatamap.h | 1281 +++++++++++++++++++++++++ src/tqdbuserror.cpp | 216 +++++ src/tqdbuserror.h | 476 ++++++++++ src/tqdbusintegrator.cpp | 689 ++++++++++++++ src/tqdbusmacros.h | 31 + src/tqdbusmarshall.cpp | 1254 ++++++++++++++++++++++++ src/tqdbusmarshall.h | 40 + src/tqdbusmessage.cpp | 263 +++++ src/tqdbusmessage.h | 514 ++++++++++ src/tqdbusmessage_p.h | 52 + src/tqdbusobject.h | 372 ++++++++ src/tqdbusobjectpath.cpp | 79 ++ src/tqdbusobjectpath.h | 119 +++ src/tqdbusproxy.cpp | 209 ++++ src/tqdbusproxy.h | 585 ++++++++++++ src/tqdbusserver.cpp | 60 ++ src/tqdbusserver.h | 53 ++ src/tqdbusunixfd.cpp | 95 ++ src/tqdbusunixfd.h | 150 +++ src/tqdbusvariant.h | 120 +++ tools/dbusxml2qt3/LICENSE | 18 - tools/dbusxml2qt3/classgen.cpp | 1091 --------------------- tools/dbusxml2qt3/classgen.h | 54 -- tools/dbusxml2qt3/main.cpp | 637 ------------- tools/dbusxml2qt3/methodgen.cpp | 1793 ----------------------------------- tools/dbusxml2qt3/methodgen.h | 153 --- tqdbusatomic.h | 40 - tqdbusconnection.cpp | 408 -------- tqdbusconnection.h | 663 ------------- tqdbusconnection_p.h | 177 ---- tqdbusdata.cpp | 1121 ---------------------- tqdbusdata.h | 1223 ------------------------ tqdbusdataconverter.cpp | 143 --- tqdbusdataconverter.h | 207 ---- tqdbusdatalist.cpp | 786 --------------- tqdbusdatalist.h | 758 --------------- tqdbusdatamap.h | 1281 ------------------------- tqdbuserror.cpp | 216 ----- tqdbuserror.h | 476 ---------- tqdbusintegrator.cpp | 689 -------------- tqdbusmacros.h | 31 - tqdbusmarshall.cpp | 1254 ------------------------ tqdbusmarshall.h | 40 - tqdbusmessage.cpp | 263 ----- tqdbusmessage.h | 514 ---------- tqdbusmessage_p.h | 52 - tqdbusobject.h | 372 -------- tqdbusobjectpath.cpp | 79 -- tqdbusobjectpath.h | 119 --- tqdbusproxy.cpp | 209 ---- tqdbusproxy.h | 585 ------------ tqdbusserver.cpp | 60 -- tqdbusserver.h | 53 -- tqdbusunixfd.cpp | 95 -- tqdbusunixfd.h | 150 --- tqdbusvariant.h | 120 --- 75 files changed, 16012 insertions(+), 15992 deletions(-) create mode 100644 src/CMakeLists.txt create mode 100644 src/tools/dbusxml2qt3/LICENSE create mode 100644 src/tools/dbusxml2qt3/classgen.cpp create mode 100644 src/tools/dbusxml2qt3/classgen.h create mode 100644 src/tools/dbusxml2qt3/main.cpp create mode 100644 src/tools/dbusxml2qt3/methodgen.cpp create mode 100644 src/tools/dbusxml2qt3/methodgen.h create mode 100644 src/tqdbusatomic.h create mode 100644 src/tqdbusconnection.cpp create mode 100644 src/tqdbusconnection.h create mode 100644 src/tqdbusconnection_p.h create mode 100644 src/tqdbusdata.cpp create mode 100644 src/tqdbusdata.h create mode 100644 src/tqdbusdataconverter.cpp create mode 100644 src/tqdbusdataconverter.h create mode 100644 src/tqdbusdatalist.cpp create mode 100644 src/tqdbusdatalist.h create mode 100644 src/tqdbusdatamap.h create mode 100644 src/tqdbuserror.cpp create mode 100644 src/tqdbuserror.h create mode 100644 src/tqdbusintegrator.cpp create mode 100644 src/tqdbusmacros.h create mode 100644 src/tqdbusmarshall.cpp create mode 100644 src/tqdbusmarshall.h create mode 100644 src/tqdbusmessage.cpp create mode 100644 src/tqdbusmessage.h create mode 100644 src/tqdbusmessage_p.h create mode 100644 src/tqdbusobject.h create mode 100644 src/tqdbusobjectpath.cpp create mode 100644 src/tqdbusobjectpath.h create mode 100644 src/tqdbusproxy.cpp create mode 100644 src/tqdbusproxy.h create mode 100644 src/tqdbusserver.cpp create mode 100644 src/tqdbusserver.h create mode 100644 src/tqdbusunixfd.cpp create mode 100644 src/tqdbusunixfd.h create mode 100644 src/tqdbusvariant.h delete mode 100644 tools/dbusxml2qt3/LICENSE delete mode 100644 tools/dbusxml2qt3/classgen.cpp delete mode 100644 tools/dbusxml2qt3/classgen.h delete mode 100644 tools/dbusxml2qt3/main.cpp delete mode 100644 tools/dbusxml2qt3/methodgen.cpp delete mode 100644 tools/dbusxml2qt3/methodgen.h delete mode 100644 tqdbusatomic.h delete mode 100644 tqdbusconnection.cpp delete mode 100644 tqdbusconnection.h delete mode 100644 tqdbusconnection_p.h delete mode 100644 tqdbusdata.cpp delete mode 100644 tqdbusdata.h delete mode 100644 tqdbusdataconverter.cpp delete mode 100644 tqdbusdataconverter.h delete mode 100644 tqdbusdatalist.cpp delete mode 100644 tqdbusdatalist.h delete mode 100644 tqdbusdatamap.h delete mode 100644 tqdbuserror.cpp delete mode 100644 tqdbuserror.h delete mode 100644 tqdbusintegrator.cpp delete mode 100644 tqdbusmacros.h delete mode 100644 tqdbusmarshall.cpp delete mode 100644 tqdbusmarshall.h delete mode 100644 tqdbusmessage.cpp delete mode 100644 tqdbusmessage.h delete mode 100644 tqdbusmessage_p.h delete mode 100644 tqdbusobject.h delete mode 100644 tqdbusobjectpath.cpp delete mode 100644 tqdbusobjectpath.h delete mode 100644 tqdbusproxy.cpp delete mode 100644 tqdbusproxy.h delete mode 100644 tqdbusserver.cpp delete mode 100644 tqdbusserver.h delete mode 100644 tqdbusunixfd.cpp delete mode 100644 tqdbusunixfd.h delete mode 100644 tqdbusvariant.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5097178..880eec2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,19 +44,6 @@ tde_setup_install_path( INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/$ tde_setup_install_path( PKGCONFIG_INSTALL_DIR "${LIB_INSTALL_DIR}/pkgconfig" ) -##### install headers ########################### - -install( FILES - tqdbuserror.h tqdbusmessage.h tqdbusconnection.h - tqdbusvariant.h tqdbusobject.h tqdbusproxy.h - tqdbusmacros.h tqdbusdata.h tqdbusdatalist.h - tqdbusdatamap.h tqdbusobjectpath.h tqdbusunixfd.h - tqdbusdataconverter.h - DESTINATION ${INCLUDE_INSTALL_DIR} ) - - -##### install other data ######################## - ##### write pkgconfig file ###################### string( REGEX REPLACE "^${CMAKE_INSTALL_PREFIX}" "\${prefix}" PC_EXEC_PREFIX ${EXEC_INSTALL_PREFIX} ) @@ -68,8 +55,9 @@ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/dbus-1-tqt.pc DESTINATION ${PKGCONFIG ##### build setup ############################### -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include tqt.h" ) +set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TQT_CXX_FLAGS}" ) set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" ) +set( CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined" ) add_definitions( -DDBUS_COMPILATION @@ -77,57 +65,16 @@ add_definitions( ${TQT_CFLAGS_OTHER} ) -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${TQT_INCLUDE_DIRS} - ${DBUS_INCLUDE_DIRS} -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### dbus-1-tqt (shared) ######################### +set( APIDOX_HTML_DIRECTORY "usr/share/doc/libdbus-1-tqt/HTML" ) +set( APIDOX_DIRECTORY "${CMAKE_BINARY_DIR}/${APIDOX_HTML_DIRECTORY}/en" ) -tde_add_library( dbus-1-tqt SHARED AUTOMOC - SOURCES ${dbus_tqt_MOCS} - tqdbusconnection.cpp tqdbuserror.cpp tqdbusintegrator.cpp - tqdbusmarshall.cpp tqdbusmessage.cpp tqdbusserver.cpp - tqdbusproxy.cpp tqdbusdata.cpp tqdbusdatalist.cpp - tqdbusobjectpath.cpp tqdbusunixfd.cpp - tqdbusdataconverter.cpp - VERSION 0.0.0 - LINK ${TQT_LIBRARIES} ${DBUS_LIBRARIES} - DESTINATION ${LIB_INSTALL_DIR} -) +##### source directories ######################## -##### dbusxml2qt3 (executable) ################## +add_subdirectory( src ) -tde_add_executable( dbusxml2qt3 - SOURCES - tools/dbusxml2qt3/classgen.cpp - tools/dbusxml2qt3/main.cpp - tools/dbusxml2qt3/methodgen.cpp - LINK ${TQT_LIBRARIES} - DESTINATION ${BIN_INSTALL_DIR} -) +##### write configure files ##################### -##### add apidox targets ############ -set( APIDOX_HTML_DIRECTORY "usr/share/doc/libdbus-1-tqt/HTML" ) -set( APIDOX_DIRECTORY "${CMAKE_BINARY_DIR}/${APIDOX_HTML_DIRECTORY}/en" ) configure_file( ${CMAKE_SOURCE_DIR}/dbus-1-tqt.Doxyfile.in ${CMAKE_BINARY_DIR}/dbus-1-tqt.Doxyfile ) -add_custom_target( apidox - COMMAND test -d ${APIDOX_DIRECTORY} || mkdir -p ${APIDOX_DIRECTORY} - COMMAND doxygen ${CMAKE_BINARY_DIR}/dbus-1-tqt.Doxyfile - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - -add_custom_target( install-apidox - COMMAND "./install_apidox" "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" "${APIDOX_HTML_DIRECTORY}" - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/cmake/" - ) diff --git a/dbus-1-tqt.Doxyfile.in b/dbus-1-tqt.Doxyfile.in index bdb4455..396e8f2 100644 --- a/dbus-1-tqt.Doxyfile.in +++ b/dbus-1-tqt.Doxyfile.in @@ -582,7 +582,7 @@ WARN_LOGFILE = # ./include \ # ./scripts -INPUT = ${CMAKE_SOURCE_DIR} +INPUT = ${CMAKE_SOURCE_DIR}/src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -651,7 +651,7 @@ RECURSIVE = NO # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = tools doc admin cmake obj-x86_64-linux-gnu dbus-apidocs debian +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..fa3fa5c --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,73 @@ + ################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${TQT_INCLUDE_DIRS} + ${DBUS_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### install headers ########################### + +install( FILES + tqdbuserror.h tqdbusmessage.h tqdbusconnection.h + tqdbusvariant.h tqdbusobject.h tqdbusproxy.h + tqdbusmacros.h tqdbusdata.h tqdbusdatalist.h + tqdbusdatamap.h tqdbusobjectpath.h tqdbusunixfd.h + tqdbusdataconverter.h + DESTINATION ${INCLUDE_INSTALL_DIR} ) + + +##### dbus-1-tqt (shared) ######################### + +tde_add_library( dbus-1-tqt SHARED AUTOMOC + SOURCES ${dbus_tqt_MOCS} + tqdbusconnection.cpp tqdbuserror.cpp tqdbusintegrator.cpp + tqdbusmarshall.cpp tqdbusmessage.cpp tqdbusserver.cpp + tqdbusproxy.cpp tqdbusdata.cpp tqdbusdatalist.cpp + tqdbusobjectpath.cpp tqdbusunixfd.cpp + tqdbusdataconverter.cpp + VERSION 0.0.0 + LINK ${TQT_LIBRARIES} ${DBUS_LIBRARIES} + DESTINATION ${LIB_INSTALL_DIR} +) + + +##### dbusxml2qt3 (executable) ################## + +tde_add_executable( dbusxml2qt3 + SOURCES + tools/dbusxml2qt3/classgen.cpp + tools/dbusxml2qt3/main.cpp + tools/dbusxml2qt3/methodgen.cpp + LINK ${TQT_LIBRARIES} + DESTINATION ${BIN_INSTALL_DIR} +) + + +##### add apidox targets ############ + +add_custom_target( apidox + COMMAND test -d ${APIDOX_DIRECTORY} || mkdir -p ${APIDOX_DIRECTORY} + COMMAND doxygen ${CMAKE_BINARY_DIR}/dbus-1-tqt.Doxyfile + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + +add_custom_target( install-apidox + COMMAND "./install_apidox" "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" "${APIDOX_HTML_DIRECTORY}" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/cmake/" + ) diff --git a/src/tools/dbusxml2qt3/LICENSE b/src/tools/dbusxml2qt3/LICENSE new file mode 100644 index 0000000..1edf08c --- /dev/null +++ b/src/tools/dbusxml2qt3/LICENSE @@ -0,0 +1,18 @@ +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/tools/dbusxml2qt3/classgen.cpp b/src/tools/dbusxml2qt3/classgen.cpp new file mode 100644 index 0000000..12051c0 --- /dev/null +++ b/src/tools/dbusxml2qt3/classgen.cpp @@ -0,0 +1,1091 @@ +/* +* Copyright (C) 2007 Kevin Krammer +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +// TQt includes +#include +#include +#include +#include + +// local includes +#include "classgen.h" +#include "methodgen.h" + +class Set : public TQMap +{ +public: + void insertString(const TQString& key) + { + insert(key, true); + } + + void removeString(const TQString& key) + { + erase(key); + } + + void insertStringList(const TQStringList& list) + { + TQStringList::const_iterator it = list.begin(); + TQStringList::const_iterator endIt = list.end(); + for (; it != endIt; ++it) + { + insert(*it, true); + } + } +}; + +static void writeFileHeader(TQTextStream& stream) +{ + stream << "// File autogenerated" << endl; + stream << endl; +} + +static void writeFileFooter(TQTextStream& stream) +{ + stream << "// End of File" << endl; + stream << endl; +} + +static void openIncludeGuard(const TQString& className, TQTextStream& stream) +{ + stream << "#if !defined(" << className.upper() << "_H_INCLUDED)" << endl; + stream << "#define " << className.upper() << "_H_INCLUDED" << endl; + stream << endl; +} + +static void closeIncludeGuard(const TQString& className, TQTextStream& stream) +{ + stream << "#endif //" << className.upper() << "_H_INCLUDED" << endl; + stream << endl; +} + +static void openNamespaces(const TQStringList& namespaces, TQTextStream& stream) +{ + TQStringList::const_iterator it = namespaces.begin(); + TQStringList::const_iterator endIt = namespaces.end(); + for (; it != endIt; ++it) + { + stream << "namespace " << *it << endl; + stream << "{" << endl; + } + stream << endl; +} + +static void closeNamespaces(const TQStringList& namespaces, TQTextStream& stream) +{ + TQStringList::const_iterator it = namespaces.end(); + TQStringList::const_iterator endIt = namespaces.end(); + for (--it; it != endIt; --it) + { + stream << "}; // namespace " << *it << endl; + stream << endl; + } +} + +static void writeIncludes(const TQString& description, const TQStringList& includes, + TQTextStream& stream) +{ + if (includes.isEmpty()) return; + + stream << "// " << description << " includes" << endl; + + TQStringList::const_iterator it = includes.begin(); + TQStringList::const_iterator endIt = includes.end(); + for (;it != endIt; ++it) + { + stream << "#include " << *it << endl; + } + + stream << endl; +} + +static void extractHeaderIncludes(const Method& method, + TQMap& includes) +{ + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + for (; it != endIt; ++it) + { + if ((*it).headerIncludes.isEmpty()) continue; + + TQMap::const_iterator mapIt = + (*it).headerIncludes.begin(); + TQMap::const_iterator mapEndIt = + (*it).headerIncludes.end(); + + for (; mapIt != mapEndIt; ++mapIt) + { + includes[mapIt.key()].insertStringList(mapIt.data()); + } + } +} + +static void extractForwardDeclarations(const Method& method, Set& forwards) +{ + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + for (; it != endIt; ++it) + { + if ((*it).forwardDeclarations.isEmpty()) continue; + + forwards.insertStringList((*it).forwardDeclarations); + } +} + +static void writeHeaderIncludes(const Class& classData, Class::Role role, + TQTextStream& stream) +{ + TQMap includes; + Set forwards; + + TQValueList::const_iterator it = classData.methods.begin(); + TQValueList::const_iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + if ((*it).arguments.isEmpty()) continue; + + extractHeaderIncludes(*it, includes); + extractForwardDeclarations(*it, forwards); + } + + it = classData.msignals.begin(); + endIt = classData.msignals.end(); + for (; it != endIt; ++it) + { + if ((*it).arguments.isEmpty()) continue; + + extractHeaderIncludes(*it, includes); + extractForwardDeclarations(*it, forwards); + } + + + TQValueList::const_iterator propertyIt = classData.properties.begin(); + TQValueList::const_iterator propertyEndIt = classData.properties.end(); + for (; propertyIt != propertyEndIt; ++propertyIt) + { + if (!(*propertyIt).headerIncludes.isEmpty()) + { + TQMap::const_iterator mapIt = + (*propertyIt).headerIncludes.begin(); + TQMap::const_iterator mapEndIt = + (*propertyIt).headerIncludes.end(); + + for (; mapIt != mapEndIt; ++mapIt) + { + includes[mapIt.key()].insertStringList(mapIt.data()); + } + } + + if (!(*propertyIt).forwardDeclarations.isEmpty()) + { + forwards.insertStringList((*propertyIt).forwardDeclarations); + } + } + + switch (role) + { + case Class::Interface: + includes["tqdbus"].insertString(""); + forwards.insertString("class TQT_DBusError"); + forwards.insertString("class TQDomElement"); + if (!classData.msignals.isEmpty()) + forwards.insertString("class TQString"); + if (!classData.asyncMethods.isEmpty()) + { + includes["TQt"].insertString(""); + forwards.erase("template class TQMap"); + + includes["tqdbus"].insertString(""); + forwards.erase("class TQT_DBusMessage"); + } + break; + + case Class::Proxy: + includes["TQt"].insertString(""); + forwards.insertString("class TQT_DBusConnection"); + forwards.insertString("class TQT_DBusError"); + forwards.insertString("class TQT_DBusMessage"); + forwards.insertString("class TQT_DBusProxy"); + forwards.insertString("class TQString"); + if (!classData.properties.isEmpty()) + forwards.insertString("class TQT_DBusVariant"); + if (!classData.asyncMethods.isEmpty()) + { + includes["TQt"].insertString(""); + forwards.erase("template class TQMap"); + } + break; + + case Class::Node: + includes["tqdbus"].insertString(""); + forwards.insertString("class TQT_DBusConnection"); + forwards.insertString("class TQString"); + break; + } + + includes["tqdbus"].insertString(""); + + if (!includes["TQt"].isEmpty()) + writeIncludes("TQt", includes["TQt"].keys(), stream); + + if (!includes["tqdbus"].isEmpty()) + writeIncludes("TQt D-Bus", includes["tqdbus"].keys(), stream); + + if (!includes["local"].isEmpty()) + writeIncludes("local", includes["local"].keys(), stream); + + stream << "// forward declarations" << endl; + Set::const_iterator setIt = forwards.begin(); + Set::const_iterator setEndIt = forwards.end(); + for (; setIt != setEndIt; ++setIt) + { + stream << setIt.key() << ";" << endl; + } + stream << endl; +} + +static void extractSourceIncludes(const Method& method, + TQMap& includes) +{ + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + for (; it != endIt; ++it) + { + if ((*it).sourceIncludes.isEmpty()) continue; + + TQMap::const_iterator mapIt = + (*it).sourceIncludes.begin(); + TQMap::const_iterator mapEndIt = + (*it).sourceIncludes.end(); + + for (; mapIt != mapEndIt; ++mapIt) + { + includes[mapIt.key()].insertStringList(mapIt.data()); + } + } +} + +static void writeSourceIncludes(const Class& classData, Class::Role role, + TQTextStream& stream) +{ + TQMap includes; + + TQValueList::const_iterator it = classData.methods.begin(); + TQValueList::const_iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + if ((*it).arguments.isEmpty()) continue; + + extractSourceIncludes(*it, includes); + } + + it = classData.msignals.begin(); + endIt = classData.msignals.end(); + for (; it != endIt; ++it) + { + if ((*it).arguments.isEmpty()) continue; + + extractSourceIncludes(*it, includes); + } + + TQValueList::const_iterator propertyIt = classData.properties.begin(); + TQValueList::const_iterator propertyEndIt = classData.properties.end(); + for (; propertyIt != propertyEndIt; ++propertyIt) + { + if ((*propertyIt).sourceIncludes.isEmpty()) continue; + + TQMap::const_iterator mapIt = + (*propertyIt).sourceIncludes.begin(); + TQMap::const_iterator mapEndIt = + (*propertyIt).sourceIncludes.end(); + + for (; mapIt != mapEndIt; ++mapIt) + { + includes[mapIt.key()].insertStringList(mapIt.data()); + } + } + + switch (role) + { + case Class::Interface: + includes["TQt"].insertString(""); + includes["tqdbus"].insertString(""); + includes["tqdbus"].insertString(""); + break; + + case Class::Proxy: + includes["tqdbus"].insertString(""); + includes["tqdbus"].insertString(""); + includes["tqdbus"].insertString(""); + if (!classData.properties.isEmpty()) + { + includes["tqdbus"].insertString(""); + includes["tqdbus"].insertString(""); + } + break; + + case Class::Node: + includes["TQt"].insertString(""); + includes["TQt"].insertString(""); + includes["tqdbus"].insertString(""); + includes["tqdbus"].insertString(""); + break; + } + + if (!includes["TQt"].isEmpty()) + writeIncludes("TQt", includes["TQt"].keys(), stream); + + if (!includes["tqdbus"].isEmpty()) + writeIncludes("TQt D-Bus", includes["tqdbus"].keys(), stream); + + if (!includes["local"].isEmpty()) + writeIncludes("local", includes["local"].keys(), stream); + + stream << endl; +} + +static void writeInterfaceIncludes(const TQValueList interfaces, + TQTextStream& stream) +{ + stream << "// interface classes includes" << endl; + + TQValueList::const_iterator it = interfaces.begin(); + TQValueList::const_iterator endIt = interfaces.end(); + for (; it != endIt; ++it) + { + stream << "#include \"" << (*it).name.lower() << ".h\"" << endl; + } + + stream << "#include \"introspectableinterface.h\"" << endl; + + stream << endl; +} + +static void openClassDeclaration(const Class& classData, + Class::Role role, TQTextStream& stream) +{ + switch (role) + { + case Class::Interface: + stream << "class " << classData.name << " : public TQT_DBusObjectBase" + << endl; + stream << "{" << endl; + stream << "public:" << endl; + stream << " virtual ~" << classData.name << "() {}" << endl; + stream << endl; + stream << " static void buildIntrospectionData(TQDomElement& interfaceElement);" << endl; + break; + + case Class::Proxy: + stream << "class " << classData.name << " : public TQObject" << endl; + stream << "{" << endl; + stream << " Q_OBJECT" << endl; + stream << " " << endl; + stream << "public:" << endl; + stream << " " << classData.name + << "(const TQString& service, const TQString& path, TQObject* parent = 0, const char* name = 0);" << endl; + stream << endl; + + stream << " virtual ~" << classData.name << "();" << endl; + stream << endl; + + stream << " void setConnection(const TQT_DBusConnection& connection);" + << endl; + break; + + case Class::Node: + stream << "class " << classData.name << " : public TQT_DBusObjectBase" + << endl; + stream << "{" << endl; + stream << "public:" << endl; + stream << " " << classData.name << "();" << endl; + stream << endl; + stream << " virtual ~" << classData.name << "();" << endl; + stream << endl; + stream << " bool registerObject(const TQT_DBusConnection& connection, " + << "const TQString& path);" << endl; + stream << endl; + stream << " void unregisterObject();" << endl; + stream << endl; + stream << "protected:" << endl; + stream << " virtual TQT_DBusObjectBase* createInterface(" + << "const TQString& interfaceName) = 0;" << endl; + stream << endl; + stream << "protected: // usually no need to reimplement" << endl; + stream << " virtual bool handleMethodCall(const TQT_DBusMessage& message);" << endl; + stream << endl; + stream << "private:" << endl; + stream << " class Private;" << endl; + stream << " Private* m_private;" << endl; + break; + } + + stream << endl; +} + +static void closeClassDeclaration(const Class& classData, Class::Role role, + TQTextStream& stream) +{ + switch (role) + { + case Class::Interface: + break; + + case Class::Proxy: + stream << "private: // Hiding copy constructor and assignment operator" << endl; + stream << " " << classData.name << "(const " + << classData.name << "&);" << endl; + stream << " " << classData.name << "& operator=(const " + << classData.name << "&);" << endl; + break; + + case Class::Node: + stream << "private: // Hiding copy constructor and assignment operator" << endl; + stream << " " << classData.name << "(const " + << classData.name << "&);" << endl; + stream << " " << classData.name << "& operator=(const " + << classData.name << "&);" << endl; + break; + } + stream << "}; // class " << classData.name << endl; + stream << endl; +} + +static void writeMethodDeclarations(const Class& classData, Class::Role role, + TQTextStream& stream) +{ + if (role == Class::Interface && !classData.asyncReplyMethods.isEmpty()) + { + stream << "public:" << endl; + + TQValueList::const_iterator it = + classData.asyncReplyMethods.begin(); + TQValueList::const_iterator endIt = + classData.asyncReplyMethods.end(); + for (; it != endIt; ++it) + { + Method method = *it; + method.name += "AsyncReply"; + + stream << " virtual void "; + MethodGenerator::writeMethodDeclaration(method, false, false, stream); + + stream << " virtual void " << (*it).name + << "AsyncError(int asyncCallId, const TQT_DBusError& error);" + << endl; + stream << endl; + } + } + + if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty()) + { + bool pureVirtual = true; + switch (role) + { + case Class::Interface: + pureVirtual = true; + stream << "protected:" << endl; + break; + + case Class::Proxy: + pureVirtual = false; + stream << "public:" << endl; + break; + + case Class::Node: // no variable methods + break; + } + + TQValueList::const_iterator it = classData.methods.begin(); + TQValueList::const_iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + if ((*it).async) continue; + + stream << " virtual bool "; + MethodGenerator::writeMethodDeclaration(*it, pureVirtual, true, stream); + } + + it = classData.asyncMethods.begin(); + endIt = classData.asyncMethods.end(); + for (; it != endIt; ++it) + { + Method method = *it; + method.name += "Async"; + + switch (role) + { + case Class::Interface: + stream << " virtual void "; + MethodGenerator::writeMethodDeclaration(method, pureVirtual, false, stream); + break; + + case Class::Proxy: + stream << " virtual bool "; + MethodGenerator::writeMethodDeclaration(method, pureVirtual, true, stream); + break; + + case Class::Node: // no async methods + break; + } + } + } + + if (!classData.properties.isEmpty()) + { + bool pureVirtual = true; + bool skip = false; + switch (role) + { + case Class::Interface: + tqWarning("Properties not yet supported for interfaces"); + skip = true; + pureVirtual = true; + break; + + case Class::Proxy: + pureVirtual = false; + stream << "public:" << endl; + stream << " virtual void setDBusProperty(const TQString& name," + << " const TQT_DBusVariant& variant, TQT_DBusError& error);" + << endl; + stream << " virtual TQT_DBusVariant getDBusProperty(const TQString& name, TQT_DBusError& error) const;" << endl; + stream << endl; + break; + + case Class::Node: // no node properties + skip = true; + break; + } + + if (!skip) + { + TQValueList::const_iterator it = classData.properties.begin(); + TQValueList::const_iterator endIt = classData.properties.end(); + for (; it != endIt; ++it) + { + MethodGenerator::writePropertyDeclaration(*it, pureVirtual, stream); + } + } + } + + switch (role) + { + case Class::Interface: + if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty()) + { + stream << "protected: // implement sending replies" << endl; + stream << " virtual void handleMethodReply(const TQT_DBusMessage& reply) = 0;" << endl; + stream << endl; + stream << "protected: // usually no need to reimplement" << endl; + stream << " virtual bool handleMethodCall(const TQT_DBusMessage& message);" << endl; + } + else + { + stream << "protected: // no methods to handle" << endl; + stream << " virtual bool handleMethodCall(const TQT_DBusMessage&) { return false; }" << endl; + } + break; + + case Class::Proxy: + { + if (!classData.msignals.isEmpty()) + { + stream << "protected slots: // usually no need to reimplement" << endl; + stream << " virtual void slotHandleDBusSignal(const TQT_DBusMessage& message);" << endl; + stream << endl; + } + + if (!classData.asyncReplySignals.isEmpty()) + { + if (classData.msignals.isEmpty()) + { + stream << "protected slots: // usually no need to reimplement" << endl; + } + stream << " virtual void slotHandleAsyncReply(int id, const TQT_DBusMessage& message);" << endl; + stream << endl; + } + + stream << "protected:" << endl; + stream << " TQT_DBusProxy* m_baseProxy;" << endl; + + if (!classData.asyncMethods.isEmpty()) + { + stream << endl; + stream << " TQMap m_asyncCalls;" << endl; + } + + break; + } + + case Class::Node: // not variable methods + break; + } + + stream << endl; +} + +static void writeSignalDeclarations(const Class& classData, Class::Role role, + TQTextStream& stream) +{ + if (classData.msignals.isEmpty() && classData.asyncReplySignals.isEmpty()) + return; + + TQString prefix; + switch (role) + { + case Class::Interface: + stream << "protected: // implement sending signals" << endl; + stream << " virtual bool handleSignalSend(const TQT_DBusMessage& reply) = 0;" << endl; + stream << " virtual TQString objectPath() const = 0;" << endl; + stream << endl; + stream << "protected: // for sending D-Bus signals" << endl; + prefix = " virtual bool emit"; + break; + + case Class::Proxy: + stream << "signals:" << endl; + stream << " void AsyncErrorResponseDetected(int asyncCallId, const TQT_DBusError error);" << endl << endl; + prefix = " void "; + break; + + case Class::Node: // no signals + break; + } + + TQValueList::const_iterator it = classData.msignals.begin(); + TQValueList::const_iterator endIt = classData.msignals.end(); + for (; it != endIt; ++it) + { + stream << prefix; + MethodGenerator::writeMethodDeclaration(*it, false, false, stream); + } + + it = classData.asyncReplySignals.begin(); + endIt = classData.asyncReplySignals.end(); + for (; it != endIt; ++it) + { + stream << prefix; + + Method signal = *it; + signal.name += "AsyncReply"; + + MethodGenerator::writeMethodDeclaration(signal, false, false, stream); + } + + stream << endl; +} + +static void writeSignalEmitters(const Class& classData, TQTextStream& stream) +{ + if (classData.msignals.isEmpty()) return; + + TQValueList::const_iterator it = classData.msignals.begin(); + TQValueList::const_iterator endIt = classData.msignals.end(); + for (; it != endIt; ++it) + { + MethodGenerator::writeSignalEmitter(classData, *it, stream); + } + + stream << endl; +} + +static void writeMethodCallDeclarations(const Class& classData, + TQTextStream& stream) +{ + TQValueList::const_iterator it = classData.methods.begin(); + TQValueList::const_iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + stream << " "; + MethodGenerator::writeMethodCallDeclaration(*it, stream); + } + + if (!classData.asyncReplyMethods.isEmpty()) + { + stream << "protected:" << endl; + stream << " TQMap m_asyncCalls;" << endl; + stream << endl; + } +} + +static void writeInterfaceAsyncReplyHandlers(const Class& classData, + TQTextStream& stream) +{ + if (classData.asyncReplyMethods.isEmpty()) return; + + TQValueList::const_iterator it = classData.asyncReplyMethods.begin(); + TQValueList::const_iterator endIt = classData.asyncReplyMethods.end(); + for (; it != endIt; ++it) + { + MethodGenerator::writeInterfaceAsyncReplyHandler(classData, *it, stream); + } +} + +static void writeMethodCalls(const Class& classData, TQTextStream& stream) +{ + TQValueList::const_iterator it = classData.methods.begin(); + TQValueList::const_iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + if ((*it).async) continue; + + MethodGenerator::writeMethodCall(classData, *it, stream); + } + + it = classData.asyncMethods.begin(); + endIt = classData.asyncMethods.end(); + for (; it != endIt; ++it) + { + MethodGenerator::writeMethodCall(classData, *it, stream); + } +} + +static void writeProxyMethods(const Class& classData, TQTextStream& stream) +{ + TQValueList::const_iterator it = classData.methods.begin(); + TQValueList::const_iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + if ((*it).async) continue; + + MethodGenerator::writeProxyMethod(classData.name, *it, stream); + } + + it = classData.asyncMethods.begin(); + endIt = classData.asyncMethods.end(); + for (; it != endIt; ++it) + { + MethodGenerator::writeProxyMethod(classData.name, *it, stream); + } +} + +static void writeProxyProperties(const Class& classData, TQTextStream& stream) +{ + if (classData.properties.isEmpty()) return; + + MethodGenerator::writeProxyGenericProperty(classData, stream); + + TQValueList::const_iterator it = classData.properties.begin(); + TQValueList::const_iterator endIt = classData.properties.end(); + for (; it != endIt; ++it) + { + MethodGenerator::writeProxyProperty(classData, *it, stream); + } +} + +static void splitAsyncProxyMethods(Class& classData) +{ + // create the async identifier + Argument idArgMethod; + idArgMethod.name = "asyncCallId"; + idArgMethod.signature = "int"; + idArgMethod.isPrimitive = true; + idArgMethod.direction = Argument::Out; + + Argument idArgSignal = idArgMethod; + idArgSignal.direction = Argument::In; + + TQValueList::iterator it = classData.methods.begin(); + TQValueList::iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + if (!(*it).async) continue; + + Method method = *it; + + TQValueList methodArgs; + TQValueList signalArgs; + + // add id argument + methodArgs << idArgMethod; + signalArgs << idArgSignal; + + // split in/out arguments: "in" belong to the method, "out" to the new signal + TQValueList::const_iterator argIt = method.arguments.begin(); + TQValueList::const_iterator argEndIt = method.arguments.end(); + for (; argIt != argEndIt; ++argIt) + { + if ((*argIt).direction == Argument::Out) + { + // signal parameters are "out" but have "in" signature, + // e.g. "const T&" + Argument arg = *argIt; + arg.direction = Argument::In; + + signalArgs << arg; + } + else + methodArgs << *argIt; + } + + // change method + method.arguments = methodArgs; + + classData.asyncMethods << method; + + // create "callback" signal + Method signal = method; + signal.arguments = signalArgs; + + classData.asyncReplySignals << signal; + } +} + +static void splitAsyncInterfaceMethods(Class& classData) +{ + // create the async identifier + Argument idArgMethod; + idArgMethod.name = "asyncCallId"; + idArgMethod.signature = "int"; + idArgMethod.isPrimitive = true; + idArgMethod.direction = Argument::In; + + Argument idArgReply = idArgMethod; + + TQValueList::iterator it = classData.methods.begin(); + TQValueList::iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + if (!(*it).async) continue; + + Method method = *it; + + TQValueList methodArgs; + TQValueList replyArgs; + + // add id argument + methodArgs << idArgMethod; + replyArgs << idArgReply; + + // split in/out arguments: "in" belong to the call, "out" to the reply + TQValueList::const_iterator argIt = method.arguments.begin(); + TQValueList::const_iterator argEndIt = method.arguments.end(); + for (; argIt != argEndIt; ++argIt) + { + if ((*argIt).direction == Argument::Out) + { + // reply parameters are "out" for the service but "in" for + // the reply handler + Argument arg = *argIt; + arg.direction = Argument::In; + + replyArgs << arg; + } + else + methodArgs << *argIt; + } + + // change method + method.arguments = methodArgs; + + classData.asyncMethods << method; + + // create reply handler + Method reply = method; + reply.arguments = replyArgs; + + classData.asyncReplyMethods << reply; + } +} + +bool ClassGenerator::initStreams(const TQString& baseName, + TQTextStream& headerStream, + TQTextStream& sourceStream) +{ + TQFile* headerFile = new TQFile(baseName + ".h"); + TQFile* sourceFile = new TQFile(baseName + ".cpp"); + + if (!headerFile->open(IO_WriteOnly) || !sourceFile->open(IO_WriteOnly)) + { + delete headerFile; + delete sourceFile; + + return false; + } + + headerStream.setDevice(TQT_TQIODEVICE(headerFile)); + sourceStream.setDevice(TQT_TQIODEVICE(sourceFile)); + + // create header + writeFileHeader(headerStream); + openIncludeGuard(baseName, headerStream); + + // create source + writeFileHeader(sourceStream); + sourceStream << "// declaration include" << endl; + sourceStream << "#include \"" << baseName << ".h\"" << endl; + sourceStream << endl; + + return true; +} + +bool ClassGenerator::finishStreams(const TQString& baseName, + TQTextStream& headerStream, + TQTextStream& sourceStream) +{ + closeIncludeGuard(baseName, headerStream); + writeFileFooter(headerStream); + writeFileFooter(sourceStream); + + TQIODevice* device = headerStream.device(); + headerStream.unsetDevice(); + delete device; + + device = sourceStream.device(); + sourceStream.unsetDevice(); + delete device; + + return true; +} + +bool ClassGenerator::extractClass(const TQDomElement& interfaceElement, + Class& classData) +{ + tqDebug("ClassGenerator: processing interface '%s'", + interfaceElement.attribute("name").latin1()); + + classData.dbusName = interfaceElement.attribute("name"); + + TQStringList nameParts = TQStringList::split('.', classData.dbusName); + + if (nameParts.count() < 2) return false; + + classData.name = nameParts.back(); + nameParts.pop_back(); + classData.namespaces = nameParts; + + return MethodGenerator::extractMethods(interfaceElement, classData); +} + +bool ClassGenerator::generateInterface(const Class& classData, + TQTextStream& headerStream, + TQTextStream& sourceStream) +{ + Class classDataCopy = classData; + splitAsyncInterfaceMethods(classDataCopy); + + // create header + writeHeaderIncludes(classDataCopy, Class::Interface, headerStream); + + openNamespaces(classDataCopy.namespaces, headerStream); + openClassDeclaration(classDataCopy, Class::Interface, headerStream); + + writeSignalDeclarations(classDataCopy, Class::Interface, headerStream); + writeMethodDeclarations(classDataCopy, Class::Interface, headerStream); + writeMethodCallDeclarations(classDataCopy, headerStream); + + closeClassDeclaration(classDataCopy, Class::Interface, headerStream); + closeNamespaces(classDataCopy.namespaces, headerStream); + + // create source + writeSourceIncludes(classDataCopy, Class::Interface, sourceStream); + + openNamespaces(classDataCopy.namespaces, sourceStream); + + MethodGenerator::writeIntrospectionDataMethod(classDataCopy, sourceStream); + + writeSignalEmitters(classDataCopy, sourceStream); + writeInterfaceAsyncReplyHandlers(classDataCopy, sourceStream); + writeMethodCalls(classDataCopy, sourceStream); + + MethodGenerator::writeInterfaceMainMethod(classDataCopy, sourceStream); + + closeNamespaces(classDataCopy.namespaces, sourceStream); + + return true; +} + +bool ClassGenerator::generateProxy(const Class& classData, + TQTextStream& headerStream, + TQTextStream& sourceStream) +{ + Class classDataCopy = classData; + splitAsyncProxyMethods(classDataCopy); + + // create header + writeHeaderIncludes(classDataCopy, Class::Proxy, headerStream); + + openNamespaces(classDataCopy.namespaces, headerStream); + openClassDeclaration(classDataCopy, Class::Proxy, headerStream); + + writeSignalDeclarations(classDataCopy, Class::Proxy, headerStream); + writeMethodDeclarations(classDataCopy, Class::Proxy, headerStream); + + closeClassDeclaration(classDataCopy, Class::Proxy, headerStream); + closeNamespaces(classDataCopy.namespaces, headerStream); + + // create source + writeSourceIncludes(classDataCopy, Class::Proxy, sourceStream); + + openNamespaces(classDataCopy.namespaces, sourceStream); + + MethodGenerator::writeProxyBegin(classDataCopy, sourceStream); + + writeProxyMethods(classDataCopy, sourceStream); + + writeProxyProperties(classDataCopy, sourceStream); + + if (!classDataCopy.msignals.isEmpty()) + MethodGenerator::writeSignalHandler(classDataCopy, sourceStream); + + if (!classDataCopy.asyncReplySignals.isEmpty()) + MethodGenerator::writeProxyAsyncReplyHandler(classDataCopy, sourceStream); + + closeNamespaces(classDataCopy.namespaces, sourceStream); + + return true; +} + +bool ClassGenerator::generateNode(const Class& classData, + const TQValueList& interfaces, + TQTextStream& headerStream, + TQTextStream& sourceStream) +{ + // create header + writeHeaderIncludes(classData, Class::Node, headerStream); + + openNamespaces(classData.namespaces, headerStream); + openClassDeclaration(classData, Class::Node, headerStream); + + closeClassDeclaration(classData, Class::Node, headerStream); + closeNamespaces(classData.namespaces, headerStream); + + // create source + writeSourceIncludes(classData, Class::Node, sourceStream); + writeInterfaceIncludes(interfaces, sourceStream); + + openNamespaces(classData.namespaces, sourceStream); + + MethodGenerator::writeNodePrivate(classData, sourceStream); + + MethodGenerator::writeNodeBegin(classData, sourceStream); + + MethodGenerator::writeNodeMethods(classData, interfaces, sourceStream); + + closeNamespaces(classData.namespaces, sourceStream); + + return true; +} + +// End of File diff --git a/src/tools/dbusxml2qt3/classgen.h b/src/tools/dbusxml2qt3/classgen.h new file mode 100644 index 0000000..3597890 --- /dev/null +++ b/src/tools/dbusxml2qt3/classgen.h @@ -0,0 +1,54 @@ +/* +* Copyright (C) 2007 Kevin Krammer +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +#if !defined(CLASSGEN_H_INCLUDED) +#define CLASSGEN_H_INCLUDED + +// forward declarations +class Class; +class TQDomElement; +class TQTextStream; +template class TQValueList; + +class ClassGenerator +{ +public: + static bool initStreams(const TQString& baseName, + TQTextStream& headerStream, TQTextStream& sourceStream); + + static bool finishStreams(const TQString& baseName, + TQTextStream& headerStream, TQTextStream& sourceStream); + + static bool extractClass(const TQDomElement& interfaceElement, Class& classData); + static bool generateInterface(const Class& classData, + TQTextStream& headerStream, + TQTextStream& sourceStream); + static bool generateProxy(const Class& classData, + TQTextStream& headerStream, TQTextStream& sourceStream); + static bool generateNode(const Class& classData, + const TQValueList& interfaces, + TQTextStream& headerStream, TQTextStream& sourceStream); +}; + +#endif + +// End of File diff --git a/src/tools/dbusxml2qt3/main.cpp b/src/tools/dbusxml2qt3/main.cpp new file mode 100644 index 0000000..0208072 --- /dev/null +++ b/src/tools/dbusxml2qt3/main.cpp @@ -0,0 +1,637 @@ +/* +* Copyright (C) 2007 Kevin Krammer +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +// standard includes +#include +#include + +// TQt includes +#include +#include +#include +#include + +// local includes +#include "classgen.h" +#include "methodgen.h" + +typedef TQMap OptionMap; + +void usage(); + +OptionMap parseOptions(int argc, char** argv); + +bool checkForOption(const OptionMap& options, const TQString& option) +{ + return options.find(option) != options.end(); +} + +int main(int argc, char** argv) +{ + const OptionMap options = parseOptions(argc, argv); + + if (!checkForOption(options, "filename")) + { + std::cerr << "dbusxml2qt3: introspection data file missing" << std::endl; + usage(); + exit(1); + } + + TQString fileName = options["filename"]; + TQFile file(fileName); + if (!file.exists()) + { + std::cerr << "dbusxml2qt3: introspection data file '" + << fileName.local8Bit().data() + << "' does not exist" << std::endl; + exit(2); + } + + if (!file.open(IO_ReadOnly)) + { + std::cerr << "dbusxml2qt3: introspection data file '" + << fileName.local8Bit().data() + << "' cannot be read" << std::endl; + exit(2); + } + + TQDomDocument document; + + if (!document.setContent(&file)) + { + file.close(); + + std::cerr << "dbusxml2qt3: introspection data file '" + << fileName.local8Bit().data() + << "' cannot be parsed" << std::endl; + exit(2); + } + + file.close(); + + TQDomElement rootElement = document.documentElement(); + if (rootElement.isNull() || rootElement.tagName() != "node") + { + std::cerr << "dbusxml2qt3: introspection data file '" + << fileName.local8Bit().data() + << "' does not have a 'node' element as its root node" + << std::endl; + exit(2); + } + + TQValueList interfaces; + bool hasIntrospectable = false; + + TQDomNode child = rootElement.firstChild(); + for (; !child.isNull(); child = child.nextSibling()) + { + if (!child.isElement()) continue; + + TQDomElement element = child.toElement(); + + if (element.tagName() == "interface") + { + if (!element.attribute("name").isEmpty()) + { + Class classData; + if (ClassGenerator::extractClass(element, classData)) + { + if (classData.dbusName == "org.freedesktop.DBus.Introspectable") + hasIntrospectable = true; + else + interfaces << classData; + } + } + } + } + + if (interfaces.isEmpty()) + { + std::cerr << "dbusxml2qt3: introspection data file '" + << fileName.local8Bit().data() + << "' does not contain any valid interface descriptions" + << std::endl; + exit(3); + } + + bool generateProxies = checkForOption(options, "proxy"); + bool generateInterfaces = checkForOption(options, "interface"); + bool generateNode = checkForOption(options, "node"); + + // if no specific option is selected, we generate everything + bool generateAll = !(generateProxies || generateInterfaces || generateNode); + + if (checkForOption(options, "classname")) + { + // class name only useful for single interfaces or just node + if (interfaces.count() > 1 && (generateAll || generateInterfaces || generateProxies)) + { + std::cerr << "dbusxml2qt3: class name option specified but " + << "introspection data file '" + << fileName.local8Bit().data() + << "' contains more than one interface description" + << std::endl; + exit(3); + } + + // class name for node is handled differently later on + if (!generateNode) + { + TQStringList nameParts = TQStringList::split("::", options["classname"]); + + interfaces[0].name = nameParts.back(); + + nameParts.pop_back(); + interfaces[0].namespaces = nameParts; + } + } + + if (checkForOption(options, "namespace")) + { + TQStringList nameParts = TQStringList::split("::", options["namespace"]); + + TQValueList::iterator it = interfaces.begin(); + TQValueList::iterator endIt = interfaces.end(); + for (; it != endIt; ++it) + { + (*it).namespaces = nameParts; + } + } + + if (generateInterfaces || generateAll) + { + TQTextStream headerStream; + TQTextStream sourceStream; + + TQString baseName = options["interface"]; + if (!baseName.isEmpty()) + { + if (!ClassGenerator::initStreams(baseName, headerStream, sourceStream)) + { + std::cerr << "dbusxml2qt3: proxy files, using base name '" + << baseName.local8Bit().data() + << "', could not be opened for writing" + << std::endl; + exit(4); + } + } + + TQValueList::const_iterator it = interfaces.begin(); + TQValueList::const_iterator endIt = interfaces.end(); + for (; it != endIt; ++it) + { + if (baseName.isEmpty()) + { + if (!ClassGenerator::initStreams((*it).name.lower() + "interface", + headerStream, sourceStream)) + { + std::cerr << "dbusxml2qt3: interface files, using base name '" + << baseName.local8Bit().data() + << "', could not be opened for writing" + << std::endl; + exit(4); + } + } + + ClassGenerator::generateInterface(*it, headerStream, sourceStream); + + if (baseName.isEmpty()) + { + ClassGenerator::finishStreams((*it).name.lower() + "interface", + headerStream, sourceStream); + } + } + + if (!baseName.isEmpty()) + ClassGenerator::finishStreams(baseName, headerStream, sourceStream); + } + + if (generateProxies || generateAll) + { + TQTextStream headerStream; + TQTextStream sourceStream; + + TQString baseName = options["proxy"]; + if (!baseName.isEmpty()) + { + if (!ClassGenerator::initStreams(baseName, headerStream, sourceStream)) + { + std::cerr << "dbusxml2qt3: proxy files, using base name '" + << baseName.local8Bit().data() + << "', could not be opened for writing" + << std::endl; + exit(4); + } + } + + TQValueList::const_iterator it = interfaces.begin(); + TQValueList::const_iterator endIt = interfaces.end(); + for (; it != endIt; ++it) + { + if (baseName.isEmpty()) + { + if (!ClassGenerator::initStreams((*it).name.lower() + "proxy", + headerStream, sourceStream)) + { + std::cerr << "dbusxml2qt3: proxy files, using base name '" + << baseName.local8Bit().data() + << "', could not be opened for writing" + << std::endl; + exit(4); + } + } + + ClassGenerator::generateProxy(*it, headerStream, sourceStream); + + if (baseName.isEmpty()) + { + ClassGenerator::finishStreams((*it).name.lower() + "proxy", + headerStream, sourceStream); + } + } + + if (!baseName.isEmpty()) + ClassGenerator::finishStreams(baseName, headerStream, sourceStream); + } + + if (generateNode || generateAll) + { + if (!hasIntrospectable) + { + tqDebug("Generating org.freedesktop.DBus.Introspectable on demand"); + + Class classData; + classData.name = "Introspectable"; + classData.dbusName = "org.freedesktop.DBus.Introspectable"; + + classData.namespaces << "org" << "freedesktop" << "DBus"; + + Method method; + method.name = "Introspect"; + method.noReply = false; + method.async = false; + + Argument argument; + argument.name = "data"; + argument.direction = Argument::Out; + argument.signature = "TQString"; + argument.accessor = "String"; + argument.isPrimitive = false; + argument.dbusSignature = "s"; + + argument.forwardDeclarations << "class TQString"; + argument.sourceIncludes["TQt"].append(""); + + method.arguments << argument; + classData.methods << method; + + TQTextStream headerStream; + TQTextStream sourceStream; + + if (!ClassGenerator::initStreams(classData.name.lower() + "interface", + headerStream, sourceStream)) + { + std::cerr << "dbusxml2qt3: interface files, using base name '" + << classData.name.lower().local8Bit().data() << "interface" + << "', could not be opened for writing" + << std::endl; + exit(4); + } + + ClassGenerator::generateInterface(classData, + headerStream, sourceStream); + + ClassGenerator::finishStreams(classData.name.lower() + "interface", + headerStream, sourceStream); + } + + TQString nodeClassName = options["classname"]; + if (nodeClassName.isEmpty()) + { + nodeClassName = rootElement.attribute("name"); + if (nodeClassName.startsWith("/")) nodeClassName = nodeClassName.mid(1); + if (nodeClassName.isEmpty()) + { + std::cerr << "dbusxml2qt3: cannot generate node without class name." + << std::endl; + exit(3); + } + + nodeClassName.replace('/', "_"); + } + + TQStringList nameParts = TQStringList::split("::", nodeClassName); + + Class classData; + classData.name = nameParts.back(); + + nameParts.pop_back(); + classData.namespaces = nameParts; + + if (checkForOption(options, "namespace")) + { + nameParts = TQStringList::split("::", options["namespace"]); + + classData.namespaces = nameParts; + } + + TQTextStream headerStream; + TQTextStream sourceStream; + + TQString baseName = options["node"]; + if (baseName.isEmpty()) baseName = classData.name.lower() + "node"; + + if (!ClassGenerator::initStreams(baseName, headerStream, sourceStream)) + { + std::cerr << "dbusxml2qt3: interface files, using base name '" + << baseName.local8Bit().data() + << "', could not be opened for writing" + << std::endl; + exit(4); + } + + ClassGenerator::generateNode(classData, interfaces, + headerStream, sourceStream); + + ClassGenerator::finishStreams(baseName, headerStream, sourceStream); + } + + return 0; +} + +void usage() +{ + std::cout << "usage: dbusxml2qt3 [options] " << std::endl; + std::cout << std::endl; + + std::cout << "Options:" << std::endl; + std::cout << "-h, --help" << std::endl; + std::cout << "\tDisplay this help" << std::endl; + std::cout << std::endl; + + std::cout << "-c , --class " << std::endl; + std::cout << "\tUse 'classname' instead of last string in interface name" + << std::endl; + std::cout << std::endl; + + std::cout << "-N [namespace], --namespace [namespace]" << std::endl; + std::cout << "\tOverride namespaces. If provided, use 'namespace' instead, otherwise ignore namespaces" + << std::endl; + std::cout << std::endl; + + std::cout << "-i [basename], --interface [basename]" << std::endl; + std::cout << "\tGenerate interface files. If provided, use 'basename' for filenames" + << std::endl; + std::cout << std::endl; + + std::cout << "-p [basename], --proxy [basename]" << std::endl; + std::cout << "\tGenerate proxy files. If provided, use 'basename' for filenames" + << std::endl; + std::cout << std::endl; + + std::cout << "-n [basename], --node [basename]" << std::endl; + std::cout << "\tGenerate node files. If provided, use 'basename' for filenames" + << std::endl; + std::cout << std::endl; + + std::cout << "Examples:" << std::endl; + std::cout << "dbusxml2qt3 myinterface.xml" << std::endl; + std::cout << "\tGenerates as much as possible, i.e. interfaces, proxies and, " + << "if a node name is specified in 'myinterface.xml', the node files" + << std::endl; + std::cout << "\tUses lowercased interface names as plus type specific suffix " + << "for the file names" << std::endl; + std::cout << std::endl; + + std::cout << "dbusxml2qt3 myinterface.xml -N" << std::endl; + std::cout << "\tSame as first example but does not use namespaces" + << std::endl; + std::cout << std::endl; + + std::cout << "dbusxml2qt3 myinterface.xml -N org::myorg" << std::endl; + std::cout << "\tSame as first example but overrides namespaces with 'org::myorg'" + << std::endl; + std::cout << std::endl; + + std::cout << "dbusxml2qt3 myinterface.xml -n mynode -c MyNode" << std::endl; + std::cout << "\tGenerate only node files, use 'mynode' as the file basename " + << "and classname 'MyClass'" + << std::endl; + std::cout << std::endl; + + std::cout << "dbusxml2qt3 myinterface.xml -p" << std::endl; + std::cout << "\tGenerate only proxy files, use default file basename" + << std::endl; + std::cout << std::endl; + + std::cout << "dbusxml2qt3 myinterface.xml -p myproxy" << std::endl; + std::cout << "\tGenerate only proxy files, use 'myproxy' as the file basename" + << std::endl; + std::cout << std::endl; +} + +bool testAndSetOption(OptionMap& options, const TQString& option, const TQString& value) +{ + OptionMap::iterator it = options.find(option); + if (it == options.end()) + { + options.insert(option, value); + return true; + } + + return false; +} + +OptionMap parseOptions(int argc, char** argv) +{ + TQStringList args; + for (int i = 1; i < argc; ++i) + { + args << TQString::fromLocal8Bit(argv[i]); + } + + OptionMap options; + + while (!args.isEmpty()) + { + TQString arg = args.front(); + args.pop_front(); + + if (arg.startsWith("-")) + { + if (arg.endsWith("help")) + { + usage(); + exit(0); + } + else if (arg == "-p" || arg == "--proxy") + { + // test for optional argument + TQString value; + if (!args.isEmpty() > 0 && !args[0].startsWith("-")) + { + value = args.front(); + args.pop_front(); + } + + if (!testAndSetOption(options, "proxy", value)) + { + std::cerr << "Error while parsing command line argument '" + << arg.local8Bit().data() << "'"; + + if (!value.isEmpty()) + std::cerr << ", value '" << value.local8Bit().data() << "':"; + else + std::cerr << ":"; + + std::cerr << " already set to '" + << options["proxy"].local8Bit().data() << std::endl; + } + } + else if (arg == "-i" || arg == "--interface") + { + // test for optional argument + TQString value; + if (!args.isEmpty() > 0 && !args[0].startsWith("-")) + { + value = args.front(); + args.pop_front(); + } + + if (!testAndSetOption(options, "interface", value)) + { + std::cerr << "Error while parsing command line argument '" + << arg.local8Bit().data() << "'"; + + if (!value.isEmpty()) + std::cerr << ", value '" << value.local8Bit().data() << "':"; + else + std::cerr << ":"; + + std::cerr << " already set to '" + << options["interface"].local8Bit().data() << std::endl; + } + } + else if (arg == "-n" || arg == "--node") + { + // test for optional argument + TQString value; + if (!args.isEmpty() > 0 && !args[0].startsWith("-")) + { + value = args.front(); + args.pop_front(); + } + + if (!testAndSetOption(options, "node", value)) + { + std::cerr << "Error while parsing command line argument '" + << arg.local8Bit().data() << "'"; + + if (!value.isEmpty()) + std::cerr << ", value '" << value.local8Bit().data() << "':"; + else + std::cerr << ":"; + + std::cerr << " already set to '" + << options["node"].local8Bit().data() << std::endl; + } + } + else if (arg == "-N" || arg == "--namespace") + { + // test for optional argument + TQString value; + if (!args.isEmpty() > 0 && !args[0].startsWith("-")) + { + value = args.front(); + args.pop_front(); + } + + if (!testAndSetOption(options, "namespace", value)) + { + std::cerr << "Error while parsing command line argument '" + << arg.local8Bit().data() << "'"; + + if (!value.isEmpty()) + std::cerr << ", value '" << value.local8Bit().data() << "':"; + else + std::cerr << ":"; + + std::cerr << " already set to '" + << options["namespace"].local8Bit().data() << std::endl; + } + } + else if (arg == "-c" || arg == "--class") + { + // test for mandatory argument + if (args.isEmpty() || args[0].startsWith("-")) + { + std::cerr << "Error while parsing command line argument '" + << arg.local8Bit().data() + << "': mandatory parameter missing" << std::endl; + usage(); + exit(1); + } + + TQString value = args.front(); + args.pop_front(); + + if (!testAndSetOption(options, "classname", value)) + { + std::cerr << "Error while parsing command line argument '" + << arg.local8Bit().data() << "'"; + + if (!value.isEmpty()) + std::cerr << ", value '" << value.local8Bit().data() << "':"; + else + std::cerr << ":"; + + std::cerr << " already set to '" + << options["classname"].local8Bit().data() << std::endl; + } + } + else + { + std::cerr << "Error while parsing command line argument '" + << arg.local8Bit().data() + << "': unknown option" << std::endl; + usage(); + exit(1); + } + } + else + { + if (!testAndSetOption(options, "filename", arg)) + { + std::cerr << "Error while parsing command line argument '" + << arg.local8Bit().data() + << "': introspection file already given as '" + << options["filename"].local8Bit().data() << std::endl; + usage(); + exit(1); + } + } + } + + return options; +} + +// End of File diff --git a/src/tools/dbusxml2qt3/methodgen.cpp b/src/tools/dbusxml2qt3/methodgen.cpp new file mode 100644 index 0000000..4e407d5 --- /dev/null +++ b/src/tools/dbusxml2qt3/methodgen.cpp @@ -0,0 +1,1793 @@ +/* +* Copyright (C) 2007 Kevin Krammer +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +// TQt includes +#include +#include + +// local includes +#include "methodgen.h" + +static bool parseDBusSignature(const TQString& signature, Argument& argument) +{ + argument.dbusSignature = signature; + + if (signature.length() == 1) + { + if (signature == "b") + { + argument.signature = "bool"; + argument.accessor = "Bool"; + argument.isPrimitive = true; + } + else if (signature == "y") + { + argument.signature = "TQ_UINT8"; + argument.accessor = "Byte"; + argument.isPrimitive = true; + } + else if (signature == "n") + { + argument.signature = "TQ_INT16"; + argument.accessor = "Int16"; + argument.isPrimitive = true; + } + else if (signature == "q") + { + argument.signature = "TQ_UINT16"; + argument.accessor = "UInt16"; + argument.isPrimitive = true; + } + else if (signature == "i") + { + argument.signature = "TQ_INT32"; + argument.accessor = "Int32"; + argument.isPrimitive = true; + } + else if (signature == "u") + { + argument.signature = "TQ_UINT32"; + argument.accessor = "UInt32"; + argument.isPrimitive = true; + } + else if (signature == "x") + { + argument.signature = "TQ_INT64"; + argument.accessor = "Int64"; + argument.isPrimitive = true; + } + else if (signature == "t") + { + argument.signature = "TQ_UINT64"; + argument.accessor = "UInt64"; + argument.isPrimitive = true; + } + else if (signature == "d") + { + argument.signature = "double"; + argument.accessor = "Double"; + argument.isPrimitive = true; + } + else if (signature == "s") + { + argument.signature = "TQString"; + argument.accessor = "String"; + argument.isPrimitive = false; + + argument.forwardDeclarations.append("class TQString"); + argument.sourceIncludes["TQt"].append(""); + } + else if (signature == "o") + { + argument.signature = "TQT_DBusObjectPath"; + argument.accessor = "ObjectPath"; + argument.isPrimitive = false; + + argument.forwardDeclarations.append("class TQT_DBusObjectPath"); + argument.sourceIncludes["tqdbus"].append(""); + } + else if (signature == "h") + { + argument.signature = "TQT_DBusUnixFd"; + argument.accessor = "UnixFd"; + argument.isPrimitive = false; + + argument.forwardDeclarations.append("class TQT_DBusUnixFd"); + argument.sourceIncludes["tqdbus"].append(""); + } + else if (signature == "v") + { + argument.signature = "TQT_DBusVariant"; + argument.accessor = "Variant"; + argument.isPrimitive = false; + + argument.forwardDeclarations.append("class TQT_DBusVariant"); + argument.sourceIncludes["tqdbus"].append(""); + } + else + return false; + } + else if (signature.startsWith("a")) + { + if (signature == "as") + { + argument.signature = "TQStringList"; + argument.accessor = "List"; + argument.subAccessor = "TQStringList"; + argument.isPrimitive = false; + + argument.forwardDeclarations.append("class TQStringList"); + + argument.sourceIncludes["tqdbus"].append(""); + argument.sourceIncludes["TQt"].append(""); + } + else if (signature.startsWith("a{")) + { + int from = signature.find("{"); + int to = signature.findRev("}"); + if (from == -1 || to == -1 || (to - from - 1) < 2) return false; + + TQString dictSignature = signature.mid(from + 1, (to - from - 1)); + + Argument key; + if (!parseDBusSignature(dictSignature.left(1), key)) return false; + + Argument value; + if (parseDBusSignature(dictSignature.mid(1), value)) + { + if (!value.subAccessor.isEmpty()) + { + argument.isPrimitive = false; + argument.containerClass = "TQT_DBusDataMap< " + key.signature + " >"; + argument.signature = "TQT_DBusDataMap< " + key.signature + " >"; + argument.accessor = key.accessor + "KeyMap"; + + argument.forwardDeclarations.append("template class TQT_DBusDataMap"); + argument.forwardDeclarations += key.forwardDeclarations; + + argument.sourceIncludes = key.sourceIncludes; + argument.sourceIncludes["tqdbus"].append(""); + argument.sourceIncludes["tqdbus"].append(""); + } + else + { + argument.isPrimitive = false; + argument.containerClass = "TQT_DBusDataMap< " + key.signature + " >"; + argument.signature = "TQMap< " + key.signature + + ", " + value.signature + " >"; + argument.accessor = key.accessor + "KeyMap"; + argument.subAccessor = value.accessor + "Map"; + + argument.forwardDeclarations.append("template class TQMap"); + argument.forwardDeclarations += key.forwardDeclarations; + argument.forwardDeclarations += value.forwardDeclarations; + + argument.sourceIncludes = key.sourceIncludes; + argument.sourceIncludes["TQt"].append(""); + argument.sourceIncludes["tqdbus"].append(""); + argument.sourceIncludes["tqdbus"].append(""); + + TQMap::const_iterator it = + value.sourceIncludes.begin(); + TQMap::const_iterator endIt = + value.sourceIncludes.end(); + for (; it != endIt; ++it) + { + argument.sourceIncludes[it.key()] += it.data(); + } + } + } + else + { + argument.isPrimitive = false; + argument.containerClass = "TQT_DBusDataMap< " + key.signature + " >"; + argument.signature = "TQT_DBusDataMap< " + key.signature + " >"; + argument.accessor = key.accessor + "KeyMap"; + + argument.forwardDeclarations.append("template class TQT_DBusDataMap"); + argument.forwardDeclarations += key.forwardDeclarations; + + argument.sourceIncludes = key.sourceIncludes; + argument.sourceIncludes["tqdbus"].append(""); + argument.sourceIncludes["tqdbus"].append(""); + } + } + else + { + TQString itemSignature = signature.mid(1); + + Argument item; + if (parseDBusSignature(itemSignature, item) && !itemSignature.startsWith("a")) + { + argument.isPrimitive = false; + argument.signature = "TQValueList< " + item.signature + " >"; + argument.accessor = "List"; + argument.subAccessor = item.accessor + "List"; + argument.containerClass = "TQT_DBusDataList"; + + argument.forwardDeclarations.append("class TQT_DBusDataList"); + argument.forwardDeclarations.append("template class TQValueList"); + argument.forwardDeclarations += item.forwardDeclarations; + + argument.sourceIncludes["TQt"].append(""); + argument.sourceIncludes["tqdbus"].append(""); + + TQMap::const_iterator it = + item.sourceIncludes.begin(); + TQMap::const_iterator endIt = + item.sourceIncludes.end(); + for (; it != endIt; ++it) + { + argument.sourceIncludes[it.key()] += it.data(); + } + } + else + { + argument.signature = "TQT_DBusDataList"; + argument.accessor = "List"; + argument.isPrimitive = false; + + argument.forwardDeclarations.append("class TQT_DBusDataList"); + + argument.sourceIncludes["tqdbus"].append(""); + } + } + } + else + return false; + + return true; +} + +static TQMap extractTypeAnnotations(const TQDomElement& element) +{ + const TQString annotationPrefix = "org.freedesktop.DBus.TQt3.Type."; + + TQMap annotations; + + TQDomNode node = element.firstChild(); + for (uint count = 1; !node.isNull(); node = node.nextSibling(), ++count) + { + if (!node.isElement()) continue; + + TQDomElement element = node.toElement(); + if (element.tagName() != "annotation") continue; + + TQString name = element.attribute("name"); + if (name.isEmpty()) continue; + + TQString value = element.attribute("value").stripWhiteSpace(); + if (value.isEmpty()) continue; + + if (!name.startsWith(annotationPrefix)) continue; + + TQString arg = name.mid(annotationPrefix.length()); + + annotations.insert(arg, value); + } + + return annotations; +} + +static bool hasAnnotation(const TQDomElement& element, const TQString& annotation, TQString* value = 0) +{ + for (TQDomNode node = element.firstChild(); !node.isNull(); + node = node.nextSibling()) + { + if (!node.isElement()) continue; + + TQDomElement childElement = node.toElement(); + if (childElement.tagName() != "annotation") continue; + if (childElement.attribute("name") != annotation) continue; + + if (value != 0) *value = childElement.attribute("value"); + return true; + } + + return false; +} + +static TQValueList extractArguments(const TQDomElement& methodElement, + Class& classData) +{ + TQMap argAnnotations = extractTypeAnnotations(methodElement); + + TQValueList arguments; + + bool isSignal = methodElement.tagName() == "signal"; + + uint inCount = 0; + uint outCount = 0; + for (TQDomNode node = methodElement.firstChild(); !node.isNull(); + node = node.nextSibling()) + { + if (!node.isElement()) continue; + + TQDomElement element = node.toElement(); + if (element.tagName() != "arg") continue; + if (element.attribute("type").isEmpty()) continue; + + Argument argument; + argument.name = element.attribute("name"); + if (argument.name.isEmpty()) + argument.name = TQString("arg%1").arg(inCount + outCount); + + argument.direction = Argument::In; + if (!isSignal && element.attribute("direction", "in") == "out") + argument.direction = Argument::Out; + + TQString annotation; + if (!isSignal && argument.direction == Argument::In) + { + annotation = argAnnotations[TQString("In%1").arg(inCount)]; + ++inCount; + } + else + { + annotation = argAnnotations[TQString("Out%1").arg(outCount)]; + ++outCount; + } + + if (!annotation.isEmpty()) + { + // just assume nobody uses annotations for primitives + argument.annotatedType = annotation; + argument.signature = annotation; + argument.isPrimitive = false; + argument.dbusSignature = element.attribute("type"); + + TQString includeBase = + TQString("\"%1type%2.h\"").arg(classData.name.lower()); + + argument.headerIncludes["local"].append(includeBase.arg("declarations")); + argument.sourceIncludes["local"].append(includeBase.arg("includes")); + argument.sourceIncludes["tqdbus"].append(""); + } + else if (!parseDBusSignature(element.attribute("type"), argument)) + { + argument.signature = "TQT_DBusData"; + argument.isPrimitive = false; + + argument.forwardDeclarations.append("class TQT_DBusData"); + argument.sourceIncludes["tqdbus"].append(""); + } + + arguments.append(argument); + } + + return arguments; +} + +static void writeVariable(const Argument& argument, uint index, + const TQString& prefix, TQTextStream& stream) +{ + stream << prefix << argument.signature << " _" << argument.name; + if (argument.direction == Argument::In) + { + if (!argument.annotatedType.isEmpty()) + { + stream << ";" << endl; + + // TODO: error handling? + stream << prefix << "TQT_DBusDataConverter::convertFromTQT_DBusData<" + << argument.annotatedType + << TQString(">(message[%1], _").arg(index) + << argument.name << ")"; + } + else if (!argument.accessor.isEmpty()) + { + stream << TQString::fromUtf8(" = message[%1].to").arg(index); + stream << argument.accessor; + + if (!argument.subAccessor.isEmpty()) + { + stream << TQString("().to%1").arg(argument.subAccessor); + } + + stream << "()"; + } + else + stream << TQString::fromUtf8(" = message[%1]").arg(index); + } + + stream << ";" << endl; +} + +static void writeVariables(const TQString& prefix, const Method& method, + TQTextStream& stream) +{ + uint count = 0; + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + for (; it != endIt; ++it) + { + writeVariable(*it, count, prefix, stream); + + if ((*it).direction == Argument::In) ++count; + } +} + +static void writeSignalEmit(const Method& signal, TQTextStream& stream) +{ + stream << " emit " << signal.name << "("; + + TQValueList::const_iterator it = signal.arguments.begin(); + TQValueList::const_iterator endIt = signal.arguments.end(); + for (; it != endIt;) + { + stream << "_" << (*it).name; + + ++it; + if (it != endIt) stream << ", "; + } + + stream << ");" << endl; +} + +static void writeMethodIntrospection(const Method& method, bool& firstArgument, + TQTextStream& stream) +{ + stream << " methodElement.setAttribute(\"name\", \"" + << method.name << "\");" << endl; + + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + for (; it != endIt; ++it) + { + stream << endl; + if (firstArgument) + { + firstArgument = false; + + stream << " TQDomElement argumentElement = document.createElement(" + << "\"arg\");" << endl; + } + else + { + stream << " argumentElement = document.createElement(" + << "\"arg\");" << endl; + } + + stream << " argumentElement.setAttribute(\"name\", \"" + << (*it).name << "\");" << endl; + + stream << " argumentElement.setAttribute(\"type\", \"" + << (*it).dbusSignature << "\");" << endl; + + stream << " argumentElement.setAttribute(\"direction\", \"" + << ((*it).direction == Argument::In ? "in" : "out") << "\");" + << endl; + + stream << " methodElement.appendChild(argumentElement);" << endl; + } + stream << endl; +} + +static void writeNodeInitialization(const Class& classData, + const TQValueList& interfaces, TQTextStream& stream) +{ + stream << "bool " << classData.name + << "::registerObject(const TQT_DBusConnection& connection, " + << "const TQString& path)" << endl; + stream << "{" << endl; + stream << " if (path.isEmpty()) return false;" << endl; + stream << endl; + + stream << " if (!m_private->objectPath.isEmpty()) unregisterObject();" + << endl; + stream << endl; + + stream << " m_private->connection = connection;" << endl; + stream << " m_private->objectPath = path;" << endl; + stream << endl; + stream << " if (!m_private->connection.registerObject(path, this))" << endl; + stream << " {" << endl; + stream << " m_private->connection = TQT_DBusConnection();" << endl; + stream << " m_private->objectPath = TQString();" << endl; + stream << endl; + stream << " return false;" << endl; + stream << " }" << endl; + stream << endl; + + stream << " if (m_private->interfaces.isEmpty())" << endl; + stream << " {" << endl; + stream << " TQString name = \"org.freedesktop.DBus.Introspectable\";" + << endl; + stream << " TQT_DBusObjectBase* interface = m_private;" << endl; + stream << " m_private->interfaces.insert(name, interface);" << endl; + + TQValueList::const_iterator it = interfaces.begin(); + TQValueList::const_iterator endIt = interfaces.end(); + for (; it != endIt; ++it) + { + stream << endl; + stream << " name = \"" << (*it).dbusName << "\";" << endl; + stream << " interface = createInterface(name);" << endl; + stream << " Q_ASSERT(interface != 0);" << endl; + stream << " m_private->interfaces.insert(name, interface);" << endl; + } + + stream << " }" << endl; + stream << endl; + stream << " return true;" << endl; + stream << "}" << endl; + stream << endl; +} +static void writeNodeIntrospection(const Class& classData, + const TQValueList& interfaces, TQTextStream& stream) +{ + stream << "void " << classData.name << "::Private" + << "::cacheIntrospectionData()" << endl; + stream << "{" << endl; + + stream << " TQDomDocument doc;" << endl; + stream << " TQDomElement nodeElement = doc.createElement(\"node\");" << endl; + stream << " TQDomElement interfaceElement = doc.createElement(\"interface\");" + << endl; + stream << " org::freedesktop::DBus::Introspectable" + << "::buildIntrospectionData(interfaceElement);" << endl; + stream << " nodeElement.appendChild(interfaceElement);" << endl; + + TQValueList::const_iterator it = interfaces.begin(); + TQValueList::const_iterator endIt = interfaces.end(); + for (; it != endIt; ++it) + { + if ((*it).dbusName == "org.freedesktop.DBus.Introspectable") continue; + + stream << endl; + stream << " interfaceElement = doc.createElement(\"interface\");" + << endl; + stream << " " << (*it).namespaces.join("::") + "::" + (*it).name + << "::buildIntrospectionData(interfaceElement);" << endl; + stream << " nodeElement.appendChild(interfaceElement);" << endl; + } + + stream << endl; + stream << " doc.appendChild(nodeElement);" << endl; + stream << endl; + + stream << " introspectionData = \"\\n\";" << endl; + stream << " introspectionData += doc.toString();" << endl; + stream << "}" << endl; + stream << endl; +} + +bool MethodGenerator::extractMethods(const TQDomElement& interfaceElement, + Class& classData) +{ + TQMap propertyAnnotations = + extractTypeAnnotations(interfaceElement); + + uint propertyCount = 0; + for (TQDomNode node = interfaceElement.firstChild(); !node.isNull(); + node = node.nextSibling()) + { + if (!node.isElement()) continue; + + TQDomElement element = node.toElement(); + if (element.attribute("name").isEmpty()) continue; + + if (element.tagName() == "method" || element.tagName() == "signal") + { + Method method; + method.name = element.attribute("name"); + method.arguments = extractArguments(element, classData); + method.noReply = false; + method.async = false; + + if (element.tagName() == "method") + { + method.async = hasAnnotation(element, "org.freedesktop.DBus.GLib.Async"); + classData.methods.append(method); + if (method.async) { + method.async = false; + classData.methods.append(method); + } + } + else + classData.msignals.append(method); + } + else if (element.tagName() == "property") + { + Property property; + property.name = element.attribute("name"); + property.read = element.attribute("access").find("read") != -1; + property.write = element.attribute("access").find("write") != -1; + + TQString annotation = + propertyAnnotations[TQString("Property%1").arg(propertyCount)]; + + if (!annotation.isEmpty()) + { + property.annotatedType = annotation; + property.signature = annotation; + property.dbusSignature = element.attribute("type"); + property.isPrimitive = false; + + TQString includeBase = + TQString("\"%1type%2.h\"").arg(classData.name.lower()); + + property.headerIncludes["local"].append(includeBase.arg("declarations")); + property.sourceIncludes["local"].append(includeBase.arg("includes")); + property.sourceIncludes["tqdbus"].append(""); + } + else if (!parseDBusSignature(element.attribute("type"), property)) + { + property.signature = "TQT_DBusData"; + property.isPrimitive = false; + + property.forwardDeclarations.append("class TQT_DBusData"); + property.sourceIncludes["tqdbus"].append(""); + } + + classData.properties.append(property); + ++propertyCount; + } + } + + return !classData.methods.isEmpty() || !classData.msignals.isEmpty() || + !classData.properties.isEmpty(); +} + +void MethodGenerator::writeMethodDeclaration(const Method& method, bool pureVirtual, + bool withError, TQTextStream& stream) +{ + stream << method.name << "("; + + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + for (; it != endIt;) + { + if (!(*it).isPrimitive && (*it).direction == Argument::In) + stream << "const "; + + stream << (*it).signature; + + if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&"; + + stream << " " << (*it).name; + + ++it; + if (it != endIt || withError) stream << ", "; + } + + if (withError) + stream << "TQT_DBusError& error)"; + else + stream << ")"; + + if (pureVirtual) + stream << " = 0;" << endl; + else + stream << ";" << endl; + + stream << endl; +} + +void MethodGenerator::writePropertyDeclaration(const Property& property, + bool pureVirtual, TQTextStream& stream) +{ + if (property.write) + { + stream << " virtual void set" << property.name << "("; + + if (!property.isPrimitive) stream << "const "; + + stream << property.signature; + + if (!property.isPrimitive) stream << "&"; + + stream << " value, TQT_DBusError& error)"; + + if (pureVirtual) + stream << " = 0;" << endl; + else + stream << ";" << endl; + } + + if (property.read) + { + stream << " virtual " << property.signature << " get" + << property.name << "(TQT_DBusError& error) const"; + + if (pureVirtual) + stream << " = 0;" << endl; + else + stream << ";" << endl; + } + + if (property.read || property.write) stream << endl; +} + +void MethodGenerator::writeMethodCallDeclaration(const Method& method, + TQTextStream& stream) +{ + if (method.async) + stream << "void call" << method.name << "Async"; + else + stream << "TQT_DBusMessage call" << method.name; + + stream << "(const TQT_DBusMessage& message);" << endl; + stream << endl; +} + +void MethodGenerator::writeMethodCall(const Class& classData, + const Method& method, TQTextStream& stream) +{ + if (method.async) + stream << "void " << classData.name << "::call" << method.name << "Async"; + else + stream << "TQT_DBusMessage " << classData.name << "::call" << method.name; + + stream << "(const TQT_DBusMessage& message)" << endl; + + stream << "{" << endl; + + if (method.async) + { + // FIXME: using writeVariables by removing asyncCallId argument + Method reducedMethod = method; + reducedMethod.arguments.pop_front(); + + writeVariables(" ", reducedMethod, stream); + } + else + { + stream << " TQT_DBusError error;" << endl; + stream << " TQT_DBusMessage reply;" << endl; + stream << endl; + + writeVariables(" ", method, stream); + } + + stream << endl; + + if (method.async) + { + stream << " int _asyncCallId = 0;" << endl; + stream << " while (m_asyncCalls.find(_asyncCallId) != m_asyncCalls.end())" + << endl; + stream << " {" << endl; + stream << " ++_asyncCallId;" << endl; + stream << " }" << endl; + stream << " m_asyncCalls.insert(_asyncCallId, message);" << endl; + stream << endl; + + stream << " " << method.name << "Async("; + } + else + stream << " if (" << method.name << "("; + + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + while (it != endIt) + { + stream << "_" << (*it).name; + + ++it; + if (it != endIt) stream << ", "; + } + + if (method.async) + { + stream << ");" << endl; + stream << endl; + + stream << " return;" << endl; + stream << "}" << endl; + stream << endl; + return; + } + + if (method.arguments.count() > 0) stream << ", "; + stream << "error))" << endl; + + stream << " {" << endl; + stream << " reply = TQT_DBusMessage::methodReply(message);" << endl; + + it = method.arguments.begin(); + for (; it != endIt; ++it) + { + if ((*it).direction == Argument::Out) + { + if (!(*it).annotatedType.isEmpty()) + { + stream << " TQT_DBusData " << (*it).name << "Data;" << endl; + stream << " TQT_DBusDataConverter::convertToTQT_DBusData<" + << (*it).annotatedType << ">(_" + << (*it).name << ", " << (*it).name << "Data);" + << endl; + stream << " reply << " << (*it).name << "Data"; + } + else if (!(*it).accessor.isEmpty()) + { + stream << " reply << TQT_DBusData::from" << (*it).accessor; + if (!(*it).subAccessor.isEmpty()) + { + stream << "(" << (*it).containerClass; + } + + stream << "(_" << (*it).name << ")"; + + if (!(*it).subAccessor.isEmpty()) + { + stream << ")"; + } + } + else + stream << " reply << _" << (*it).name; + + stream << ";" << endl; + } + } + stream << " }" << endl; + stream << " else" << endl; + stream << " {" << endl; + + stream << " if (!error.isValid())" << endl; + stream << " {" << endl; + stream << " tqWarning(\"Call to implementation of "; + + TQStringList::const_iterator nsIt = classData.namespaces.begin(); + TQStringList::const_iterator nsEndIt = classData.namespaces.end(); + for (; nsIt != nsEndIt; ++nsIt) + { + stream << *nsIt << "::"; + } + + stream << classData.name << "::" << method.name; + stream << " returned 'false' but error object is not valid!\");" << endl; + stream << endl; + stream << " error = TQT_DBusError::stdFailed(\""; + + nsIt = classData.namespaces.begin(); + for (; nsIt != nsEndIt; ++nsIt) + { + stream << *nsIt << "."; + } + + stream << classData.name << "." << method.name << " execution failed\");" + << endl; + stream << " }" << endl; + stream << endl; + + stream << " reply = TQT_DBusMessage::methodError(message, error);" << endl; + + stream << " }" << endl; + stream << endl; + stream << " return reply;" << endl; + stream << "}" << endl; + stream << endl; +} + +void MethodGenerator::writeSignalEmitter(const Class& classData, + const Method& method, TQTextStream& stream) +{ + stream << "bool " << classData.name << "::emit" << method.name << "("; + + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + for (; it != endIt;) + { + if (!(*it).isPrimitive && (*it).direction == Argument::In) + stream << "const "; + + stream << (*it).signature; + + if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&"; + + stream << " " << (*it).name; + + ++it; + if (it != endIt) stream << ", "; + } + + stream << ")" << endl; + + stream << "{" << endl; + + // TODO: create error or use enum for return + stream << " TQString path = objectPath();" << endl; + stream << " Q_ASSERT(!path.isEmpty());" << endl; + stream << endl; + + stream << " TQT_DBusMessage message = TQT_DBusMessage::signal(path, \""; + stream << classData.dbusName << "\", \"" << method.name << "\");" << endl; + stream << endl; + + it = method.arguments.begin(); + for (; it != endIt; ++it) + { + if ((*it).direction == Argument::In) + { + if (!(*it).annotatedType.isEmpty()) + { + // TODO: error handling + stream << " TQT_DBusData " << (*it).name << "Data;" << endl; + stream << " if (TQT_DBusDataConverter:convertToTQT_DBusData<" + << (*it).annotatedType << ">(" + << (*it).name << ", " << (*it).name << "Data" + << ") != TQT_DBusDataConverter::Success) return false;" + << endl; + stream << " message << " << (*it).name << "Data"; + } + else if (!(*it).accessor.isEmpty()) + { + stream << " message << TQT_DBusData::from" << (*it).accessor; + if (!(*it).subAccessor.isEmpty()) + { + stream << "(" << (*it).containerClass; + } + + stream << "(" << (*it).name << ")"; + + if (!(*it).subAccessor.isEmpty()) + { + stream << ")"; + } + } + else + stream << " message << " << (*it).name; + + stream << ";" << endl; + } + } + stream << endl; + + stream << " return handleSignalSend(message);" << endl; + + stream << "}" << endl; + stream << endl; +} + + +void MethodGenerator::writeInterfaceAsyncReplyHandler(const Class& classData, + const Method& method, TQTextStream& stream) +{ + stream << "void " << classData.name << "::" << method.name + << "AsyncReply("; + + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + while (it != endIt) + { + if (!(*it).isPrimitive && (*it).direction == Argument::In) + stream << "const "; + + stream << (*it).signature; + + if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&"; + + stream << " " << (*it).name; + + ++it; + if (it != endIt) stream << ", "; + } + stream << ")" << endl; + stream << endl; + stream << "{" << endl; + + stream << " TQMap::iterator findIt = m_asyncCalls.find(asyncCallId);" << endl; + stream << " if (findIt == m_asyncCalls.end()) return;" << endl; + stream << endl; + + stream << " TQT_DBusMessage call = findIt.data();" << endl; + stream << " m_asyncCalls.erase(findIt);" << endl; + stream << endl; + + stream << " TQT_DBusMessage reply = TQT_DBusMessage::methodReply(call);" + << endl; + + it = method.arguments.begin(); + for (++it; it != endIt; ++it) // skip asyncCallId at beginning + { + if (!(*it).annotatedType.isEmpty()) + { + stream << " TQT_DBusData " << (*it).name << "Data;" << endl; + + // TODO error handling + stream << " if (TQT_DBusDataConverter::convertToTQT_DBusData<" + << (*it).annotatedType << ">(" << (*it).name << ", " + << (*it).name << "Data" + << ") != TQT_DBusDataConverter::Success) return false;" + << endl; + stream << " reply << " << (*it).name << "Data;" << endl; + } + else if (!(*it).accessor.isEmpty()) + { + stream << " reply << TQT_DBusData::from" << (*it).accessor << "("; + + if ((*it).subAccessor.isEmpty()) + stream << (*it).name; + else + stream << (*it).containerClass << "(" << (*it).name << ")"; + + stream << ");" << endl; + } + else + stream << " reply << " << (*it).name << ";" << endl; + } + stream << endl; + + stream << " handleMethodReply(reply);" << endl; + + stream << "}" << endl; + stream << endl; + + stream << "void " << classData.name << "::" << method.name + << "AsyncError(int asyncCallId, const TQT_DBusError& error)"; + stream << endl; + + stream << "{" << endl; + + stream << " TQMap::iterator findIt = m_asyncCalls.find(asyncCallId);" << endl; + stream << " if (findIt == m_asyncCalls.end()) return;" << endl; + stream << endl; + + stream << " TQT_DBusMessage call = findIt.data();" << endl; + stream << " m_asyncCalls.erase(findIt);" << endl; + stream << endl; + + stream << " TQT_DBusMessage reply = TQT_DBusMessage::methodError(call, error);" + << endl; + stream << " handleMethodReply(reply);" << endl; + + stream << "}" << endl; + stream << endl; +} + +void MethodGenerator::writeInterfaceMainMethod(const Class& classData, + TQTextStream& stream) +{ + if (classData.methods.isEmpty()) return; + + stream << "bool " << classData.name + << "::handleMethodCall(const TQT_DBusMessage& message)" << endl; + stream << "{" << endl; + + stream << " if (message.interface() != \"" << classData.dbusName + << "\") return false;" << endl; + stream << endl; + + TQValueList::const_iterator it = classData.methods.begin(); + TQValueList::const_iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + stream << " if (message.member() == \"" << (*it).name << "\")" << endl; + stream << " {" << endl; + + if ((*it).async) + { + stream << " call" << (*it).name << "Async(message);" << endl; + stream << endl; + } + else + { + stream << " TQT_DBusMessage reply = call" << (*it).name + << "(message);" << endl; + stream << " handleMethodReply(reply);" << endl; + stream << endl; + } + stream << " return true;" << endl; + stream << " }" << endl; + stream << endl; + } + + stream << " return false; " << endl; + stream << "}" << endl; + stream << endl; +} + +void MethodGenerator::writeSignalHandler(const Class& classData, + TQTextStream& stream) +{ + stream << "void " << classData.name + << "::slotHandleDBusSignal(const TQT_DBusMessage& message)" << endl; + stream << "{" << endl; + + TQValueList::const_iterator it = classData.msignals.begin(); + TQValueList::const_iterator endIt = classData.msignals.end(); + bool first = true; + for (; it != endIt; ++it) + { + stream << " "; + + if (!first) + stream << "else "; + else + first = false; + + stream << "if (message.member() == \"" << (*it).name << "\")" << endl; + stream << " {" << endl; + + writeVariables(" ", *it, stream); + stream << endl; + + writeSignalEmit(*it, stream); + + stream << " }" << endl; + } + + stream << "}" << endl; + stream << endl; +} + +void MethodGenerator::writeProxyBegin(const Class& classData, TQTextStream& stream) +{ + stream << classData.name << "::" << classData.name + << "(const TQString& service, const TQString& path, TQObject* parent, const char* name)" << endl; + stream << " : TQObject(parent, name)," << endl; + stream << " m_baseProxy(new TQT_DBusProxy())" << endl; + stream << "{" << endl; + stream << " m_baseProxy->setInterface(\"" + << classData.dbusName << "\");" << endl; + stream << " m_baseProxy->setPath(path);" << endl; + stream << " m_baseProxy->setService(service);" << endl; + stream << endl; + + if (!classData.msignals.isEmpty()) + { + stream << " TQObject::connect(m_baseProxy, " + << "TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&))," << endl; + stream << " this, " + << " TQT_SLOT(slotHandleDBusSignal(const TQT_DBusMessage&)));" + << endl; + } + + if (!classData.asyncReplySignals.isEmpty()) + { + stream << " TQObject::connect(m_baseProxy, " + << "TQT_SIGNAL(asyncReply(int, const TQT_DBusMessage&))," << endl; + stream << " this, " + << " TQT_SLOT(slotHandleAsyncReply(int, const TQT_DBusMessage&)));" + << endl; + } + + stream << "}" << endl; + + stream << endl; + + stream << classData.name << "::~" << classData.name << "()" << endl; + stream << "{" << endl; + stream << " delete m_baseProxy;" << endl; + stream << "}" << endl; + stream << endl; + + stream << "void " << classData.name + << "::setConnection(const TQT_DBusConnection& connection)" << endl; + stream << "{" << endl; + stream << " m_baseProxy->setConnection(connection);" << endl; + stream << "}" << endl; + stream << endl; +} + +void MethodGenerator::writeProxyMethod(const TQString& className, + const Method& method, TQTextStream& stream) +{ + stream << "bool " << className << "::" << method.name + << (method.async ? "Async(" : "("); + + TQValueList::const_iterator it = method.arguments.begin(); + TQValueList::const_iterator endIt = method.arguments.end(); + for (; it != endIt; ++it) + { + if (!(*it).isPrimitive && (*it).direction == Argument::In) + stream << "const "; + + stream << (*it).signature; + + if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&"; + + stream << " " << (*it).name << ", "; + } + + stream << "TQT_DBusError& error)" << endl; + + stream << "{" << endl; + stream << " TQValueList parameters;" << endl; + stream << endl; + + uint outCount = 0; + + it = method.arguments.begin(); + for (; it != endIt; ++it) + { + if ((*it).direction == Argument::Out) + { + ++outCount; + continue; + } + + if (!(*it).annotatedType.isEmpty()) + { + stream << " TQT_DBusData " << (*it).name << "Data;" << endl; + + // TODO error handling + stream << " if (TQT_DBusDataConverter::convertToTQT_DBusData<" + << (*it).annotatedType << ">(" << (*it).name << ", " + << (*it).name << "Data" + << ") != TQT_DBusDataConverter::Success) return false;" + << endl; + stream << " parameters << " << (*it).name << "Data;" << endl; + } + else if (!(*it).accessor.isEmpty()) + { + stream << " parameters << TQT_DBusData::from" << (*it).accessor << "("; + + if ((*it).subAccessor.isEmpty()) + stream << (*it).name; + else + stream << (*it).containerClass << "(" << (*it).name << ")"; + + stream << ");" << endl; + } + else + stream << " parameters << " << (*it).name << ";" << endl; + } + + stream << endl; + + if (outCount == 0 && method.noReply) + { + stream << " if (!m_baseProxy->send(\"" << method.name + << "\", parameters))" << endl; + stream << " {" << endl; + stream << " error = m_baseProxy->lastError();" << endl; + stream << " return false;" << endl; + stream << " }" << endl; + stream << " return true;" << endl; + stream << "}" << endl; + stream << endl; + return; + } + + if (method.async) + { + stream << " asyncCallId = m_baseProxy->sendWithAsyncReply(\""; + stream << method.name << "\", parameters);" << endl; + stream << endl; + + stream << " if (asyncCallId != 0) m_asyncCalls[asyncCallId] = \"" + << method.name << "\";" << endl; + stream << endl; + + stream << " error = TQT_DBusError();"; + stream << endl; + + stream << " return (asyncCallId != 0);" << endl; + stream << "}" << endl; + stream << endl; + return; + } + + stream << " TQT_DBusMessage reply = m_baseProxy->sendWithReply(\""; + stream << method.name << "\", parameters, &error);" << endl; + stream << endl; + + stream << " if (reply.type() != TQT_DBusMessage::ReplyMessage) return false;" + << endl; + + if (outCount == 0) + { + stream << " return true;" << endl; + stream << "}" << endl; + stream << endl; + return; + } + + stream << endl; + + // TODO: create error or use enum for return + stream << " if (reply.count() != " << outCount << ") return false;" << endl; + stream << endl; + + bool firstAccessor = true; + bool firstSubAccessor = true; + + it = method.arguments.begin(); + for (; it != endIt; ++it) + { + if ((*it).direction == Argument::In) continue; + + --outCount; + + if (!(*it).annotatedType.isEmpty()) + { + // TODO error handling + stream << " if (TQT_DBusDataConverter::convertFromTQT_DBusData<" + << (*it).annotatedType << ">(reply.front(), " + << (*it).name + << ") != TQT_DBusDataConverter::Success) return false;" + << endl; + } + else if (!(*it).accessor.isEmpty()) + { + if (firstAccessor) + { + stream << " bool ok = false;" << endl; + stream << endl; + firstAccessor = false; + } + + if ((*it).subAccessor.isEmpty()) + { + stream << " " << (*it).name << " = reply.front().to" + << (*it).accessor << "(&ok);" << endl; + } + else + { + if (firstSubAccessor) + { + stream << " bool subOK = false;" << endl; + stream << endl; + firstSubAccessor = false; + } + + stream << " " << (*it).name << " = reply.front().to" + << (*it).accessor << "(&ok).to" << (*it).subAccessor + << "(&subOK);" << endl; + + // TODO: create error or use enum for return + stream << " if (!subOK) return false;" << endl; + } + + // TODO: create error or use enum for return + stream << " if (!ok) return false;" << endl; + } + else + stream << " " << (*it).name << " = reply.front();" << endl; + stream << endl; + + if (outCount > 0) + { + stream << " reply.pop_front();" << endl; + stream << endl; + } + } + + stream << " return true;" << endl; + + stream << "}" << endl; + stream << endl; +} + +void MethodGenerator::writeProxyGenericProperty(const Class& classData, + TQTextStream& stream) +{ + stream << "void " << classData.name + << "::setDBusProperty(const TQString& name, " + << "const TQT_DBusVariant& value, TQT_DBusError& error)" + << endl; + stream << "{" << endl; + + stream << " TQT_DBusConnection connection = m_baseProxy->connection();" << endl; + stream << endl; + stream << " TQT_DBusMessage message = TQT_DBusMessage::methodCall(" + << "m_baseProxy->service(), m_baseProxy->path(), " + << "\"org.freedesktop.DBus.Properties\", \"Set\");" << endl; + stream << endl; + + stream << " message << TQT_DBusData::fromString(m_baseProxy->interface());" + << endl; + stream << " message << TQT_DBusData::fromString(name);" << endl; + stream << " message << TQT_DBusData::fromVariant(value);" << endl; + stream << endl; + + stream << " connection.sendWithReply(message, &error);" << endl; + + stream << "}" << endl; + + stream << endl; + + stream << "TQT_DBusVariant " << classData.name + << "::getDBusProperty(const TQString& name, TQT_DBusError& error) const" + << endl; + stream << "{" << endl; + + stream << " TQT_DBusConnection connection = m_baseProxy->connection();" << endl; + stream << endl; + + stream << " TQT_DBusMessage message = TQT_DBusMessage::methodCall(" + << "m_baseProxy->service(), m_baseProxy->path(), " + << "\"org.freedesktop.DBus.Properties\", \"Get\");" << endl; + stream << endl; + + stream << " message << TQT_DBusData::fromString(m_baseProxy->interface());" + << endl; + stream << " message << TQT_DBusData::fromString(name);" << endl; + stream << endl; + + stream << " TQT_DBusMessage reply = connection.sendWithReply(message, &error);" + << endl; + stream << endl; + + stream << " if (reply.type() != TQT_DBusMessage::ReplyMessage)" + << " return TQT_DBusVariant();" << endl; + stream << " if (reply.count() != 1) return TQT_DBusVariant();" << endl; + + stream << endl; + + stream << " bool ok = false;" << endl; + stream << " TQT_DBusVariant value = reply.front().toVariant(&ok);" << endl; + + // TODO generate error + stream << " if (!ok) return TQT_DBusVariant();" << endl; + stream << endl; + + stream << " return value;" << endl; + + stream << "}" << endl; + + stream << endl; +} + +void MethodGenerator::writeProxyProperty(const Class& classData, + const Property& property, TQTextStream& stream) +{ + if (property.write) + { + stream << "void " << classData.name << "::set" << property.name << "("; + + if (!property.isPrimitive) stream << "const "; + + stream << property.signature; + + if (!property.isPrimitive) stream << "&"; + + stream << " value, TQT_DBusError& error)" << endl; + stream << "{" << endl; + stream << " TQT_DBusVariant variant;" << endl; + + if (!property.annotatedType.isEmpty()) + { + // TODO: error handling + stream << " TQT_DBusDataConverter::convertToTQT_DBusData<" + << property.annotatedType << ">(value, variant.value);" + << endl; + } + else if (!property.accessor.isEmpty()) + { + stream << " variant.value = TQT_DBusData::from" + << property.accessor << "("; + + if (property.subAccessor.isEmpty()) + stream << "value"; + else + stream << property.containerClass << "(value)"; + + stream << ");" << endl; + } + else + stream << " variant.value = TQT_DBusData(value);" << endl; + + stream << " variant.signature = \"" << property.dbusSignature << "\";" + << endl; + + stream << endl; + stream << " setDBusProperty(\"" << property.name + << "\", variant, error);" << endl; + + stream << "}" << endl; + stream << endl; + } + + if (property.read) + { + stream << property.signature << " " << classData.name + << "::get" << property.name << "(TQT_DBusError& error) const" << endl; + stream << "{" << endl; + + stream << " TQT_DBusVariant variant = getDBusProperty(\"" + << property.name << "\", error);" << endl; + stream << endl; + stream << " if (error.isValid()) return " + << property.signature << "();" << endl; + stream << endl; + + if (!property.annotatedType.isEmpty()) + { + stream << " " << property.signature << " result;" << endl; + + // TODO error handling + stream << " TQT_DBusDataConverter::convertFromTQT_DBusData<" + << property.annotatedType << ">(variant.value, result);" + << endl; + } + else if (!property.accessor.isEmpty()) + { + stream << " bool ok = false;" << endl; + stream << endl; + + if (property.subAccessor.isEmpty()) + { + stream << " " << property.signature << " result = "; + stream << " variant.value.to" << property.accessor + << "(&ok);" << endl; + } + else + { + stream << " bool subOK = false;" << endl; + stream << endl; + + stream << " " << property.signature << " result = "; + stream << " variant.value.to" + << property.accessor << "(&ok).to" << property.subAccessor + << "(&subOK);" << endl; + + // TODO: create error + stream << " if (!subOK) {}" << endl; + } + + // TODO: create error + stream << " if (!ok) {}" << endl; + } + else + stream << " " << property.signature << " result = variant.value;"; + stream << endl; + + stream << " return result;" << endl; + stream << "}" << endl; + stream << endl; + } +} + +void MethodGenerator::writeProxyAsyncReplyHandler(const Class& classData, + TQTextStream& stream) +{ + stream << "void " << classData.name + << "::slotHandleAsyncReply(int asyncCallId, const TQT_DBusMessage& message)" << endl; + stream << "{" << endl; + + stream << " TQMap::iterator findIt = " + << "m_asyncCalls.find(asyncCallId);" << endl; + stream << " if (findIt == m_asyncCalls.end()) return;" << endl; + stream << endl; + stream << " const TQString signalName = findIt.data();" << endl; + stream << " m_asyncCalls.erase(findIt);" << endl; + stream << endl; + + TQValueList::const_iterator it = classData.asyncReplySignals.begin(); + TQValueList::const_iterator endIt = classData.asyncReplySignals.end(); + bool first = true; + for (; it != endIt; ++it) + { + stream << " "; + + if (!first) + stream << "else "; + else + first = false; + + stream << "if (signalName == \"" << (*it).name << "\")" << endl; + stream << " {" << endl; + + // FIXME tricking writeVariables and writeSignalEmit into writing + // the reply emit code by manipulating arguments and name + stream << " int _asyncCallId = asyncCallId;" << endl << endl; + + stream << " if (message.type() == TQT_DBusMessage::ErrorMessage) {" << endl; + stream << " emit AsyncErrorResponseDetected(_asyncCallId, message.error());" << endl; + stream << " }" << endl << endl; + + Method signal = *it; + signal.arguments.pop_front(); + + writeVariables(" ", signal, stream); + stream << endl; + + signal = *it; + signal.name += "AsyncReply"; + + writeSignalEmit(signal, stream); + + stream << " }" << endl; + } + + stream << "}" << endl; + stream << endl; +} + +void MethodGenerator::writeIntrospectionDataMethod(const Class& classData, + TQTextStream& stream) +{ + stream << "void " << classData.name + << "::buildIntrospectionData(TQDomElement& interfaceElement)" << endl; + stream << "{" << endl; + + stream << " interfaceElement.setAttribute(\"name\", \"" + << classData.dbusName << "\");" << endl; + stream << endl; + + bool firstMethod = true; + bool firstArgument = true; + + TQValueList::const_iterator it = classData.methods.begin(); + TQValueList::const_iterator endIt = classData.methods.end(); + for (; it != endIt; ++it) + { + if (firstMethod) + { + firstMethod = false; + stream << " TQDomDocument document = interfaceElement.ownerDocument();" << endl; + stream << " TQDomElement methodElement = document.createElement(" + << "\"method\");" << endl; + } + else + { + stream << endl; + stream << " methodElement = document.createElement(" + << "\"method\");" << endl; + } + + writeMethodIntrospection(*it, firstArgument, stream); + + stream << " interfaceElement.appendChild(methodElement);" << endl; + } + + it = classData.msignals.begin(); + endIt = classData.msignals.end(); + for (; it != endIt; ++it) + { + if (firstMethod) + { + firstMethod = false; + stream << " TQDomDocument document = interfaceElement.ownerDocument();" << endl; + stream << endl; + stream << " TQDomElement methodElement = document.createElement(" + << "\"signal\");" << endl; + } + else + { + stream << endl; + stream << " methodElement = document.createElement(" + << "\"signal\");" << endl; + } + + writeMethodIntrospection(*it, firstArgument, stream); + + stream << " interfaceElement.appendChild(methodElement);" << endl; + } + + stream << "}" << endl; + stream << endl; +} + +void MethodGenerator::writeNodePrivate(const Class& classData, TQTextStream& stream) +{ + stream << "class " << classData.name + << "::Private : public org::freedesktop::DBus::Introspectable" << endl; + stream << "{" << endl; + stream << "public:" << endl; + stream << " virtual ~Private();" << endl; + stream << endl; + + stream << "public:" << endl; + stream << " TQMap interfaces;" << endl; + stream << " TQString introspectionData;" << endl; + stream << endl; + stream << " TQT_DBusConnection connection;" << endl; + stream << " TQString objectPath;" << endl; + stream << endl; + + stream << "protected:" << endl; + stream << " virtual bool Introspect(TQString& data, TQT_DBusError& error);" + << endl; + stream << endl; + stream << " virtual void handleMethodReply(const TQT_DBusMessage& reply);" + << endl; + + stream << "private:" << endl; + stream << " void cacheIntrospectionData();" << endl; + + stream << "};" << endl; + stream << endl; +} + +void MethodGenerator::writeNodeBegin(const Class& classData, TQTextStream& stream) +{ + stream << classData.name << "::" << classData.name + << "() : TQT_DBusObjectBase()," << endl; + stream << " m_private(new Private())" << endl; + stream << "{" << endl; + stream << "}" << endl; + stream << endl; + + stream << classData.name << "::~" << classData.name << "()" << endl; + stream << "{" << endl; + stream << " unregisterObject();" << endl; + stream << endl; + stream << " delete m_private;" << endl; + stream << "}" << endl; + stream << endl; +} + +void MethodGenerator::writeNodeMethods(const Class& classData, + const TQValueList& interfaces, TQTextStream& stream) +{ + writeNodeInitialization(classData, interfaces, stream); + + stream << "void " << classData.name << "::unregisterObject()" << endl; + stream << "{" << endl; + stream << " if (m_private->objectPath.isEmpty()) return;" << endl; + stream << endl; + stream << " m_private->connection.unregisterObject(m_private->objectPath);" << endl; + stream << endl; + stream << " m_private->connection = TQT_DBusConnection();" << endl; + stream << " m_private->objectPath = TQString();" << endl; + stream << "}" << endl; + stream << endl; + + stream << "bool " << classData.name + << "::handleMethodCall(const TQT_DBusMessage& message)" << endl; + stream << "{" << endl; + stream << " TQMap::iterator findIt = " + << "m_private->interfaces.find(message.interface());" << endl; + stream << " if (findIt == m_private->interfaces.end()) return false;" + << endl; + stream << endl; + stream << " return delegateMethodCall(message, findIt.data());" << endl; + stream << "}" << endl; + stream << endl; + + stream << classData.name << "::Private::~Private()" << endl; + stream << "{" << endl; + stream << " TQMap::const_iterator it = " + << "interfaces.begin();" << endl; + stream << " TQMap::const_iterator endIt = " + << "interfaces.end();" << endl; + stream << " for (; it != endIt; ++it)" << endl; + stream << " {" << endl; + stream << " TQT_DBusObjectBase* interface = it.data();" << endl; + stream << " if (interface != this)" << endl; + stream << " delete interface;" << endl; + stream << " }" << endl; + stream << " interfaces.clear();" << endl; + stream << "}" << endl; + stream << endl; + + stream << "bool " << classData.name << "::Private" + << "::Introspect(TQString& data, TQT_DBusError& error)" << endl; + stream << "{" << endl; + stream << " Q_UNUSED(error);" << endl; + stream << " if (introspectionData.isEmpty()) cacheIntrospectionData();" + << endl; + stream << endl; + stream << " data = introspectionData;" << endl; + stream << endl; + stream << " return true;" << endl; + stream << "}" << endl; + stream << endl; + + stream << "void " << classData.name << "::Private" + << "::handleMethodReply(const TQT_DBusMessage& reply)" << endl; + stream << "{" << endl; + stream << " connection.send(reply);" << endl; + stream << "}" << endl; + stream << endl; + + writeNodeIntrospection(classData, interfaces, stream); +} + +// End of File diff --git a/src/tools/dbusxml2qt3/methodgen.h b/src/tools/dbusxml2qt3/methodgen.h new file mode 100644 index 0000000..9954fb2 --- /dev/null +++ b/src/tools/dbusxml2qt3/methodgen.h @@ -0,0 +1,153 @@ +/* +* Copyright (C) 2007 Kevin Krammer +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +#if !defined(METHODGEN_H_INCLUDED) +#define METHODGEN_H_INCLUDED + +// TQt includes +#include +#include + +// forward declarations +class TQTextStream; + +class Argument +{ +public: + enum Direction + { + In, + Out + }; + + TQString name; + TQString annotatedType; + TQString signature; + TQString accessor; + TQString subAccessor; + TQString containerClass; + Direction direction; + bool isPrimitive; + + TQStringList forwardDeclarations; + TQMap headerIncludes; + TQMap sourceIncludes; + + TQString dbusSignature; +}; + +class Method +{ +public: + TQString name; + TQValueList arguments; + bool noReply; + bool async; +}; + +class Property : public Argument +{ +public: + bool read; + bool write; +}; + +class Class +{ +public: + enum Role + { + Interface, + Proxy, + Node + }; + + TQString name; + TQString dbusName; + TQStringList namespaces; + TQValueList methods; + TQValueList msignals; + TQValueList properties; + + TQValueList asyncMethods; + TQValueList asyncReplySignals; + TQValueList asyncReplyMethods; +}; + +class MethodGenerator +{ +public: + static bool extractMethods(const TQDomElement& interfaceElement, + Class& classData); + + static void writeMethodDeclaration(const Method& method, bool pureVirtual, + bool withError, TQTextStream& stream); + + static void writePropertyDeclaration(const Property& property, bool pureVirtual, + TQTextStream& stream); + + static void writeMethodCallDeclaration(const Method& method, + TQTextStream& stream); + + static void writeMethodCall(const Class& classData, const Method& method, + TQTextStream& stream); + + static void writeSignalEmitter(const Class& classData, const Method& method, + TQTextStream& stream); + + static void writeInterfaceAsyncReplyHandler(const Class& classData, + const Method& method, + TQTextStream& stream); + + static void writeInterfaceMainMethod(const Class& classData, + TQTextStream& stream); + + static void writeSignalHandler(const Class& classData, TQTextStream& stream); + + static void writeProxyBegin(const Class& classData, TQTextStream& stream); + + static void writeProxyMethod(const TQString& className, const Method& method, + TQTextStream& stream); + + static void writeProxyGenericProperty(const Class& classData, + TQTextStream& stream); + + static void writeProxyProperty(const Class& classData, const Property& property, + TQTextStream& stream); + + static void writeProxyAsyncReplyHandler(const Class& classData, + TQTextStream& stream); + + static void writeIntrospectionDataMethod(const Class& classData, + TQTextStream& stream); + + static void writeNodePrivate(const Class& classData, TQTextStream& stream); + + static void writeNodeBegin(const Class& classData, TQTextStream& stream); + + static void writeNodeMethods(const Class& classData, + const TQValueList& interfaces, TQTextStream& stream); +}; + +#endif + +// End of File diff --git a/src/tqdbusatomic.h b/src/tqdbusatomic.h new file mode 100644 index 0000000..50ceec3 --- /dev/null +++ b/src/tqdbusatomic.h @@ -0,0 +1,40 @@ +/* qdbusatomic.h Dummy reference counter + * + * Copyright (C) 2005 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef ATOMIC_H +#define ATOMIC_H + +class Atomic +{ +public: + Atomic(int value); + + void ref(); + + bool deref(); + +private: + int m_value; +}; + +#endif diff --git a/src/tqdbusconnection.cpp b/src/tqdbusconnection.cpp new file mode 100644 index 0000000..0360456 --- /dev/null +++ b/src/tqdbusconnection.cpp @@ -0,0 +1,408 @@ +/* qdbusconnection.cpp + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2005-2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include + +#include "tqdbusconnection.h" +#include "tqdbuserror.h" +#include "tqdbusmessage.h" +#include "tqdbusconnection_p.h" + +#include "tqdbusmessage_p.h" + +QT_STATIC_CONST_IMPL char *TQT_DBusConnection::default_connection_name = "qt_dbus_default_connection"; + +class TQT_DBusConnectionManager +{ +public: + TQT_DBusConnectionManager(): default_connection(0) {} + ~TQT_DBusConnectionManager(); + void bindToApplication(); + TQT_DBusConnectionPrivate *connection(const TQString &name) const; + void removeConnection(const TQString &name); + void setConnection(const TQString &name, TQT_DBusConnectionPrivate *c); + + static TQT_DBusConnectionManager* instance() { + if (managerInstance == 0) managerInstance = new TQT_DBusConnectionManager(); + return managerInstance; + } + +private: + TQT_DBusConnectionPrivate *default_connection; + // FIXME-QT4 TQHash connectionHash; + typedef TQMap ConnectionHash; + ConnectionHash connectionHash; + + static TQT_DBusConnectionManager* managerInstance; +}; + +// FIXME-QT4 TQ_GLOBAL_STATIC(TQT_DBusConnectionManager, manager); +TQT_DBusConnectionManager* TQT_DBusConnectionManager::managerInstance = 0; +TQT_DBusConnectionManager* manager() { + return TQT_DBusConnectionManager::instance(); +} + +TQT_DBusConnectionPrivate *TQT_DBusConnectionManager::connection(const TQString &name) const +{ + if (name == TQString::fromLatin1(TQT_DBusConnection::default_connection_name)) + return default_connection; + + ConnectionHash::const_iterator it = connectionHash.find(name); + + return (it != connectionHash.end() ? it.data() : 0); +} + +void TQT_DBusConnectionManager::removeConnection(const TQString &name) +{ + TQT_DBusConnectionPrivate *d = 0; + if (name == TQString::fromLatin1(TQT_DBusConnection::default_connection_name)) { + d = default_connection; + default_connection = 0; + } else { + ConnectionHash::iterator it = connectionHash.find(name); + if (it == connectionHash.end()) + return; + + d = it.data(); + connectionHash.erase(it); + } + if (!d->ref.deref()) + delete d; +} + +TQT_DBusConnectionManager::~TQT_DBusConnectionManager() +{ + if (default_connection) { + delete default_connection; + default_connection = 0; + } +/* FIXME-QT4 + for (TQHash::const_iterator it = connectionHash.constBegin(); + it != connectionHash.constEnd(); ++it) { + delete it.value(); + }*/ + for (ConnectionHash::const_iterator it = connectionHash.constBegin(); + it != connectionHash.constEnd(); ++it) + { + delete it.data(); + } + connectionHash.clear(); +} + +void TQT_DBusConnectionManager::bindToApplication() +{ + if (default_connection) { + default_connection->bindToApplication(); + } +/* FIXME-QT4 + for (TQHash::const_iterator it = connectionHash.constBegin(); + it != connectionHash.constEnd(); ++it) { + (*it)->bindToApplication(); + }*/ + for (ConnectionHash::const_iterator it = connectionHash.constBegin(); + it != connectionHash.constEnd(); ++it) + { + it.data()->bindToApplication(); + } +} + +void qDBusBindToApplication() +{ + manager()->bindToApplication(); +} + +void TQT_DBusConnectionManager::setConnection(const TQString &name, TQT_DBusConnectionPrivate *c) +{ + if (name == TQString::fromLatin1(TQT_DBusConnection::default_connection_name)) + default_connection = c; + else + connectionHash[name] = c; +} + + +TQT_DBusConnection::TQT_DBusConnection() : d(0) +{ +} + +TQT_DBusConnection::TQT_DBusConnection(const TQString &name) +{ + d = manager()->connection(name); + if (d) + d->ref.ref(); +} + +TQT_DBusConnection::TQT_DBusConnection(const TQT_DBusConnection &other) +{ + d = other.d; + if (d) + d->ref.ref(); +} + +TQT_DBusConnection::~TQT_DBusConnection() +{ + if (d && !d->ref.deref()) + delete d; +} + +TQT_DBusConnection &TQT_DBusConnection::operator=(const TQT_DBusConnection &other) +{ + if (other.d) + other.d->ref.ref(); +/* FIXME-QT4 + TQT_DBusConnectionPrivate *old = static_cast( + q_atomic_set_ptr(&d, other.d));*/ + TQT_DBusConnectionPrivate* old = d; + d = other.d; + if (old && !old->ref.deref()) + delete old; + + return *this; +} + +TQT_DBusConnection TQT_DBusConnection::sessionBus() +{ + return addConnection(TQT_DBusConnection::SessionBus); +} + +TQT_DBusConnection TQT_DBusConnection::systemBus() +{ + return addConnection(TQT_DBusConnection::SystemBus); +} + +TQT_DBusConnection TQT_DBusConnection::addConnection(BusType type, const TQString &name) +{ +// Q_ASSERT_X(TQCoreApplication::instance(), "TQT_DBusConnection::addConnection", +// "Cannot create connection without a Q[Core]Application instance"); + + TQT_DBusConnectionPrivate *d = manager()->connection(name); + if (d) + return TQT_DBusConnection(name); + + d = new TQT_DBusConnectionPrivate; + DBusConnection *c = 0; + switch (type) { + case SystemBus: + c = dbus_bus_get(DBUS_BUS_SYSTEM, &d->error); + break; + case SessionBus: + c = dbus_bus_get(DBUS_BUS_SESSION, &d->error); + break; + case ActivationBus: + c = dbus_bus_get(DBUS_BUS_STARTER, &d->error); + break; + } + d->setConnection(c); //setConnection does the error handling for us + + manager()->setConnection(name, d); + + return TQT_DBusConnection(name); +} + +TQT_DBusConnection TQT_DBusConnection::addConnection(const TQString &address, + const TQString &name) +{ +// Q_ASSERT_X(TQCoreApplication::instance(), "TQT_DBusConnection::addConnection", +// "Cannot create connection without a Q[Core]Application instance"); + + TQT_DBusConnectionPrivate *d = manager()->connection(name); + if (d) + return TQT_DBusConnection(name); + + d = new TQT_DBusConnectionPrivate; + // setConnection does the error handling for us + d->setConnection(dbus_connection_open(address.utf8().data(), &d->error)); + + manager()->setConnection(name, d); + + return TQT_DBusConnection(name); +} + +void TQT_DBusConnection::closeConnection(const TQString &name) +{ + manager()->removeConnection(name); +} + +void TQT_DBusConnectionPrivate::timerEvent(TQTimerEvent *e) +{ + DBusTimeout *timeout = timeouts[e->timerId()]; + dbus_timeout_handle(timeout); +} + +bool TQT_DBusConnection::send(const TQT_DBusMessage &message) const +{ + if (!d || !d->connection) + return false; + + DBusMessage *msg = message.toDBusMessage(); + if (!msg) + return false; + + bool isOk = dbus_connection_send(d->connection, msg, 0); + dbus_message_unref(msg); + return isOk; +} + +int TQT_DBusConnection::sendWithAsyncReply(const TQT_DBusMessage &message, TQObject *receiver, + const char *method) const +{ + if (!d || !d->connection) + return 0; + + return d->sendWithReplyAsync(message, receiver, method); +} + +TQT_DBusMessage TQT_DBusConnection::sendWithReply(const TQT_DBusMessage &message, TQT_DBusError *error) const +{ + if (!d || !d->connection) + return TQT_DBusMessage::fromDBusMessage(0); + + DBusMessage *msg = message.toDBusMessage(); + if (!msg) + return TQT_DBusMessage::fromDBusMessage(0); + + DBusMessage *reply = dbus_connection_send_with_reply_and_block(d->connection, msg, -1, &d->error); + + if (d->handleError() && error) + *error = d->lastError; + + dbus_message_unref(msg); + + TQT_DBusMessage ret = TQT_DBusMessage::fromDBusMessage(reply); + if (reply) { + dbus_message_unref(reply); + } + + bool dbus_error_set = dbus_error_is_set(&d->error); + ret.d->error.setDBUSError(dbus_error_set); + if (error) error->setDBUSError(dbus_error_set); + + return ret; +} + +void TQT_DBusConnection::flush() const +{ + if (!d || !d->connection) return; + + d->flush(); +} + +void TQT_DBusConnection::dispatch() const +{ + if (!d || !d->connection) return; + + d->dispatch(); +} + +void TQT_DBusConnection::scheduleDispatch() const +{ + if (!d || !d->connection) return; + + d->scheduleDispatch(); +} + +bool TQT_DBusConnection::connect(TQObject* object, const char* slot) +{ + if (!d || !d->connection || !object || !slot) + return false; + + bool ok = object->connect(d, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), slot); + + return ok; +} + +bool TQT_DBusConnection::disconnect(TQObject* object, const char* slot) +{ + if (!d || !d->connection || !object || !slot) + return false; + + bool ok = d->disconnect(object, slot); + + return ok; +} + +bool TQT_DBusConnection::registerObject(const TQString& path, TQT_DBusObjectBase* object) +{ + if (!d || !d->connection || !object || path.isEmpty()) + return false; + + TQT_DBusConnectionPrivate::ObjectMap::const_iterator it = d->registeredObjects.find(path); + if (it != d->registeredObjects.end()) + return false; + + d->registeredObjects.insert(path, object); + + return true; +} + +void TQT_DBusConnection::unregisterObject(const TQString &path) +{ + if (!d || !d->connection || path.isEmpty()) + return; + + TQT_DBusConnectionPrivate::ObjectMap::iterator it = d->registeredObjects.find(path); + if (it == d->registeredObjects.end()) + return ; + + d->registeredObjects.erase(it); +} + +bool TQT_DBusConnection::isConnected( ) const +{ + return d && d->connection && dbus_connection_get_is_connected(d->connection); +} + +TQT_DBusError TQT_DBusConnection::lastError() const +{ + return d ? d->lastError : TQT_DBusError(); +} + +TQString TQT_DBusConnection::uniqueName() const +{ + return d && d->connection ? + TQString::fromUtf8(dbus_bus_get_unique_name(d->connection)) + : TQString(); +} + +bool TQT_DBusConnection::requestName(const TQString &name, int modeFlags) +{ + Q_ASSERT(modeFlags >= 0); + + if (!d || !d->connection) + return false; + + if (modeFlags < 0) + return false; + + int dbusFlags = 0; + if (modeFlags & AllowReplace) + dbusFlags |= DBUS_NAME_FLAG_ALLOW_REPLACEMENT; + if (modeFlags & ReplaceExisting) + dbusFlags |= DBUS_NAME_FLAG_REPLACE_EXISTING; + + dbus_bus_request_name(d->connection, name.utf8(), dbusFlags, &d->error); + + return !d->handleError(); +} + +#include "tqdbusconnection.moc" diff --git a/src/tqdbusconnection.h b/src/tqdbusconnection.h new file mode 100644 index 0000000..9fde84b --- /dev/null +++ b/src/tqdbusconnection.h @@ -0,0 +1,663 @@ +/* qdbusconnection.h TQT_DBusConnection object + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2005-2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSCONNECTION_H +#define TQDBUSCONNECTION_H + +/** + * @mainpage TQt3 Bindings for D-Bus + * + * D-Bus is an IPC (inter process communication) technology designed to allow + * applications to interoperate without requiring tight coupling. + * + * For more information about D-Bus itself see its website: + * http://www.freedesktop.org/wiki/Software_2fdbus + * + * The TQt3 D-Bus bindings described here are a TQt3 style API around the base + * implementation to enable TQt3 developers to use D-Bus in their applications + * without requiring them to know about the details of the C based D-Bus API. + * + * The two main use cases are: + * - using the API to access service implemented in other applications. + * See section @ref dbusclient for an introduction on this + * + * - using the API to provide access to services implemented in your application + * See section @ref dbusservice for an introduction on this + * + * Of course an application can do both at the same time. + */ + +/** + * @page dbusconventions Naming and syntax conventions in D-Bus + * + * @section dbusconventions-servicename Service names + * + * The service name is D-Bus application identifier, i.e. either + * the unique name handed out to the peer application by the bus on connect + * (see TQT_DBusConnection::uniqueName()) or, more likely, a well known name the + * peer application has requested, see TQT_DBusConnection::requestName() + * + * Such well known names have the form of word separated by dots, like + * Internet domain names but in reverse order. + * + * For example the name for the bus itself (the D-Bus daemon) would be + * @code + * "org.freedesktop.DBus" + * @endcode + * + * @section dbusconventions-objectpath Object paths + * + * The object path is like an address within the peer host application. + * The path format looks like a Unix file path, i.e. words separated by + * slash @c '/' characters. + * + * For example the path for the bus itself (the D-Bus daemon's main object) + * would be + * @code + * "/org/freedesktop/DBus" + * @endcode + * + * @section dbusconventions-interfacename Interface names + * + * The interface name specifies which group of methods and signals + * implemented by the peer service object is used in proxy operations. + * + * Interface names have the form of word separated by dots, like Internet + * domain names but in reverse order or like a fully qualified Java class name. + * + * For example the interface for the bus itself (the D-Bus daemon's main + * interface) would be + * @code + * "org.freedesktop.DBus" + * @endcode + * + * @section dbusconventions-errorname Error names + * + * A D-Bus error name is a sequence of words separated by dots, similar + * to D-Bus service names or interface names, or like a fully qualified + * Java class name. + * + * For example if a D-Bus service does not handle a method invocation sent + * to it because it doesn't know about the method it will return a D-Bus + * error named + * @code + * "org.freedesktop.DBus.Error.UnknownMethod" + * @endcode + * TQT_DBusError can create some of the more common errors based on a type value + * and decode their names into the type respectively. See TQT_DBusError#ErrorType + * + * @section dbusconventions-membername Method and signal names + * + * There is no mandatory convention for member names, neither for methods nor + * for signals. + * + * However, using the standard interfaces of D-Bus as a hint, it is recommended + * to use "camel case" names starting with an uppercase letter, for example + * @code + * "GetConnectionUnixUser" + * @endcode + */ + +#include "tqdbusmacros.h" +#include + +class TQT_DBusConnectionPrivate; +class TQT_DBusError; +class TQT_DBusMessage; +class TQT_DBusObjectBase; +class TQObject; + +/** + * @brief Provides access to a specific D-Bus bus + * + * In order to access a D-Bus message bus an application has to connect to it. + * This is very similar to connecting to an FTP server using TQFtp, where any + * number of commands can be sent in sequence over the same connection. + * + * Additionally to the asynchronous command execution provided by TQFtp a + * TQT_DBusConnection can also execute synchronous (blocking) calls so the + * code around those calls stays closer to in-process method incovations. + * + * However it is recommended to only perform blocking calls on D-Bus service + * methods that are likely to be processed fast. + * + * TQT_DBusConnection implements a shared resource, i.e. if you create a + * connection with a specific name in one part of your code and then + * create one with the same name somewhere else, the second creation will + * actually return the same shared connection object the first caller created. + * + * The application can be connected to more than one message bus simultaniously + * using one or more connections per bus, however the most common case is to + * have one connection per bus. + * + * The two main bus types are: + * - System bus: a bus connecting applications on one system across user + * or session boundaries, for example allowing to communicate + * with system services like printer spoolers, etc + * + * - Session bus: a bus connecting applications within one user session, for + * example started at login or by a session manager. Use cases + * or this kind of bus would be accessing user specific + * resources like addressbooks, retrieving user settings or + * controlling session services (e.g. disabling screensaver + * in a video player application during playback) + * + * While TQT_DBusConnection provides the basic API to access D-Bus services + * it is more convenient to use TQT_DBusProxy on top of the connection. + * + * See sections @ref dbusclient and @ref dbusservice for examples + */ +class TQDBUS_EXPORT TQT_DBusConnection +{ +public: + /** + * DBus bus types + */ + enum BusType + { + /** + * The session bus is a user and user session specific message + * channel. It will usually be started by a login script or a + * session manager. + */ + SessionBus, + + /** + * The system bus is a message channel bridging user level and + * system level process boundaries, e.g. it can allow a user process + * with normal user access restrictions to perform a limited subset + * of operations on a process running with elevated rights. + * + * @warning if an applications exposed services on the system bus, i.e. + * registers objects using registerObject(), it should be + * carefully examined on potential security issues + */ + SystemBus, + + // TODO find out about ActivationBus purpose + ActivationBus + }; + + /** + * @brief Creates an empty/disconnected connection handle + * + * This is mainly used for initializing variables of this type, i.e. like + * the default TQString constructor. + * + * A variable set to such an empty connection can be assigned a working + * connection at any time. + */ + TQT_DBusConnection(); + + /** + * @brief Creates a connection handle to a named connection + * + * This will result in an disconnected connection handle if no + * connection with that name has been created by addConnection before. + * + * Therefore it is recommended to use addConnection() instead to get a + * connection handle. + * + * @param name identifier of the shared connection object + */ + TQT_DBusConnection(const TQString &name); + + /** + * @brief Creates a shallow copy of the given connection + * + * Allows to pass connection handles around by value, similar to TQString + * thus avoiding problems like dangling pointers in application code + * + * @param other the connection to copy from + */ + TQT_DBusConnection(const TQT_DBusConnection &other); + + /** + * @brief Destroys the connection handle + * + * If this handle is the last one referencing the shared connection object + * it will delete it, disconnecting it from any objects it was + * collaborating with + */ + ~TQT_DBusConnection(); + + /** + * @brief Creates a shallow copy of the given connection + * + * Allows to pass connection handles around by value, similar to TQString + * thus avoiding problems like dangling pointers in application code + * + * @param other the connection to copy from + * + * @return a reference to this instance as required by assigment operator + * semantics + */ + TQT_DBusConnection &operator=(const TQT_DBusConnection &other); + + /** + * @brief Returns whether the connection is connected to a bus + * + * @return @c true if the connection can be used, @c false if the handle + * does not have access to a shared connection object or if the + * connection to the bus could not be established or broke + */ + bool isConnected() const; + + /** + * @brief Returns the last error seen by the connection + * + * This can be a connection error, e.g. attempt to connect failed, or a + * transmission error or an error reported by a method call + * + * @return the last error seen by the connection + */ + TQT_DBusError lastError() const; + + /** + * @brief Flags for controlling the behavior name collision handling + * + * @see requestName() + */ + enum NameRequestMode + { + /** + * Do not allow others to take over a name requested by this + * application + */ + NoReplace = 0, + + /** + * Allow other applications that request the same name to get it, + * i.e. allow the bus to transfer the name from this application + * to the one requesting it + */ + AllowReplace = 1, + + /** + * Try to get the name transferred from the current owner to this + * application. This will only work if the other application as + * requested the name using the AllowReplace flag + */ + ReplaceExisting = 2 + }; + + /** + * @brief Requests to be addressable on the bus by a given name + * + * Each connection to a bus gets a unique name once the connection is + * established. This is similar to getting an IP address when connecting + * to the Internet. + * + * If an application's purpose is to provide services to other applications + * the other applications require to know how to address the service + * provider. Similar to a domain name on the Internet D-Bus allows to + * register names on the bus and be addressed through those names instead + * of the connection identifier. + * + * @note this is not required if the application only needs to acccess + * services or only implements generic service APIs + * + * If more than one application request the same name, D-Bus will try + * to resolve this conflict as good as possible. + * The #NameRequestMode flags allow to control how an application prefers + * to be treated in such a conflict. + * + * @param name the name the connection should be addressable with. See + * section @ref dbusconventions-servicename + * @param modeFlags an OR'ed combination of #NameRequestMode flags + * + * @return @c true if the name request was successfull, @c false if + * the connection is not connected to a bus or the name is already + * taken and cannot be tranferred + * + * @see uniqueName() + */ + bool requestName(const TQString &name, int modeFlags = NoReplace); + + /** + * @brief Returns the connection identifier assigned at connect + * + * The unique name is the connection address or identifier the bus assigned + * to this connection when it got established. + * + * @return the connection's unique bus identifier + * + * @see requestName() + */ + TQString uniqueName() const; + + /** + * @brief Sends a message over the bus + * + * Sends a message composed through the TQT_DBusMessage API to the bus. + * This is the main method for service objects (see TQT_DBusObjectBase) to + * send replies and errors for method calls they accepted or for sending + * D-Bus signals. + * + * @note for doing method calls it is more convenient to use TQT_DBusProxy, + * see TQT_DBusProxy::send() + * + * @param message the message to send + * + * @return @c true if sending succeeded, @c false if the connection is not + * connected, if the message lacks information about the recepient + * or if sending fails a at a lower level in the communication + * stack + * + * @see lastError() + */ + bool send(const TQT_DBusMessage &message) const; + + /** + * @brief Sends a message over the bus and waits for the reply + * + * Sends a message composed through the TQT_DBusMessage API to the bus. + * It then blocks and waits until the associated reply is received. + * Any message received in between is stored and can be processed + * by calling dispatch() or scheduleDispatch() + * + * @note for doing method calls it is more convenient to use TQT_DBusProxy, + * see TQT_DBusProxy::sendWithReply() + * + * @param message the message to send + * @param error an optional parameter to directly get any error that might + * occur during processing of the call + * + * @return a message containing either the call's reply or an invalid + * message in case the call failed + * + * @see lastError() + */ + TQT_DBusMessage sendWithReply(const TQT_DBusMessage &message, TQT_DBusError *error = 0) const; + + /** + * @brief Sends a message over the bus, specifying a receiver object for + * replies + * + * Sends a message composed through the TQT_DBusMessage API to the bus and + * returns an identifier number to associate with the reply once it is + * received by the given receiver. + * See TQT_DBusMessage::replySerialNumber() + * + * The required slot signature is + * @code + * void slotname(const TQT_DBusMessage&); + * @endcode + * + * @note for doing method calls it is more convenient to use TQT_DBusProxy, + * see TQT_DBusProxy::sendWithAsyncReply() + * + * @param message the message to send + * @param receiver the TQObject to relay the reply to + * @param slot the slot to invoke for the reply + * + * @return a numeric identifier for association with the reply or @c 0 if + * sending failed + * + * @see lastError() + */ + int sendWithAsyncReply(const TQT_DBusMessage &message, TQObject *receiver, + const char *slot) const; + + /** + * @brief Flushes buffered outgoing message + * + * Attempts to send all enqueued outgoing messages before returning. + */ + void flush() const; + + /** + * @brief Processes buffered inbound messages + * + * Attempts to process all enqueued inbound messages, e.g. replies to + * method calls or received signals. + * + * @warning dispatching message can result in TQt signals being emitted + * before this method returns. In case you just want to make sure + * no inbound message is forgotten, call scheduleDispatch() which + * will execute the dispatch delayed through the event loop. + */ + void dispatch() const; + + /** + * @brief Request a delayed check for inbound buffer processing + * + * Similar to dispatch() but delayed by a single shot timer to ensure + * the method has returned before the processing is started. + * + * If a asynchronous method call is followed by a synchronous call without + * returning to the event loop in between, a call to scheduleDispatch() + * ensures that a pending reply to the asynchronous call is processed + * as soon as possible + */ + void scheduleDispatch() const; + + /** + * @brief Connects an object to receive D-Bus signals + * + * This provides a basic access to all D-Bus signals received on this + * connection. + * For every D-Bus signal processed by the connection object a TQt signal + * is emitted and thus delivered to all receiver objects connected + * through this method. + * + * The required slot signature is + * @code + * void slotname(const TQT_DBusMessage&); + * @endcode + * + * so a suitable receiver could look like this + * @code + * class DBusSignalReceiver : public TQObject + * { + * Q_OBJECT + * + * public slots: + * void dbusSignal(const TQT_DBusMessage&); + * }; + * @endcode + * + * and would be connected like this + * @code + * // assuming the following variables + * TQT_DBusConnection connection; + * DBusSignalReceiver* receiver; + * + * connection.connect(receiver, TQT_SLOT(dbusSignal(const TQT_DBusMessage&))); + * @endcode + * + * See TQT_DBusProxy::dbusSignal() for a more obvious way of connecting slots. + * + * @param object the receiver object + * @param slot the receiver slot (or signal for signal->signal connections) + * + * @return @c true if the connection was successfull, otherwise @c false + * + * @see disconnect() + */ + bool connect(TQObject* object, const char* slot); + + /** + * @brief Disconnects a given receiver from the D-Bus signal handling + * + * @param object the receiver object to disconnect from + * @param slot the receiver slot (or signal for signal->signal connections) + * + * @return @c true if the disconnect was successfull, otherwise @c false + * + * @see connect() + */ + bool disconnect(TQObject* object, const char* slot); + + /** + * @brief Registers a service object for a given path + * + * In order to receive method calls over the D-Bus connection the service + * objects path within its host application has to be registered with the + * connection. See section @ref dbusconventions-objectpath for details. + * + * Only one objects can be registered for a single object path, i.e. + * the path -> object mapping is unambiguous, similar to mapping of + * filesystem paths to files. + * + * If a service object offers more than one interface it is up to the + * service implementation if all are implemented in the object path to this + * method or if the passed object is just another demultiplexer which + * relays the message to the interface implementor. + * + * @param path the object path to register the object for + * @param object the service implementation object for that path + * + * @return @c true if the given object is now registered for the given path + * or @c false if path is empty, object is null or another object + * is already registered for this path + * + * @see unregisterObject() + */ + bool registerObject(const TQString& path, TQT_DBusObjectBase* object); + + /** + * @brief Unregister a service object on a given path + * + * Removes any mapping of object path to service object previously + * registered by registerObject(). + * See section @ref dbusconventions-objectpath for details. + * + * @warning always(!) unregister a service object before deleting it + * + * @param path the object path of the object to unregister + * + * @see registerObject() + */ + void unregisterObject(const TQString &path); + + /** + * @brief Gets a connection to the session bus + * + * Convenience overload for creating the default shared connection to the + * D-Bus session bus. + * + * Equivalent to calling addConnection(SessionBus); + * + * @return a connection handle. Check isConnected() to find out if the + * connection attempt has been successfull + * + * @see addConnection(BusType,const TQString&); + */ + static TQT_DBusConnection sessionBus(); + + /** + * @brief Gets a connection to the system bus + * + * Convenience overload for creating the default shared connection to the + * D-Bus system bus. + * + * Equivalent to calling addConnection(SystemBus); + * + * @return a connection handle. Check isConnected() to find out if the + * connection attempt has been successfull + * + * @see addConnection(BusType,const TQString&); + */ + static TQT_DBusConnection systemBus(); + + /** + * @brief Add a connection to a bus with a specific bus type + * + * This is a factory method as it will create a connection for the given + * name if its not available yet, but return a previously created + * connection for that name if available. + * + * Depending on the #BusType the D-Bus library will connect to the address + * configured for that type, so this is the recommended way to create + * connection to D-Bus. + * + * @code + * // Associate the default connection name with a connection to the user's + * // session bus + * TQT_DBusConnection con = TQT_DBusConnection::addConnection(TQT_DBusConnection::SessionBus); + * + * // check if we are connected and which uniqueName we got + * if (con.isConnected()) + * { + * tqDebug("Connected to session bus. We got uniqueName %s", + * con.uniqueName().local8Bit().data()); + * } + * @endcode + * For the common use cases see also sessionBus() and systemBus() + * + * @param type the #BusType of the bus to connect to + * @param name the name to use for TQT_DBusConnection's connection sharing + * + * @return a connection handle. Check isConnected() to find out if the + * connection attempt has been successfull + * + * @see closeConnection() + */ + static TQT_DBusConnection addConnection(BusType type, + const TQString &name = default_connection_name); + + /** + * @brief Add a connection to a bus at a specific address + * + * This is a factory method as it will create a connection for the given + * name if its not available yet, but return a previously created + * connection for that name if available. + * + * @note this requires to know the address of a D-Bus daemon to connect to + * + * @param address the address of the D-Bus daemon. Usually a Unix domain + * socket address + * @param name the name to use for TQT_DBusConnection's connection sharing + * + * @return a connection handle. Check isConnected() to find out if the + * connection attempt has been successfull + * + * @see closeConnection() + */ + static TQT_DBusConnection addConnection(const TQString &address, + const TQString &name = default_connection_name); + + // TODO check why this doesn't close the D-Bus connection + /** + * @brief Closes a connection with a given name + * + * Removes the name from the pool of shared connections, i.e. a call to + * addConnection() with the same name afterwards will create a new + * connection. + * + * @param name the connection name as used in addConnection() + */ + static void closeConnection(const TQString &name = default_connection_name); + + /** + * String used as the default parameter for connection names + */ + QT_STATIC_CONST char *default_connection_name; + +private: + TQT_DBusConnectionPrivate *d; +}; + +#endif diff --git a/src/tqdbusconnection_p.h b/src/tqdbusconnection_p.h new file mode 100644 index 0000000..6e4efd1 --- /dev/null +++ b/src/tqdbusconnection_p.h @@ -0,0 +1,177 @@ +/* qdbusconnection_p.h TQT_DBusConnection private object + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2005 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// + +#ifndef TQDBUSCONNECTION_P_H +#define TQDBUSCONNECTION_P_H + +#include +#include +#include +#include + +#include + +#include "tqdbusatomic.h" +#include "tqdbuserror.h" +#include "tqdbusobject.h" +#include "tqdbusmessage.h" + +class TQT_DBusMessage; +class TQSocketNotifier; +class TQTimer; +class TQTimerEvent; + +struct DBusConnection; +struct DBusServer; + +class TQT_DBusResultInfo +{ + public: + TQT_DBusMessage message; + TQObject* receiver; + TQCString method; +}; +typedef TQValueList TQT_DBusResultInfoList; + +class TQT_DBusConnectionPrivate: public TQObject +{ + Q_OBJECT + + +public: + TQT_DBusConnectionPrivate(TQObject *parent = 0); + ~TQT_DBusConnectionPrivate(); + + void bindToApplication(); + + void setConnection(DBusConnection *connection); + void setServer(DBusServer *server); + void closeConnection(); + void timerEvent(TQTimerEvent *e); + + bool handleSignal(DBusMessage *msg); + bool handleObjectCall(DBusMessage *message); + bool handleError(); + + void emitPendingCallReply(const TQT_DBusMessage& message); + +signals: + void dbusSignal(const TQT_DBusMessage& message); + + void dbusPendingCallReply(const TQT_DBusMessage& message); + +public slots: + void socketRead(int); + void socketWrite(int); + + void objectDestroyed(TQObject* object); + + void purgeRemovedWatches(); + + void scheduleDispatch(); + void dispatch(); + +public: + DBusError error; + TQT_DBusError lastError; + + enum ConnectionMode { InvalidMode, ServerMode, ClientMode }; + + // FIXME TQAtomic ref; + Atomic ref; + ConnectionMode mode; + DBusConnection *connection; + DBusServer *server; + + TQTimer* dispatcher; + + static int messageMetaType; + static int registerMessageMetaType(); + int sendWithReplyAsync(const TQT_DBusMessage &message, TQObject *receiver, + const char *method); + void flush(); + + struct Watcher + { + Watcher(): watch(0), read(0), write(0) {} + DBusWatch *watch; + TQSocketNotifier *read; + TQSocketNotifier *write; + }; + // FIXME typedef TQMultiHash WatcherHash; + typedef TQValueList WatcherList; + WatcherList removedWatches; + typedef TQMap WatcherHash; + WatcherHash watchers; + + // FIXME typedef TQHash TimeoutHash; + typedef TQMap TimeoutHash; + TimeoutHash timeouts; + + typedef TQMap ObjectMap; + ObjectMap registeredObjects; + + TQValueList pendingTimeouts; + + struct TQT_DBusPendingCall + { + TQGuardedPtr receiver; + TQCString method; + DBusPendingCall *pending; + }; + typedef TQMap PendingCallMap; + PendingCallMap pendingCalls; + + typedef TQValueList PendingMessagesForEmit; + PendingMessagesForEmit pendingMessages; + + bool inDispatch; + + TQT_DBusResultInfoList m_resultEmissionQueue; + +public: + void newMethodInResultEmissionQueue(); + +private slots: + void transmitResultEmissionQueue(); + void transmitMessageEmissionQueue(); + +private: + TQTimer* m_resultEmissionQueueTimer; + TQTimer* m_messageEmissionQueueTimer; +}; + +#endif diff --git a/src/tqdbusdata.cpp b/src/tqdbusdata.cpp new file mode 100644 index 0000000..629df57 --- /dev/null +++ b/src/tqdbusdata.cpp @@ -0,0 +1,1121 @@ +/* qdbusdata.cpp DBUS data transport type + * + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include "dbus/dbus.h" + +#include "tqdbusdata.h" +#include "tqdbusdatalist.h" +#include "tqdbusdatamap.h" +#include "tqdbusobjectpath.h" +#include "tqdbusunixfd.h" +#include "tqdbusvariant.h" + +#include +#include +#include + +class TQT_DBusData::Private : public TQShared +{ +public: + Private() : TQShared(), type(TQT_DBusData::Invalid), keyType(TQT_DBusData::Invalid) {} + + ~Private() + { + switch (type) + { + case TQT_DBusData::String: + delete (TQString*)value.pointer; + break; + + case TQT_DBusData::ObjectPath: + delete (TQT_DBusObjectPath*)value.pointer; + break; + + case TQT_DBusData::UnixFd: + delete (TQT_DBusUnixFd*)value.pointer; + break; + + case TQT_DBusData::List: + delete (TQT_DBusDataList*)value.pointer; + break; + + case TQT_DBusData::Struct: + delete (TQValueList*)value.pointer; + break; + + case TQT_DBusData::Variant: + delete (TQT_DBusVariant*)value.pointer; + break; + + case TQT_DBusData::Map: + switch (keyType) + { + case TQT_DBusData::Byte: + delete (TQT_DBusDataMap*)value.pointer; + break; + + case TQT_DBusData::Int16: + delete (TQT_DBusDataMap*)value.pointer; + break; + + case TQT_DBusData::UInt16: + delete (TQT_DBusDataMap*)value.pointer; + break; + + case TQT_DBusData::Int32: + delete (TQT_DBusDataMap*)value.pointer; + break; + + case TQT_DBusData::UInt32: + delete (TQT_DBusDataMap*)value.pointer; + break; + + case TQT_DBusData::Int64: + delete (TQT_DBusDataMap*)value.pointer; + break; + + case TQT_DBusData::UInt64: + delete (TQT_DBusDataMap*)value.pointer; + break; + + case TQT_DBusData::String: + delete (TQT_DBusDataMap*)value.pointer; + break; + + case TQT_DBusData::ObjectPath: + delete (TQT_DBusDataMap*)value.pointer; + break; + + case TQT_DBusData::UnixFd: + delete (TQT_DBusDataMap*)value.pointer; + break; + + default: + tqFatal("TQT_DBusData::Private: unhandled map key type %d(%s)", + keyType, TQT_DBusData::typeName(keyType)); + break; + } + break; + + default: + break; + } + } + +public: + Type type; + Type keyType; + + union + { + bool boolValue; + TQ_UINT8 byteValue; + TQ_INT16 int16Value; + TQ_UINT16 uint16Value; + TQ_INT32 int32Value; + TQ_UINT32 uint32Value; + TQ_INT64 int64Value; + TQ_UINT64 uint64Value; + double doubleValue; + void* pointer; + } value; +}; + +// key type definitions for TQT_DBusDataMap +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::Byte; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::Int16; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::UInt16; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::Int32; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::UInt32; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::Int64; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::UInt64; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::String; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::ObjectPath; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::UnixFd; + + +TQT_DBusData::TQT_DBusData() : d(new Private()) +{ +} + +TQT_DBusData::TQT_DBusData(const TQT_DBusData& other) : d(0) +{ + d = other.d; + + d->ref(); +} + +TQT_DBusData::~TQT_DBusData() +{ + if (d->deref()) delete d; +} + +TQT_DBusData& TQT_DBusData::operator=(const TQT_DBusData& other) +{ + if (&other == this) return *this; + + if (d->deref()) delete d; + + d = other.d; + + d->ref(); + + return *this; +} + +bool TQT_DBusData::operator==(const TQT_DBusData& other) const +{ + if (&other == this) return true; + + if (d == other.d) return true; + + if (d->type == other.d->type) + { + switch (d->type) + { + case TQT_DBusData::Invalid: + return true; + + case TQT_DBusData::Bool: + return d->value.boolValue == other.d->value.boolValue; + + case TQT_DBusData::Byte: + return d->value.byteValue == other.d->value.byteValue; + + case TQT_DBusData::Int16: + return d->value.int16Value == other.d->value.int16Value; + + case TQT_DBusData::UInt16: + return d->value.uint16Value == other.d->value.uint16Value; + + case TQT_DBusData::Int32: + return d->value.int32Value == other.d->value.int32Value; + + case TQT_DBusData::UInt32: + return d->value.uint32Value == other.d->value.uint64Value; + + case TQT_DBusData::Int64: + return d->value.int64Value == other.d->value.int64Value; + + case TQT_DBusData::UInt64: + return d->value.uint64Value == other.d->value.uint64Value; + + case TQT_DBusData::Double: + // FIXME: should not compare doubles for equality like this + return d->value.doubleValue == other.d->value.doubleValue; + + case TQT_DBusData::String: + return toString() == other.toString(); + + case TQT_DBusData::ObjectPath: + return toObjectPath() == other.toObjectPath(); + + case TQT_DBusData::UnixFd: + return toUnixFd() == other.toUnixFd(); + + case TQT_DBusData::List: + return toList() == other.toList(); + + case TQT_DBusData::Struct: + return toStruct() == other.toStruct(); + + case TQT_DBusData::Variant: + return toVariant() == other.toVariant(); + + case TQT_DBusData::Map: + if (d->keyType != other.d->keyType) return false; + + switch (d->keyType) + { + case TQT_DBusData::Byte: + return toByteKeyMap() == other.toByteKeyMap(); + + case TQT_DBusData::Int16: + return toInt16KeyMap() == other.toInt16KeyMap(); + + case TQT_DBusData::UInt16: + return toUInt16KeyMap() == other.toUInt16KeyMap(); + + case TQT_DBusData::Int32: + return toInt32KeyMap() == other.toInt32KeyMap(); + + case TQT_DBusData::UInt32: + return toUInt32KeyMap() == other.toUInt32KeyMap(); + + case TQT_DBusData::Int64: + return toInt64KeyMap() == other.toInt64KeyMap(); + + case TQT_DBusData::UInt64: + return toUInt64KeyMap() == other.toUInt64KeyMap(); + + case TQT_DBusData::String: + return toStringKeyMap() == other.toStringKeyMap(); + + case TQT_DBusData::ObjectPath: + return toObjectPathKeyMap() == other.toObjectPathKeyMap(); + + case TQT_DBusData::UnixFd: + return toUnixFdKeyMap() == other.toUnixFdKeyMap(); + + default: + tqFatal("TQT_DBusData operator== unhandled map key type %d(%s)", + d->keyType, TQT_DBusData::typeName(d->keyType)); + break; + } + + break; + } + } + + return false; +} + +bool TQT_DBusData::operator!=(const TQT_DBusData& other) const +{ + return !operator==(other); +} + +TQT_DBusData::Type TQT_DBusData::type() const +{ + return d->type; +} + +TQT_DBusData::Type TQT_DBusData::keyType() const +{ + if (d->type != TQT_DBusData::Map) return TQT_DBusData::Invalid; + + return d->keyType; +} + +const char* TQT_DBusData::typeName(Type type) +{ + switch (type) + { + case TQT_DBusData::Invalid: return "Invalid"; + case TQT_DBusData::Bool: return "Bool"; + case TQT_DBusData::Byte: return "Byte"; + case TQT_DBusData::Int16: return "Int16"; + case TQT_DBusData::UInt16: return "UInt16"; + case TQT_DBusData::Int32: return "Int32"; + case TQT_DBusData::UInt32: return "UInt32"; + case TQT_DBusData::Int64: return "Int64"; + case TQT_DBusData::UInt64: return "UInt64"; + case TQT_DBusData::Double: return "Double"; + case TQT_DBusData::String: return "String"; + case TQT_DBusData::ObjectPath: return "ObjectPath"; + case TQT_DBusData::UnixFd: return "UnixFd"; + case TQT_DBusData::List: return "List"; + case TQT_DBusData::Struct: return "Struct"; + case TQT_DBusData::Variant: return "Variant"; + case TQT_DBusData::Map: return "Map"; + } + + return 0; +} + +TQT_DBusData TQT_DBusData::fromBool(bool value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Bool; + data.d->value.boolValue = value; + + return data; +} + +bool TQT_DBusData::toBool(bool* ok) const +{ + if (d->type != TQT_DBusData::Bool) + { + if (ok != 0) *ok = false; + return false; + } + + if (ok != 0) *ok = true; + + return d->value.boolValue; +} + +TQT_DBusData TQT_DBusData::fromByte(TQ_UINT8 value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Byte; + data.d->value.byteValue = value; + + return data; +} + +TQ_UINT8 TQT_DBusData::toByte(bool* ok) const +{ + if (d->type != TQT_DBusData::Byte) + { + if (ok != 0) *ok = false; + return 0; + } + + if (ok != 0) *ok = true; + + return d->value.byteValue; +} + +TQT_DBusData TQT_DBusData::fromInt16(TQ_INT16 value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Int16; + data.d->value.int16Value = value; + + return data; +} + +TQ_INT16 TQT_DBusData::toInt16(bool* ok) const +{ + if (d->type != TQT_DBusData::Int16) + { + if (ok != 0) *ok = false; + return 0; + } + + if (ok != 0) *ok = true; + + return d->value.int16Value; +} + +TQT_DBusData TQT_DBusData::fromUInt16(TQ_UINT16 value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::UInt16; + data.d->value.uint16Value = value; + + return data; +} + +TQ_UINT16 TQT_DBusData::toUInt16(bool* ok) const +{ + if (d->type != TQT_DBusData::UInt16) + { + if (ok != 0) *ok = false; + return 0; + } + + if (ok != 0) *ok = true; + + return d->value.uint16Value; +} + +TQT_DBusData TQT_DBusData::fromInt32(TQ_INT32 value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Int32; + data.d->value.int32Value = value; + + return data; +} + +TQ_INT32 TQT_DBusData::toInt32(bool* ok) const +{ + if (d->type != TQT_DBusData::Int32) + { + if (ok != 0) *ok = false; + return 0; + } + + if (ok != 0) *ok = true; + + return d->value.int32Value; +} + +TQT_DBusData TQT_DBusData::fromUInt32(TQ_UINT32 value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::UInt32; + data.d->value.uint32Value = value; + + return data; +} + +TQ_UINT32 TQT_DBusData::toUInt32(bool* ok) const +{ + if (d->type != TQT_DBusData::UInt32) + { + if (ok != 0) *ok = false; + return 0; + } + + if (ok != 0) *ok = true; + + return d->value.uint32Value; +} + +TQT_DBusData TQT_DBusData::fromInt64(TQ_INT64 value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Int64; + data.d->value.int64Value = value; + + return data; +} + +TQ_INT64 TQT_DBusData::toInt64(bool* ok) const +{ + if (d->type != TQT_DBusData::Int64) + { + if (ok != 0) *ok = false; + return 0; + } + + if (ok != 0) *ok = true; + + return d->value.int64Value; +} + +TQT_DBusData TQT_DBusData::fromUInt64(TQ_UINT64 value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::UInt64; + data.d->value.uint64Value = value; + + return data; +} + +TQ_UINT64 TQT_DBusData::toUInt64(bool* ok) const +{ + if (d->type != TQT_DBusData::UInt64) + { + if (ok != 0) *ok = false; + return 0; + } + + if (ok != 0) *ok = true; + + return d->value.uint64Value; +} + +TQT_DBusData TQT_DBusData::fromDouble(double value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Double; + data.d->value.doubleValue = value; + + return data; +} + +double TQT_DBusData::toDouble(bool* ok) const +{ + if (d->type != TQT_DBusData::Double) + { + if (ok != 0) *ok = false; + return 0.0; + } + + if (ok != 0) *ok = true; + + return d->value.doubleValue; +} + +TQT_DBusData TQT_DBusData::fromString(const TQString& value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::String; + data.d->value.pointer = new TQString(value); + + return data; +} + +TQString TQT_DBusData::toString(bool* ok) const +{ + if (d->type != TQT_DBusData::String) + { + if (ok != 0) *ok = false; + return TQString(); + } + + if (ok != 0) *ok = true; + + return *((TQString*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromObjectPath(const TQT_DBusObjectPath& value) +{ + TQT_DBusData data; + + if (value.isValid()) + { + data.d->type = TQT_DBusData::ObjectPath; + data.d->value.pointer = new TQT_DBusObjectPath(value); + } + + return data; +} + +TQT_DBusObjectPath TQT_DBusData::toObjectPath(bool* ok) const +{ + if (d->type != TQT_DBusData::ObjectPath) + { + if (ok != 0) *ok = false; + return TQT_DBusObjectPath(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusObjectPath*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromUnixFd(const TQT_DBusUnixFd& value) +{ + TQT_DBusData data; + + if (value.isValid()) + { + data.d->type = TQT_DBusData::UnixFd; + data.d->value.pointer = new TQT_DBusUnixFd(value); + } + + return data; +} + +TQT_DBusUnixFd TQT_DBusData::toUnixFd(bool* ok) const +{ + if (d->type != TQT_DBusData::UnixFd) + { + if (ok != 0) *ok = false; + return TQT_DBusUnixFd(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusUnixFd*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromList(const TQT_DBusDataList& list) +{ + TQT_DBusData data; + + if (list.type() == TQT_DBusData::Invalid) return data; + + data.d->type = TQT_DBusData::List; + data.d->value.pointer = new TQT_DBusDataList(list); + + return data; +} + +TQT_DBusDataList TQT_DBusData::toList(bool* ok) const +{ + if (d->type != TQT_DBusData::List) + { + if (ok != 0) *ok = false; + return TQT_DBusDataList(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataList*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromTQValueList(const TQValueList& list) +{ + return fromList(TQT_DBusDataList(list)); +} + +TQValueList TQT_DBusData::toTQValueList(bool* ok) const +{ + bool internalOk = false; + TQT_DBusDataList list = toList(&internalOk); + + if (!internalOk) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + return list.toTQValueList(); +} + +TQT_DBusData TQT_DBusData::fromStruct(const TQValueList& memberList) +{ + TQT_DBusData data; + + TQValueList::const_iterator it = memberList.begin(); + TQValueList::const_iterator endIt = memberList.end(); + for (; it != endIt; ++it) + { + if ((*it).d->type == Invalid) return data; + } + + data.d->type = TQT_DBusData::Struct; + data.d->value.pointer = new TQValueList(memberList); + + return data; +} + +TQValueList TQT_DBusData::toStruct(bool* ok) const +{ + if (d->type != TQT_DBusData::Struct) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + if (ok != 0) *ok = true; + + return *((TQValueList*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromVariant(const TQT_DBusVariant& value) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Variant; + data.d->value.pointer = new TQT_DBusVariant(value); + + return data; +} + +TQT_DBusVariant TQT_DBusData::toVariant(bool* ok) const +{ + if (d->type != TQT_DBusData::Variant) + { + if (ok != 0) *ok = false; + return TQT_DBusVariant(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusVariant*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromByteKeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toByteKeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromInt16KeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toInt16KeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromUInt16KeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toUInt16KeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && + d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromInt32KeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toInt32KeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromUInt32KeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toUInt32KeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && + d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromInt64KeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toInt64KeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromUInt64KeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toUInt64KeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && + d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromStringKeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toStringKeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromObjectPathKeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toObjectPathKeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && + d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +TQT_DBusData TQT_DBusData::fromUnixFdKeyMap(const TQT_DBusDataMap& map) +{ + TQT_DBusData data; + + data.d->type = TQT_DBusData::Map; + data.d->keyType = map.keyType(); + data.d->value.pointer = new TQT_DBusDataMap(map); + + return data; +} + +TQT_DBusDataMap TQT_DBusData::toUnixFdKeyMap(bool* ok) const +{ + if (d->type != TQT_DBusData::Map && + d->keyType != TQT_DBusDataMap::m_keyType) + { + if (ok != 0) *ok = false; + return TQT_DBusDataMap(); + } + + if (ok != 0) *ok = true; + + return *((TQT_DBusDataMap*)d->value.pointer); +} + +static const char* qDBusTypeForTQT_DBusType(TQT_DBusData::Type type) +{ + switch (type) + { + case TQT_DBusData::Invalid: + return 0; + case TQT_DBusData::Bool: + return DBUS_TYPE_BOOLEAN_AS_STRING; + case TQT_DBusData::Byte: + return DBUS_TYPE_BYTE_AS_STRING; + case TQT_DBusData::Int16: + return DBUS_TYPE_INT16_AS_STRING; + case TQT_DBusData::UInt16: + return DBUS_TYPE_UINT16_AS_STRING; + case TQT_DBusData::Int32: + return DBUS_TYPE_INT32_AS_STRING; + case TQT_DBusData::UInt32: + return DBUS_TYPE_UINT32_AS_STRING; + case TQT_DBusData::Int64: + return DBUS_TYPE_INT64_AS_STRING; + case TQT_DBusData::UInt64: + return DBUS_TYPE_UINT64_AS_STRING; + case TQT_DBusData::Double: + return DBUS_TYPE_DOUBLE_AS_STRING; + case TQT_DBusData::String: + return DBUS_TYPE_STRING_AS_STRING; + case TQT_DBusData::ObjectPath: + return DBUS_TYPE_OBJECT_PATH_AS_STRING; + case TQT_DBusData::UnixFd: + return DBUS_TYPE_UNIX_FD_AS_STRING; + case TQT_DBusData::Variant: + return DBUS_TYPE_VARIANT_AS_STRING; + default: + break; + } + return 0; +} + +template +TQCString qDBusSignatureForMapValue(const TQT_DBusDataMap& map) +{ + if (map.hasContainerValueType()) + return map.containerValueType().buildDBusSignature(); + else + return qDBusTypeForTQT_DBusType(map.valueType()); +} + +TQCString TQT_DBusData::buildDBusSignature() const +{ + TQCString signature; + + switch (d->type) + { + case TQT_DBusData::List: + { + TQT_DBusDataList* list = (TQT_DBusDataList*) d->value.pointer; + signature = DBUS_TYPE_ARRAY_AS_STRING; + if (list->hasContainerItemType()) + signature += list->containerItemType().buildDBusSignature(); + else + signature += qDBusTypeForTQT_DBusType(list->type()); + break; + } + + case TQT_DBusData::Struct: + { + signature += DBUS_STRUCT_BEGIN_CHAR; + + TQValueList* memberList = + (TQValueList*) d->value.pointer; + + TQValueList::const_iterator it = (*memberList).begin(); + TQValueList::const_iterator endIt = (*memberList).end(); + for (; it != endIt; ++it) + { + signature += (*it).buildDBusSignature(); + } + signature += DBUS_STRUCT_END_CHAR; + break; + } + + case TQT_DBusData::Map: + signature += DBUS_TYPE_ARRAY_AS_STRING; + signature += DBUS_DICT_ENTRY_BEGIN_CHAR; + + signature += qDBusTypeForTQT_DBusType(keyType()); + + switch (keyType()) + { + case TQT_DBusData::Byte: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + case TQT_DBusData::Int16: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + case TQT_DBusData::UInt16: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + case TQT_DBusData::Int32: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + case TQT_DBusData::UInt32: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + case TQT_DBusData::Int64: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + case TQT_DBusData::UInt64: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + case TQT_DBusData::String: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + case TQT_DBusData::ObjectPath: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + case TQT_DBusData::UnixFd: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; + default: + break; + } + + signature += DBUS_DICT_ENTRY_END_CHAR; + break; + + default: + signature = qDBusTypeForTQT_DBusType(d->type); + break; + } + + return signature; +} diff --git a/src/tqdbusdata.h b/src/tqdbusdata.h new file mode 100644 index 0000000..ae64706 --- /dev/null +++ b/src/tqdbusdata.h @@ -0,0 +1,1223 @@ +/* qdbusdata.h DBUS data transport type + * + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSDATA_H +#define TQDBUSDATA_H + +#include "tqdbusmacros.h" +#include + +class TQCString; +class TQT_DBusDataList; +class TQT_DBusVariant; +class TQT_DBusObjectPath; +class TQT_DBusUnixFd; +class TQString; + +template class TQValueList; +template class TQT_DBusDataMap; + +/** + * @brief Class for accurately representing D-Bus data types + * + * The TQT_DBusData class can be compared to TQt's TQVariant class, but + * specialized to contain data types used in D-Bus messages. + * + * Like TQVariant objects of TQT_DBusData use implicit sharing, i.e. copying + * a TQT_DBusData object is a cheap operation and does not require that the + * content itself is copied. + * + * Depending on the #Type of the object, the content can be a recursive + * construct of TQT_DBusData objects, e.g. a #List can contain elements that are + * containers themselves, e.g. #Map, #Struct, #Variant or even #List again. + * + * @see TQT_DBusDataList + * @see TQT_DBusDataMap + * @see TQT_DBusDataConverter + */ +class TQDBUS_EXPORT TQT_DBusData +{ +public: + /** + * @brief Enum for the data types used in D-Bus messages + * + * In order to provide correct mapping of C++ and TQt types and the data + * types used in D-Bus messages, TQT_DBusData uses explicit naming of types + * where the name is usually the one used in D-Bus, with the exception of + * #List and #Map since this is closer to the TQt container they are + * implemented with (TQValueList and TQMap respectively) + * + * @see type(), keyType() + * @see typeName() + */ + enum Type + { + /** + * Base type for TQT_DBusData objects created by the default constructor. + * + * Also used as the type of returned objects when getter type methods + * fail due to type incompatabilties, i.e. toInt32() called on a #List + * object. + * + * @see isValid() + */ + Invalid = 0, + + /** + * Type when encapsulating a boolean value. + * + * @see fromBool(), toBool() + */ + Bool, + + /** + * Type when encapsulating a byte (unsigned char) value. + * + * @see fromByte(), toByte() + */ + Byte, + + /** + * Type when encapsulating a signed 16-bit integer value. + * + * @see fromInt16(), toInt16() + */ + Int16, + + /** + * Type when encapsulating an unsigned 16-bit integer value. + * + * @see fromUInt16(), toUInt16() + */ + UInt16, + + /** + * Type when encapsulating a signed 32-bit integer value. + * + * @see fromInt32(), toInt32() + */ + Int32, + + /** + * Type when encapsulating an unsigned 32-bit integer value. + * + * @see fromUInt32(), toUInt32() + */ + UInt32, + + /** + * Type when encapsulating a signed 64-bit integer value. + * + * @see fromInt64(), toInt64() + */ + Int64, + + /** + * Type when encapsulating an unsigned 64-bit integer value. + * + * @see fromUInt64(), toUInt64() + */ + UInt64, + + /** + * Type when encapsulating a double value. + * + * @see fromDouble(), toDouble() + */ + Double, + + /** + * Type when encapsulating a string value. + * + * All strings are converted to UTF-8 during transmission + * + * @see fromString(), toString() + */ + String, + + /** + * Type when encapsulating a D-Bus object path. + * + * D-Bus defines a special string variation for transporting the + * paths used to address objects within D-Bus services, see + * @ref dbusconventions-objectpath for formatting details. + * + * @note from the point of view of this bindings an object path is + * pretty much a normal string with externally checked restrictions. + * However, method calls or return values can require a signature + * to include an object path and any remote peer might then reject + * the normal string signature. + * + * @see fromObjectPath(), toObjectPath() + */ + ObjectPath, + + /** + * Type when encapsulating a D-Bus unix file handle. + * + * @see fromUnixFd(), toUnixFd() + */ + UnixFd, + + /** + * Type when encapsulating a list of values. + * + * The D-Bus type this maps to is called @c array but since the TQt + * container class used to implement this type is TQValueList (or rather + * TQT_DBusDataList), the TQT_DBusData type is called @c List instead. + * + * A list can contain any of the supported types as elements, even + * container types. + * However it can only contain elements with the same type per list + * object. + * + * @see fromList(), toList() + */ + List, + + /** + * Type when encapsulating a struct of values. + * + * A struct is basically a list of struct member variables, each + * member can be any of the supported types, even containers types. + * + * The C++/TQt value type used in the converter methods is a TQValueList + * with type TQT_DBusData. + * For example a TQRect could be mapped like this: + * @code + * TQRect rect(0, 0, 640, 480); + * TQValueList memberList; + * + * memberList << TQT_DBusData::fromInt32(rect.x()); + * memberList << TQT_DBusData::fromInt32(rect.y()); + * memberList << TQT_DBusData::fromInt32(rect.width()); + * memberList << TQT_DBusData::fromInt32(rect.height()); + * + * TQT_DBusData data = TQT_DBusData:fromStruct(memberList); + * @endcode + * + * And reconstructed like this: + * @code + * memberList = data.toStruct(); + * + * int x = memberList[0].toInt32(); + * int y = memberList[1].toInt32(); + * int w = memberList[2].toInt32(); + * int h = memberList[3].toInt32(); + * + * rect = TQRect(x, y, w, h); + * @endcode + * + * @note Empty structs, i.e. an empty member list, are not allowed + * + * @see fromStruct(), toStruct() + * @see TQT_DBusDataConverter + */ + Struct, + + /** + * Type when encapsulating a special variable container value. + * + * See TQT_DBusVariant for details on variant usage. + * + * @see fromVariant(), toVariant() + */ + Variant, + + /** + * Type when encapsulating a map of keys to values. + * + * The D-Bus type this maps to is called @c dict but since the TQt + * container class used to implement this type is TQMap (or rather + * TQT_DBusDataMap), the TQT_DBusData type is called @c Map instead. + * + * A map can contain any of the supported types as values, even + * container types, but only the following basic types as keys: + * - #Byte + * - #Int16 + * - #UInt16 + * - #Int32 + * - #UInt32 + * - #Int64 + * - #UInt64 + * - #String + * - #ObjectPath + * - #UnixFd + * + * All values need to be of the same type. + * + * @see fromByteKeyMap(), toByteKeyMap() + * @see fromInt16KeyMap(), toInt16KeyMap() + * @see fromUInt16KeyMap(), toUInt16KeyMap() + * @see fromInt32KeyMap(), toInt32KeyMap() + * @see fromUInt32KeyMap(), toUInt32KeyMap() + * @see fromInt64KeyMap(), toInt64KeyMap() + * @see fromUInt64KeyMap(), toUInt64KeyMap() + * @see fromStringKeyMap(), toStringKeyMap() + * @see fromObjectPathKeyMap(), toObjectPathKeyMap() + * @see fromUnixFdKeyMap(), toUnixFdKeyMap() + */ + Map + }; + + /** + * @brief Creates an empty, #Invalid data object + */ + TQT_DBusData(); + + /** + * @brief Copies a given @p other data object + * + * Since TQT_DBusData is implicitly shared, both objects will have the + * same content and the last object to reference it will delete it. + * + * @param other the object to copy + */ + TQT_DBusData(const TQT_DBusData& other); + + /** + * @brief Destroys the data object + * + * If this is the last instance to a shared content, it will delete it + * as well. + */ + ~TQT_DBusData(); + + /** + * @brief Copies a given @p other data object + * + * Since TQT_DBusData is implicitly shared, both objects will have the + * same content and the last object to reference it will delete it. + * + * @param other the object to copy + * + * @return a reference to this instance + */ + TQT_DBusData& operator=(const TQT_DBusData& other); + + /** + * @brief Checks if the given @p other data object is equal to this instance + * + * Two TQT_DBusData object are considered equal if they reference the same + * shared content or have the same type and the content's equality operator + * says the contents are equal. + * + * @param other the object to compare with + * + * @return @c true if the two data objects are equal, otherwise @c false + */ + bool operator==(const TQT_DBusData& other) const; + + /** + * @brief Checks if the given @p other data object is different from this instance + * + * @param other the object to compare with + * + * @return @c false if the two data objects are not equal, otherwise @c false + * + * @see operator==() + */ + bool operator!=(const TQT_DBusData& other) const; + + /** + * @brief Checks whether the data object contains a valid content + * + * This is equal to checking type() for not being #Invalid + * + * @return @c true if the data object is valid, otherwise @c false + */ + inline bool isValid() const { return type() != TQT_DBusData::Invalid; } + + /** + * @brief Returns the #Type of the data object + * + * @return one of the values of the #Type enum + * + * @see keyType() + * @see typeName() + */ + Type type() const; + + /** + * @brief Returns the #Type of the key type for maps + * + * If the type of the data object is #Map, this method returns the type + * of the map's key, #String for a TQT_DBusDataMap + * + * If the type of the data object is not #Map, it will return #Invalid + * + * @return one of the values of the #Type enum, #Invalid if the object is + * not holding a #Map + * + * @see type() + * @see typeName() + */ + Type keyType() const; + + /** + * @brief Returns the string representation of the object's #Type + * + * @return an ASCII C-string for the object's type + * + * @see type() + * @see typeName(Type) + */ + inline const char* typeName() const { return typeName(type()); } + + /** + * @brief Returns the string representation for the given @p type + * + * @param type the #Type to get the string representation for + * + * @return an ASCII C-string for the given @p type + * + * @see type() + * @see typeName() + */ + static const char* typeName(Type type); + + /** + * @brief Creates a data object for the given boolean @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #Bool containing the @p value + * + * @see toBool() + */ + static TQT_DBusData fromBool(bool value); + + /** + * @brief Tries to get the encapsulated boolean value + * + * If the data object is not of type #Bool this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Bool) + * + * @return the encapsulated boolean value or @c false if it fails + * + * @see fromBool() + */ + bool toBool(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given byte (unsigned char) @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #Byte containing the @p value + * + * @see toByte() + */ + static TQT_DBusData fromByte(TQ_UINT8 value); + + /** + * @brief Tries to get the encapsulated byte (unsigned char) value + * + * If the data object is not of type #Byte this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Byte) + * + * @return the encapsulated byte (unsigned char) value or @c 0 if it fails + * + * @see fromByte() + */ + TQ_UINT8 toByte(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given signed 16-bit integer @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #Int16 containing the @p value + * + * @see toInt16() + */ + static TQT_DBusData fromInt16(TQ_INT16 value); + + /** + * @brief Tries to get the encapsulated signed 16-bit integer value + * + * If the data object is not of type #Int16 this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Int16) + * + * @return the encapsulated signed 16-bit integer value or @c 0 if it fails + * + * @see fromInt16() + */ + TQ_INT16 toInt16(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given unsigned 16-bit integer @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #UInt16 containing the @p value + * + * @see toUInt16() + */ + static TQT_DBusData fromUInt16(TQ_UINT16 value); + + /** + * @brief Tries to get the encapsulated unsigned 16-bit integer value + * + * If the data object is not of type #UInt16 this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #UInt16) + * + * @return the encapsulated unsigned 16-bit integer value or @c 0 if it fails + * + * @see fromUInt16() + */ + TQ_UINT16 toUInt16(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given signed 32-bit integer @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #Int32 containing the @p value + * + * @see toInt32() + */ + static TQT_DBusData fromInt32(TQ_INT32 value); + + /** + * @brief Tries to get the encapsulated signed 32-bit integer value + * + * If the data object is not of type #Int32 this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Int32) + * + * @return the encapsulated signed 32-bit integer value or @c 0 if it fails + * + * @see fromInt32() + */ + TQ_INT32 toInt32(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given unsigned 32-bit integer @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #UInt32 containing the @p value + * + * @see toUInt32() + */ + static TQT_DBusData fromUInt32(TQ_UINT32 value); + + /** + * @brief Tries to get the encapsulated unsigned 32-bit integer value + * + * If the data object is not of type #UInt32 this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #UInt32) + * + * @return the encapsulated unsigned 32-bit integer value or @c 0 if it fails + * + * @see fromUInt32() + */ + TQ_UINT32 toUInt32(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given signed 64-bit integer @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #Int64 containing the @p value + * + * @see toInt64() + */ + static TQT_DBusData fromInt64(TQ_INT64 value); + + /** + * @brief Tries to get the encapsulated signed 64-bit integer value + * + * If the data object is not of type #Int64 this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Int64) + * + * @return the encapsulated signed 64-bit integer value or @c 0 if it fails + * + * @see fromInt64() + */ + TQ_INT64 toInt64(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given unsigned 64-bit integer @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #UInt64 containing the @p value + * + * @see toUInt64() + */ + static TQT_DBusData fromUInt64(TQ_UINT64 value); + + /** + * @brief Tries to get the encapsulated unsigned 64-bit integer value + * + * If the data object is not of type #UInt64 this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #UInt64) + * + * @return the encapsulated unsigned 64-bit integer value or @c 0 if it fails + * + * @see fromUInt64() + */ + TQ_UINT64 toUInt64(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given double @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #Double containing the @p value + * + * @see toDouble() + */ + static TQT_DBusData fromDouble(double value); + + /** + * @brief Tries to get the encapsulated double value + * + * If the data object is not of type #Double this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Double) + * + * @return the encapsulated double value or @c 0.0 if it fails + * + * @see fromDouble() + */ + double toDouble(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given string @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #String containing the @p value + * + * @see toString() + */ + static TQT_DBusData fromString(const TQString& value); + + /** + * @brief Tries to get the encapsulated string value + * + * If the data object is not of type #String this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #String) + * + * @return the encapsulated string value or @c TQString() if it fails + * + * @see fromString() + */ + TQString toString(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given object path @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #ObjectPath containing the @p value + * + * @see toObjectPath() + */ + static TQT_DBusData fromObjectPath(const TQT_DBusObjectPath& value); + + /** + * @brief Tries to get the encapsulated object path value + * + * If the data object is not of type #ObjectPath this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #ObjectPath) + * + * @return the encapsulated object path value or an empty and invalid object + * if it fails + * + * @see fromObjectPath() + */ + TQT_DBusObjectPath toObjectPath(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given unix file handle @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #UnixFd containing the @p value + * + * @see toUnixFd() + */ + static TQT_DBusData fromUnixFd(const TQT_DBusUnixFd& value); + + /** + * @brief Tries to get the encapsulated unix file handle value + * + * If the data object is not of type #UnixFd this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #UnixFd) + * + * @return the encapsulated object path value or an empty and invalid object + * if it fails + * + * @see fromUnixFd() + */ + TQT_DBusUnixFd toUnixFd(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p list + * + * \note The list is allowed to be empty but is required to have a valid type + * + * Unless the list the is empty, the convenience method fromTQValueList() will + * usually be easier to use since it does not require to create a + * TQT_DBusDataList first. For empty lists this method has to be used to + * make sure there is sufficient type information on the list's elements + * available for the binding's marshalling code. + * + * @param list the list to encapsulate + * + * @return a data object of type #List containing the @p list or + * an #Invalid object if the list's type is #Invalid + * + * @see toList() + */ + static TQT_DBusData fromList(const TQT_DBusDataList& list); + + /** + * @brief Tries to get the encapsulated list + * + * If the data object is not of type #List this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #List) + * + * @return the encapsulated list or an empty and #Invalid list if it fails + * + * @see fromList() + */ + TQT_DBusDataList toList(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p list + * + * @warning All elements of the list have to be of the same #Type + * + * Convenience overload for fromList(), usually more straight forward to use + * because it doesn't require to create a TQT_DBusDataList object first, + * however it can only handle lists which contain elements, for empty lists + * fromList() is the only option. + * + * @param list the list to encapsulate + * + * @return a data object of type #List containing the @p list or + * an #Invalid object if the list is empty or if elements have + * different types. + * + * @see toTQValueList() + */ + static TQT_DBusData fromTQValueList(const TQValueList& list); + + /** + * @brief Tries to get the encapsulated list + * + * Convenience overload for toList(). + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #List) + * + * @return the encapsulated list or an empty and #Invalid list if it fails + * + * @see fromTQValueList() + */ + TQValueList toTQValueList(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given struct's @p memberList + * + * See the documentation of #Struct for an example. + * + * @param memberList the list of already encapsulated struct members + * + * @return a data object of type #Struct containing the @p memberList + * + * @see toStruct() + */ + static TQT_DBusData fromStruct(const TQValueList& memberList); + + /** + * @brief Tries to get the encapsulated struct memberList + * + * If the data object is not of type #Struct this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * See the documentation of #Struct for an example. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Struct) + * + * @return the encapsulated memberList or an empty list if it fails + * + * @see fromStruct() + */ + TQValueList toStruct(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given variant @p value + * + * @param value the value to encapsulate + * + * @return a data object of type #Variant containing the @p value + * + * @see toVariant() + */ + static TQT_DBusData fromVariant(const TQT_DBusVariant& value); + + /** + * @brief Tries to get the encapsulated variant value + * + * If the data object is not of type #Variant this will fail, i.e. + * the parameter @p ok will be set to @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Variant) + * + * @return the encapsulated variant value or an empty variant if it fails + * + * @see fromVariant() + */ + TQT_DBusVariant toVariant(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #Byte. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toByteKeyMap() + */ + static TQT_DBusData fromByteKeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not #Byte + * this will fail, i.e. the parameter @p ok will be set to @c false if + * present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #Byte) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromByteKeyMap() + */ + TQT_DBusDataMap toByteKeyMap(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #Int16. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toInt16KeyMap() + */ + static TQT_DBusData fromInt16KeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not #Int16 + * this will fail, i.e. the parameter @p ok will be set to @c false if + * present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #Int16) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromInt16KeyMap() + */ + TQT_DBusDataMap toInt16KeyMap(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #UInt16. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toUInt16KeyMap() + */ + static TQT_DBusData fromUInt16KeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not #UInt16 + * this will fail, i.e. the parameter @p ok will be set to @c false if + * present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #UInt16) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromUInt16KeyMap() + */ + TQT_DBusDataMap toUInt16KeyMap(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #Int32. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toInt32KeyMap() + */ + static TQT_DBusData fromInt32KeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not #Int32 + * this will fail, i.e. the parameter @p ok will be set to @c false if + * present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #Int32) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromInt32KeyMap() + */ + TQT_DBusDataMap toInt32KeyMap(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #UInt32. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toUInt32KeyMap() + */ + static TQT_DBusData fromUInt32KeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not #UInt32 + * this will fail, i.e. the parameter @p ok will be set to @c false if + * present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #UInt32) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromUInt32KeyMap() + */ + TQT_DBusDataMap toUInt32KeyMap(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #Int64. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toInt64KeyMap() + */ + static TQT_DBusData fromInt64KeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not #Int64 + * this will fail, i.e. the parameter @p ok will be set to @c false if + * present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #Int64) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromInt64KeyMap() + */ + TQT_DBusDataMap toInt64KeyMap(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #UInt64. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toUInt64KeyMap() + */ + static TQT_DBusData fromUInt64KeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not #UInt64 + * this will fail, i.e. the parameter @p ok will be set to @c false if + * present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #UInt64) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromUInt64KeyMap() + */ + TQT_DBusDataMap toUInt64KeyMap(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #String. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toStringKeyMap() + */ + static TQT_DBusData fromStringKeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not #String + * this will fail, i.e. the parameter @p ok will be set to @c false if + * present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #String) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromStringKeyMap() + */ + TQT_DBusDataMap toStringKeyMap(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #ObjectPath. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toObjectPathKeyMap() + */ + static TQT_DBusData fromObjectPathKeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not + * #ObjectPath this will fail, i.e. the parameter @p ok will be set to + * @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #ObjectPath) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromObjectPathKeyMap() + */ + TQT_DBusDataMap toObjectPathKeyMap(bool* ok = 0) const; + + /** + * @brief Creates a data object for the given @p map + * + * \note The map is allowed to be empty but is required to have a valid + * value type + * + * The resulting data object will have the keyType() set to #UnixFd. + * + * @param map the map to encapsulate + * + * @return a data object of type #Map containing the @p map or + * an #Invalid object if the map's value type is #Invalid + * + * @see toUnixFdhKeyMap() + */ + static TQT_DBusData fromUnixFdKeyMap(const TQT_DBusDataMap& map); + + /** + * @brief Tries to get the encapsulated map + * + * If the data object is not of type #Map or if its value type is not + * #UnixFd this will fail, i.e. the parameter @p ok will be set to + * @c false if present. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type #Map or + * value type not #UnixFd) + * + * @return the encapsulated map or an empty and #Invalid map if it fails + * + * @see fromUnixFdKeyMap() + */ + TQT_DBusDataMap toUnixFdKeyMap(bool* ok = 0) const; + + /** + * @brief Creates the data objects D-Bus signature + * + * Recursivly builds the D-Bus signature of the data object if it holds a + * container type, i.e. if the object is of type #List, #Map or #Struct + * + * This can be used to create a signature for TQT_DBusVariant when creating one + * for sending over D-Bus. + * + * @return a string containing the content's signature, or a null string + * if the data object is #Invalid + */ + TQCString buildDBusSignature() const; + +private: + class Private; + Private* d; +}; + +#endif diff --git a/src/tqdbusdataconverter.cpp b/src/tqdbusdataconverter.cpp new file mode 100644 index 0000000..50575b8 --- /dev/null +++ b/src/tqdbusdataconverter.cpp @@ -0,0 +1,143 @@ +/* qdbusdataconverter.cpp TQT_DBusDataConverter template + * + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include "tqdbusdataconverter.h" +#include "tqdbusdata.h" + +#include +#include +#include +#include + +template <> +TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertFromTQT_DBusData(const TQT_DBusData& dbusData, TQRect& typeData) +{ + if (dbusData.type() != TQT_DBusData::Struct) return InvalidSignature; + + TQValueList members = dbusData.toStruct(); + if (members.count() != 4) return InvalidSignature; + + TQ_INT32 values[4]; + + TQValueList::const_iterator it = members.begin(); + TQValueList::const_iterator endIt = members.end(); + for (uint i = 0; it != endIt; ++it, ++i) + { + bool ok = false; + values[i] = (*it).toInt32(&ok); + if (!ok) return InvalidSignature; + } + + typeData = TQRect(values[0], values[1], values[2], values[3]); + + return Success; +} + +template <> +TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertToTQT_DBusData(const TQRect& typeData, TQT_DBusData& dbusData) +{ + TQValueList members; + + members << TQT_DBusData::fromInt32(typeData.x()); + members << TQT_DBusData::fromInt32(typeData.y()); + members << TQT_DBusData::fromInt32(typeData.width()); + members << TQT_DBusData::fromInt32(typeData.height()); + + dbusData = TQT_DBusData::fromStruct(members); + + return Success; +} + +template <> +TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertFromTQT_DBusData(const TQT_DBusData& dbusData, TQPoint& typeData) +{ + if (dbusData.type() != TQT_DBusData::Struct) return InvalidSignature; + + TQValueList members = dbusData.toStruct(); + if (members.count() != 2) return InvalidSignature; + + TQ_INT32 values[2]; + + TQValueList::const_iterator it = members.begin(); + TQValueList::const_iterator endIt = members.end(); + for (uint i = 0; it != endIt; ++it, ++i) + { + bool ok = false; + values[i] = (*it).toInt32(&ok); + if (!ok) return InvalidSignature; + } + + typeData = TQPoint(values[0], values[1]); + + return Success; +} + +template <> +TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertToTQT_DBusData(const TQPoint& typeData, TQT_DBusData& dbusData) +{ + TQValueList members; + + members << TQT_DBusData::fromInt32(typeData.x()); + members << TQT_DBusData::fromInt32(typeData.y()); + + dbusData = TQT_DBusData::fromStruct(members); + + return Success; +} + +template <> +TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertFromTQT_DBusData(const TQT_DBusData& dbusData, TQSize& typeData) +{ + if (dbusData.type() != TQT_DBusData::Struct) return InvalidSignature; + + TQValueList members = dbusData.toStruct(); + if (members.count() != 2) return InvalidSignature; + + TQ_INT32 values[2]; + + TQValueList::const_iterator it = members.begin(); + TQValueList::const_iterator endIt = members.end(); + for (uint i = 0; it != endIt; ++it, ++i) + { + bool ok = false; + values[i] = (*it).toInt32(&ok); + if (!ok) return InvalidSignature; + } + + typeData = TQSize(values[0], values[1]); + + return Success; +} + +template <> +TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertToTQT_DBusData(const TQSize& typeData, TQT_DBusData& dbusData) +{ + TQValueList members; + + members << TQT_DBusData::fromInt32(typeData.width()); + members << TQT_DBusData::fromInt32(typeData.height()); + + dbusData = TQT_DBusData::fromStruct(members); + + return Success; +} diff --git a/src/tqdbusdataconverter.h b/src/tqdbusdataconverter.h new file mode 100644 index 0000000..2ca21a0 --- /dev/null +++ b/src/tqdbusdataconverter.h @@ -0,0 +1,207 @@ +/* qdbusdataconverter.h TQT_DBusDataConverter template + * + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSDATACONVERTER_H +#define TQDBUSDATACONVERTER_H + +#include "tqdbusmacros.h" + +class TQT_DBusData; + +/** + * @brief Template based converter for getting complex data into or from TQT_DBusData objects + * + * Any data to transport over D-Bus, i.e. method/signal paramaters or properties, need + * to be converted into a TQT_DBusData instance. + * + * For complex types, e.g. structures or nested containers, this can be quite some code, + * and will likely be needed for more than one call. + * Therefore it is more convenient to implement the conversions once per complex type. + * + * Example: sending and recieving a TQRect over D-Bus. + * In D-Bus terminology a TQRect is a struct of four 32-bit signed integers. The code to do + * this manually looks like this: + * @code + * TQRect rect(0, 0, 100, 100); + * + * TQValueList structMembers; + * structMembers << TQT_DBusData::fromInt32(rect.x()); + * structMembers << TQT_DBusData::fromInt32(rect.y()); + * structMembers << TQT_DBusData::fromInt32(rect.wdth()); + * structMembers << TQT_DBusData::fromInt32(rect.height()); + * + * TQT_DBusData rectStruct = TQT_DBusData::fromStruct(structMembers); + * @endcode + * and reverse (without the error checking) + * @code + * TQT_DBusData dbusData; // assume we got this from a D-Bus call + * + * TQValueList structMembers = dbudData.toStruct(); + * + * int x = structMembers[0].toInt32(); + * int y = structMembers[1].toInt32(); + * int w = structMembers[2].toInt32(); + * int h = structMembers[3].toInt32(); + * + * TQRect rect(x, y, w, h); + * @endcode + * + * Rather than implementing it in the method which performs the D-Bus call, basically the same + * code can be used as a spezialisation of the TQT_DBusDataConverter methods and then used like this: + * @code + * TQRect rect(0, 0, 100, 100); + * TQT_DBusData rectStruct; + * + * TQT_DBusDataConverter::convertToTQT_DBusData(rect, rectStruct); + * @endcode + * and + * @code + * TQRect rect; + * TQT_DBusData dbusData; // assume we got this from a D-Bus call + * + * TQT_DBusDataConverter::convertFromTQT_DBusData(dbusData, rect); + * @endcode + * + * @note The bindings library contains the spezialisations for TQRect, TQPoint and TQSize. + */ +class TQDBUS_EXPORT TQT_DBusDataConverter +{ +public: + /** + * @brief Conversion result values + */ + enum Result + { + /** + * Conversion successfull + */ + Success, + + /** + * Conversion failed because the passed TQT_DBusData instance does not contain data + * of the needed signature, e.g. too few to too many members for a struct or wrong types. + * + * @see TQT_DBusError::stdInvalidSignature() + */ + InvalidSignature, + + /** + * Conversion failed because the passed TQT_DBusData contained values which are not allowed, + * e.g. out of range for a numerical type used a an enum or flags. + * + * @see TQT_DBusError::stdInvalidArgs() + */ + InvalidArgument + }; + + /** + * @brief Conversion from a filled TQT_DBusData instance to a native type + * + * For example the implementation for TQPoint looks like this: + * @code + * template <> + * TQT_DBusDataConverter::Result + * TQT_DBusDataConverter::convertFromTQT_DBusData(const TQT_DBusData& dbusData, TQPoint& typeData) + * { + * if (dbusData.type() != TQT_DBusData::Struct) return InvalidSignature; + * + * TQValueList members = dbusData.toStruct(); + * if (members.count() != 2) return InvalidSignature; + * + * bool ok = false; + * int x = members[0].toInt32(&ok); + * if (!ok) return InvalidSignature; + * + * int y = members[1].toInt32(&ok); + * if (!ok) return InvalidSignature; + * + * typeData = TQPoint(x, y); + * + * return Success; + * } + * @endcode + * + * And then can be used like this: + * @code + * TQT_DBusMessage reply; // assume we got this as a D-Bus call reply + * TQPoint point; + * + * if (TQT_DBusDataConverter::convertFromTQT_DBusData(reply[0], point) != TQT_DBusDataConverter::Success) + * { + * // error handling + * } + * @endcode + * + * @param dbusData the binding's data instance to get the content from + * @param typeData the native type instance to put the content into + * + * @return the conversion result value + */ + template + static Result convertFromTQT_DBusData(const TQT_DBusData& dbusData, T& typeData); + + /** + * @brief Conversion from a native type to a TQT_DBusData instance + * + * For example the implementation for TQPoint looks like this: + * @code + * template <> + * TQT_DBusDataConversion::Result + * TQT_DBusDataConversion::convertToTQT_DBusData(const TQPoint& typeData, TQT_DBusData& dbusData) + * { + * TQValueList members; + * members << TQT_DBusData::fromInt32(typeData.x()); + * members << TQT_DBusData::fromInt32(typeData.y()); + * + * dbusData = TQT_DBusData::fromStruct(members); + * + * return Success; + * } + * @endcode + * + * And then can be used like this: + * @code + * TQPoint point(-10, 100); + * TQT_DBusMessage methodCall; // assume created by TQBusMessage::methodCall() + * + * TQT_DBusData dbusData; + * if (TQT_DBusDataConverter::convertToTQT_DBusData(point, dbusData) != TQT_DBusDataConverter::Success) + * { + * // error handling + * } + * else + * { + * methodCall << dbusData; + * } + * @endcode + * + * @param typeData the native type instance to get the content from + * @param dbusData the binding's data instance to put the content into + * + * @return the conversion result value + */ + template + static Result convertToTQT_DBusData(const T& typeData, TQT_DBusData& dbusData); +}; + +#endif diff --git a/src/tqdbusdatalist.cpp b/src/tqdbusdatalist.cpp new file mode 100644 index 0000000..23f60a5 --- /dev/null +++ b/src/tqdbusdatalist.cpp @@ -0,0 +1,786 @@ +/* qdbusdatalist.cpp list of DBUS data transport type + * + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include "tqdbusdatalist.h" +#include "tqdbusobjectpath.h" +#include "tqdbusunixfd.h" +#include "tqdbusvariant.h" + +#include + +class TQT_DBusDataList::Private +{ +public: + Private() : type(TQT_DBusData::Invalid) {} + +public: + TQT_DBusData::Type type; + TQT_DBusData containerItem; + TQValueList list; +}; + +TQT_DBusDataList::TQT_DBusDataList() : d(new Private()) +{ +} + +TQT_DBusDataList::TQT_DBusDataList(TQT_DBusData::Type simpleItemType) : d(new Private()) +{ + d->type = simpleItemType; +} + +TQT_DBusDataList::TQT_DBusDataList(const TQT_DBusData& containerItemType) : d(new Private()) +{ + d->type = containerItemType.type(); + + switch(d->type) + { + case TQT_DBusData::List: // fall through + case TQT_DBusData::Struct: // fall through + case TQT_DBusData::Map: + d->containerItem = containerItemType; + break; + + default: // not a container + break; + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQT_DBusDataList& other) : d(new Private()) +{ + d->type = other.d->type; + d->list = other.d->list; + d->containerItem = other.d->containerItem; +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + + d->type = (*it).type(); + + TQCString elementSignature; + if (hasContainerItemType()) + { + d->containerItem = other[0]; // would be nice to get an empty one + elementSignature = d->containerItem.buildDBusSignature(); + } + + for (++it; it != endIt; ++it) + { + if (d->type != (*it).type()) + { + d->type = TQT_DBusData::Invalid; + d->containerItem = TQT_DBusData(); + + return; + } + else if (hasContainerItemType()) + { + if ((*it).buildDBusSignature() != elementSignature) + { + d->type = TQT_DBusData::Invalid; + d->containerItem = TQT_DBusData(); + + return; + } + } + } + + d->list = other; +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + d->type = TQT_DBusData::Bool; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromBool(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + d->type = TQT_DBusData::Byte; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromByte(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + d->type = TQT_DBusData::Int16; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromInt16(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + d->type = TQT_DBusData::UInt16; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromUInt16(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + d->type = TQT_DBusData::Int32; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromInt32(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + d->type = TQT_DBusData::UInt32; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromUInt32(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + d->type = TQT_DBusData::Int64; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromInt64(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + d->type = TQT_DBusData::UInt64; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromUInt64(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) +{ + d->type = TQT_DBusData::Double; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromDouble(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) + : d(new Private()) +{ + d->type = TQT_DBusData::Variant; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromVariant(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQStringList& other) : d(new Private()) +{ + d->type = TQT_DBusData::String; + + if (other.isEmpty()) return; + + TQStringList::const_iterator it = other.begin(); + TQStringList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromString(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) + : d(new Private()) +{ + d->type = TQT_DBusData::ObjectPath; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromObjectPath(*it); + } +} + +TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) + : d(new Private()) +{ + d->type = TQT_DBusData::UnixFd; + + if (other.isEmpty()) return; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromUnixFd(*it); + } +} + +TQT_DBusDataList::~TQT_DBusDataList() +{ + delete d; +} + +TQT_DBusDataList& TQT_DBusDataList::operator=(const TQT_DBusDataList& other) +{ + if (&other == this) return *this; + + d->type = other.d->type; + d->list = other.d->list; + d->containerItem = other.d->containerItem; + + return *this; +} + +TQT_DBusDataList& TQT_DBusDataList::operator=(const TQValueList& other) +{ + d->list.clear(); + d->type = TQT_DBusData::Invalid; + d->containerItem = TQT_DBusData(); + + if (other.isEmpty()) return *this; + + TQValueList::const_iterator it = other.begin(); + TQValueList::const_iterator endIt = other.end(); + + d->type = (*it).type(); + + TQCString elementSignature; + if (hasContainerItemType()) + { + d->containerItem = other[0]; // would be nice to get an empty one + + elementSignature = d->containerItem.buildDBusSignature(); + } + + for (++it; it != endIt; ++it) + { + if (d->type != (*it).type()) + { + d->type = TQT_DBusData::Invalid; + d->containerItem = TQT_DBusData(); + + return *this; + } + else if (hasContainerItemType()) + { + if ((*it).buildDBusSignature() != elementSignature) + { + d->type = TQT_DBusData::Invalid; + d->containerItem = TQT_DBusData(); + + return *this; + } + } + } + + d->list = other; + + return *this; +} + +TQT_DBusDataList& TQT_DBusDataList::operator=(const TQStringList& other) +{ + d->list.clear(); + d->type = TQT_DBusData::String; + d->containerItem = TQT_DBusData(); + + TQStringList::const_iterator it = other.begin(); + TQStringList::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + d->list << TQT_DBusData::fromString(*it); + } + + return *this; +} + +TQT_DBusData::Type TQT_DBusDataList::type() const +{ + return d->type; +} + +bool TQT_DBusDataList::hasContainerItemType() const +{ + return d->type == TQT_DBusData::List || d->type == TQT_DBusData::Map + || d->type == TQT_DBusData::Struct; +} + +TQT_DBusData TQT_DBusDataList::containerItemType() const +{ + return d->containerItem; +} + +bool TQT_DBusDataList::isEmpty() const +{ + return d->list.isEmpty(); +} + +uint TQT_DBusDataList::count() const +{ + return d->list.count(); +} + +bool TQT_DBusDataList::operator==(const TQT_DBusDataList& other) const +{ + if (&other == this) return true; + if (d == other.d) return true; + + bool containerEqual = true; + if (hasContainerItemType()) + { + if (other.hasContainerItemType()) + { + containerEqual = d->containerItem.buildDBusSignature() == + other.d->containerItem.buildDBusSignature(); + } + else + containerEqual = false; + } + else if (other.hasContainerItemType()) + containerEqual = false; + + return d->type == other.d->type && containerEqual && d->list == other.d->list; +} + +bool TQT_DBusDataList::operator!=(const TQT_DBusDataList& other) const +{ + if (&other == this) return false; + if (d == other.d) return false; + + bool containerEqual = true; + if (hasContainerItemType()) + { + if (other.hasContainerItemType()) + { + containerEqual = d->containerItem.buildDBusSignature() == + other.d->containerItem.buildDBusSignature(); + } + else + containerEqual = false; + } + else if (other.hasContainerItemType()) + containerEqual = false; + + return d->type != other.d->type || !containerEqual || d->list != other.d->list; +} + +void TQT_DBusDataList::clear() +{ + d->list.clear(); +} + +TQT_DBusDataList& TQT_DBusDataList::operator<<(const TQT_DBusData& data) +{ + if (data.type() == TQT_DBusData::Invalid) return *this; + + if (d->type == TQT_DBusData::Invalid) + { + d->type = data.type(); + + // check if we are now have container items + if (hasContainerItemType()) d->containerItem = data; + + d->list << data; + } + else if (d->type != data.type()) + { + tqWarning("TQT_DBusDataList: trying to add data of type %s to list of type %s", + data.typeName(), TQT_DBusData::typeName(d->type)); + } + else if (hasContainerItemType()) + { + TQCString ourSignature = d->containerItem.buildDBusSignature(); + TQCString dataSignature = data.buildDBusSignature(); + + if (ourSignature != dataSignature) + { + tqWarning("TQT_DBusDataList: trying to add data with signature %s " + "to list with item signature %s", + dataSignature.data(), ourSignature.data()); + } + else + d->list << data; + } + else + d->list << data; + + return *this; +} + +TQValueList TQT_DBusDataList::toTQValueList() const +{ + return d->list; +} + +TQStringList TQT_DBusDataList::toTQStringList(bool* ok) const +{ + if (d->type != TQT_DBusData::String) + { + if (ok != 0) *ok = false; + return TQStringList(); + } + + TQStringList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toString(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toBoolList(bool* ok) const +{ + if (d->type != TQT_DBusData::Bool) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toBool(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toByteList(bool* ok) const +{ + if (d->type != TQT_DBusData::Byte) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toByte(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toInt16List(bool* ok) const +{ + if (d->type != TQT_DBusData::Int16) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toInt16(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toUInt16List(bool* ok) const +{ + if (d->type != TQT_DBusData::UInt16) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toUInt16(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toInt32List(bool* ok) const +{ + if (d->type != TQT_DBusData::Int32) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toInt32(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toUInt32List(bool* ok) const +{ + if (d->type != TQT_DBusData::UInt32) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toUInt32(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toInt64List(bool* ok) const +{ + if (d->type != TQT_DBusData::Int64) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toInt64(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toUInt64List(bool* ok) const +{ + if (d->type != TQT_DBusData::UInt64) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toUInt64(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toDoubleList(bool* ok) const +{ + if (d->type != TQT_DBusData::Double) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toDouble(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toStringList(bool* ok) const +{ + return toTQStringList(ok); +} + +TQValueList TQT_DBusDataList::toObjectPathList(bool* ok) const +{ + if (d->type != TQT_DBusData::ObjectPath) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toObjectPath(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toUnixFdList(bool* ok) const +{ + if (d->type != TQT_DBusData::UnixFd) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toUnixFd(); + } + + if (ok != 0) *ok = true; + + return result; +} + +TQValueList TQT_DBusDataList::toVariantList(bool* ok) const +{ + if (d->type != TQT_DBusData::Variant) + { + if (ok != 0) *ok = false; + return TQValueList(); + } + + TQValueList result; + + TQValueList::const_iterator it = d->list.begin(); + TQValueList::const_iterator endIt = d->list.end(); + for (; it != endIt; ++it) + { + result << (*it).toVariant(); + } + + if (ok != 0) *ok = true; + + return result; +} diff --git a/src/tqdbusdatalist.h b/src/tqdbusdatalist.h new file mode 100644 index 0000000..bd0b467 --- /dev/null +++ b/src/tqdbusdatalist.h @@ -0,0 +1,758 @@ +/* qdbusdatalist.h list of DBUS data transport type + * + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSDATALIST_H +#define TQDBUSDATALIST_H + +#include "tqdbusdata.h" + +template class TQValueList; +class TQT_DBusObjectPath; +class TQT_DBusVariant; +class TQT_DBusUnixFd; +class TQString; +class TQStringList; + +/** + * @brief Class to transport lists of D-Bus data types + * + * \note while the D-Bus data type is actually called @c array this bindings + * use the term @c list since the behavior and characteristics of the + * implementation is more list like. + * + * There are basically two ways to create TQT_DBusDataList objects: + * - non-empty from content + * - empty by specifying the desired element type + * + * Example for creating a filled list from content + * @code + * TQValueList intList; + * list << 2 << 3 << 5 << 7; + * + * TQT_DBusDataList dbusList(intList); + * TQT_DBusData data = TQT_DBusData::fromList(dbusList); + * + * // or even shorter, using implicit conversion + * TQT_DBusData other = TQT_DBusData::fromList(intList); + * @endcode + * + * Example for creating an empty list + * @code + * // empty list for a simple type + * TQT_DBusDataList list(TQT_DBusData::Double); + * + * // empty list for a list of string lists + * TQT_DBusData elementType = TQT_DBusData::fromList(TQT_DBusDataList(TQT_DBusData::String)); + * TQT_DBusDataList outerList(elementType); + * @endcode + * + * @see TQT_DBusDataMap + */ +class TQDBUS_EXPORT TQT_DBusDataList +{ +public: + /** + * @brief Creates an empty and invalid list + * + * @see TQT_DBusData::Invalid + */ + TQT_DBusDataList(); + + /** + * @brief Creates an empty list with the given simple type for elements + * + * The given type has be one of the non-container types, i.e. any other than + * TQT_DBusData::Map, TQT_DBusData::List or TQT_DBusData::Struct + * + * For creating a list with elements which are containers themselves, use + * TQT_DBusDataList(const TQT_DBusData&); + * + * @param simpleItemType the type of the elements in the new list + */ + explicit TQT_DBusDataList(TQT_DBusData::Type simpleItemType); + + /** + * @brief Creates an empty list with the given container type for elements + * + * For creating a list with simple elements you can also use + * TQT_DBusDataList(TQT_DBusData::Type); + * + * @param containerItemType the type of the elements in the new list + * + * @see hasContainerItemType() + */ + explicit TQT_DBusDataList(const TQT_DBusData& containerItemType); + + /** + * @brief Creates a list from the given @p other list + * + * This behaves basically like copying a TQValueList through its copy + * constructor, i.e. no value are actually copied at this time. + * + * @param other the other list object to copy from + */ + TQT_DBusDataList(const TQT_DBusDataList& other); + + /** + * @brief Creates a list from the given TQValueList of TQT_DBusData objects + * + * If the @p other list is empty, this will behave like TQT_DBusDataList(), + * i.e. create an empty and invalid list object. + * + * Type information for the list object, i.e. element type and, if applicable, + * container item type, will be derived from the @p other list's elements. + * + * \warning if the elements of the @p other list do not all have the same + * type, the list object will also be empty and invalid + * + * @param other the TQValueList of TQT_DBusData objects to copy from + * + * @see toTQValueList() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of boolean values + * + * Type information for the list object will be set to TQT_DBusData::Bool + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Bool + * + * @param other the TQValueList of boolean values to copy from + * + * @see toBoolList() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of byte (unsigned char) values + * + * Type information for the list object will be set to TQT_DBusData::Byte + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Byte + * + * @param other the TQValueList of byte (unsigned char) values to copy from + * + * @see toByteList() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of signed 16-bit integer values + * + * Type information for the list object will be set to TQT_DBusData::Int16 + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Int16 + * + * @param other the TQValueList of signed 16-bit integer values to copy from + * + * @see toInt16List() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of unsigned 16-bit integer values + * + * Type information for the list object will be set to TQT_DBusData::UInt16 + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::UInt16 + * + * @param other the TQValueList of unsigned 16-bit integer values to copy from + * + * @see toUInt16List() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of signed 32-bit integer values + * + * Type information for the list object will be set to TQT_DBusData::Int32 + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Int32 + * + * @param other the TQValueList of signed 32-bit integer values to copy from + * + * @see toInt32List() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of unsigned 32-bit integer values + * + * Type information for the list object will be set to TQT_DBusData::UInt16 + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::UInt32 + * + * @param other the TQValueList of unsigned 32-bit integer values to copy from + * + * @see toUInt32List() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of signed 64-bit integer values + * + * Type information for the list object will be set to TQT_DBusData::Int64 + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Int64 + * + * @param other the TQValueList of signed 64-bit integer values to copy from + * + * @see toInt64List() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of unsigned 64-bit integer values + * + * Type information for the list object will be set to TQT_DBusData::UInt64 + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::UInt64 + * + * @param other the TQValueList of unsigned 64-bit integer values to copy from + * + * @see toUInt64List() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of double values + * + * Type information for the list object will be set to TQT_DBusData::Double + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Double + * + * @param other the TQValueList of double values to copy from + * + * @see toDoubleList() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of TQT_DBusVariant values + * + * Type information for the list object will be set to TQT_DBusData::Variant + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Variant + * + * @param other the TQValueList of variant values to copy from + * + * @see toVariantList() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQStringList's values + * + * Type information for the list object will be set to TQT_DBusData::String + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::String + * + * @param other the TQStringList to copy from + * + * @see toTQStringList() + */ + TQT_DBusDataList(const TQStringList& other); + + /** + * @brief Creates a list from the given TQValueList of object path values + * + * Type information for the list object will be set to TQT_DBusData::ObjectPath + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::ObjectPath + * + * @param other the TQValueList of object path values to copy from + * + * @see toObjectPathList() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Creates a list from the given TQValueList of unix file handle values + * + * Type information for the list object will be set to TQT_DBusData::UnixFd + * also when the @p other list is empty, i.e. this allows to create an + * empty but valid list object, comparable to using + * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::UnixFd + * + * @param other the TQValueList of unix file handle values to copy from + * + * @see toUnixFdList() + */ + TQT_DBusDataList(const TQValueList& other); + + /** + * @brief Destroys the list object + */ + ~TQT_DBusDataList(); + + /** + * @brief Copies from the given @p other list + * + * This behaves basically like copying a TQValueList through its assignment + * operator, i.e. no value are actually copied at this time. + * + * @param other the other list object to copy from + * + * @return a reference to this list object + */ + TQT_DBusDataList& operator=(const TQT_DBusDataList& other); + + /** + * @brief Copies from the given @p other list + * + * This behaves basically like copying a TQValueList through its assignment + * operator, i.e. no value are actually copied at this time. + * + * \warning the elements of the given @p other list have to be of the same + * type. If they aren't this list's content will cleared and the + * type will be set to TQT_DBusData::Invalid + * + * @param other the other list object to copy from + * + * @return a reference to this list object + */ + TQT_DBusDataList& operator=(const TQValueList& other); + + /** + * @brief Copies from the given @p other list + * + * Convenience overload as TQStringList is a very common data type in + * TQt and D-Bus methods also use "arrays of strings" quite often. + * + * The list object's type will be set to TQT_DBusData::String. If the object + * previously had a container as its element type, this will be reset, i.e. + * hasContainerItemType() will return @c false + * + * @param other the stringlist to copy from + * + * @return a reference to this list object + */ + TQT_DBusDataList& operator=(const TQStringList& other); + + /** + * @brief Returns the element type of the list object + * + * @return one of the values of the TQT_DBusData#Type enum + * + * @see hasContainerItemType() + * @see containerItemType() + */ + TQT_DBusData::Type type() const; + + /** + * @brief Checks whether the element type is a data container itself + * + * If the elements of the list are containers as well, this will return + * @c true + * In this case containerItemType() will return a prototype for such a + * container. + * + * @return @c true if the element type is either TQT_DBusData::Map, + * TQT_DBusData::List or TQT_DBusData::Struct, otherwise @c false + * + * @see TQT_DBusDataList(const TQT_DBusData&) + */ + bool hasContainerItemType() const; + + /** + * @brief Returns a container prototype for the list's element type + * + * Lists which have containers as their elements, i.e. hasContainerItemType() + * returns @c true this will actually specify the details for the use + * container, i.e. the returned data object can be queried for type and + * possible further subtypes. + * + * @return a data object detailing the element type or an invalid data object + * if the list does not have a container as its element type + * + * @see TQT_DBusDataList(const TQT_DBusData&); + * @see type() + * @see TQT_DBusData::Invalid + */ + TQT_DBusData containerItemType() const; + + /** + * @brief Checks whether this list object has a valid element type + * + * This is equal to checking type() for not being TQT_DBusData::Invalid + * + * @return @c true if the list object is valid, otherwise @c false + */ + inline bool isValid() const { return type() != TQT_DBusData::Invalid; } + + /** + * @brief Checks whether this list object has any elements + * + * @return @c true if there are no elements in this list, otherwise @c false + * + * @see count() + */ + bool isEmpty() const; + + /** + * @brief Returns the number of elements of this list object + * + * @return the number of elements + * + * @see isEmpty() + */ + uint count() const; + + /** + * @brief Checks whether the given @p other list is equal to this one + * + * Two lists are considered equal when they have the same type (and same + * container item type if the have one) and the element lists are equal + * as well. + * + * @param other the other list object to compare with + * + * @return @c true if the lists are equal, otherwise @c false + * + * @see TQT_DBusData::operator==() + */ + bool operator==(const TQT_DBusDataList& other) const; + + /** + * @brief Checks whether the given @p other list is different from this one + * + * Two lists are considered different when they have the different type (or + * different container item type if the have one) or the element lists are + * equal are different. + * + * @param other the other list object to compare with + * + * @return @c true if the lists are different, otherwise @c false + * + * @see TQT_DBusData::operator!=() + */ + bool operator!=(const TQT_DBusDataList& other) const; + + /** + * @brief Clears the list + * + * Type and, if applicable, container element type will stay untouched. + */ + void clear(); + + /** + * @brief Appends a given value to the list + * + * Basically works like the respective TQValueList operator, but checks if + * type of the new value matches the type of the list. + * Lists that are invalid will accept any new type and will then be + * typed accordingly. + * + * If @p data is invalid itself, it will not be appended at any time. + * + * \note the more common use case is to work with a TQValueList and then + * use the respective constructor to create the TQT_DBusDataList object + * + * @param data the data item to append to the list + * + * @return a reference to this list object + */ + TQT_DBusDataList& operator<<(const TQT_DBusData& data); + + /** + * @brief Converts the list object into a TQValueList with TQT_DBusData elements + * + * @return the values of the list object as a TQValueList + */ + TQValueList toTQValueList() const; + + /** + * @brief Tries to get the list object's elements as a TQStringList + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::String. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::String) + * + * @return a TQStringList containing the list object's string elements or + * an empty list when converting fails + * + * @see toStringList() + * @see TQT_DBusData::toString() + */ + TQStringList toTQStringList(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of bool + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::Bool. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::Bool) + * + * @return a TQValueList of bool containing the list object's boolean + * elements or an empty list when converting fails + * + * @see TQT_DBusData::toBool() + */ + TQValueList toBoolList(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQ_UINT8 + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::Byte. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::Byte) + * + * @return a TQValueList of TQ_UINT8 containing the list object's byte + * elements or an empty list when converting fails + * + * @see TQT_DBusData::toByte() + */ + TQValueList toByteList(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQ_INT16 + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::Int16. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::Int16) + * + * @return a TQValueList of TQ_INT16 containing the list object's + * signed 16-bit integer elements or an empty list when converting + * fails + * + * @see TQT_DBusData::toInt16() + */ + TQValueList toInt16List(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQ_UINT16 + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::UInt16. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::UInt16) + * + * @return a TQValueList of TQ_UINT16 containing the list object's + * unsigned 16-bit integer elements or an empty list when converting + * fails + * + * @see TQT_DBusData::toUInt16() + */ + TQValueList toUInt16List(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQ_INT32 + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::Int32. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::Int32) + * + * @return a TQValueList of TQ_INT32 containing the list object's + * signed 32-bit integer elements or an empty list when converting + * fails + * + * @see TQT_DBusData::toInt32() + */ + TQValueList toInt32List(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQ_UINT32 + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::UInt32. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::UInt32) + * + * @return a TQValueList of TQ_UINT32 containing the list object's + * unsigned 32-bit integer elements or an empty list when converting + * fails + * + * @see TQT_DBusData::toUInt32() + */ + TQValueList toUInt32List(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQ_INT64 + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::Int64. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::Int64) + * + * @return a TQValueList of TQ_INT64 containing the list object's + * signed 64-bit integer elements or an empty list when converting + * fails + * + * @see TQT_DBusData::toInt64() + */ + TQValueList toInt64List(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQ_UINT64 + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::UInt64. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::UInt64) + * + * @return a TQValueList of TQ_UINT64 containing the list object's + * unsigned 64-bit integer elements or an empty list when converting + * fails + * + * @see TQT_DBusData::toUInt64() + */ + TQValueList toUInt64List(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of double + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::Double. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::Double) + * + * @return a TQValueList of double containing the list object's double + * elements or an empty list when converting fails + * + * @see TQT_DBusData::toDouble() + */ + TQValueList toDoubleList(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQString + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::String, see also toTQStringList(). + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::String) + * + * @return a TQValueList of TQString containing the list object's string + * elements or an empty list when converting fails + * + * @see TQT_DBusData::toString() + */ + TQValueList toStringList(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of object paths + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::ObjectPath) + * + * @return a TQValueList of object paths containing the list object's object path + * elements or an empty list when converting fails + * + * @see TQT_DBusData::toObjectPath() + */ + TQValueList toObjectPathList(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQT_DBusVariant + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::Variant. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::Variant) + * + * @return a TQValueList of TQT_DBusVariant containing the list object's + * TQT_DBusVariant elements or an empty list when converting fails + * + * @see TQT_DBusData::toVariant() + */ + TQValueList toVariantList(bool* ok = 0) const; + + /** + * @brief Tries to get the list object's elements as a TQValueList of TQT_DBusUnixFd + * + * This is a convenience overload for the case when the list is of + * type TQT_DBusData::UnixFd. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of type + * TQT_DBusData::UnixFd) + * + * @return a TQValueList of TQT_DBusUnixFd containing the list object's + * TQT_DBusUnixFd elements or an empty list when converting fails + * + * @see TQT_DBusData::toUnixFd() + */ + TQValueList toUnixFdList(bool* ok = 0) const; + +private: + class Private; + Private* d; +}; + +#endif diff --git a/src/tqdbusdatamap.h b/src/tqdbusdatamap.h new file mode 100644 index 0000000..ecb06d2 --- /dev/null +++ b/src/tqdbusdatamap.h @@ -0,0 +1,1281 @@ +/* qdbusdatamap.h DBUS data mapping transport type + * + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSDATAMAP_H +#define TQDBUSDATAMAP_H + +#include "tqdbusmacros.h" +#include + +class TQT_DBusData; +class TQT_DBusObjectPath; +class TQT_DBusUnixFd; +class TQT_DBusVariant; + +/** + * @brief Class to transport maps of D-Bus data types + * + * \note while the D-Bus data type is actually called @c dict this bindings + * use the term @c map since TQT_DBusDataMap is essentially a TQMap + * + * There are basically two ways to create TQT_DBusDataMap objects: + * - non-empty from content + * - empty by specifying the desired element type + * + * Example for creating a filled map from content + * @code + * TQMap intToStringMap; + * map.insert(2, "two"); + * map.insert(3, "three"); + * map.insert(5, "five"); + * map.insert(7, "seven"); + * + * TQT_DBusDataMap dbusMap(intToStringMap); + * TQT_DBusData data = TQT_DBusData::fromInt16KeyMap(dbusMap); + * + * // or even shorter, using implicit conversion + * TQT_DBusData other = TQT_DBusData::fromInt16KeyMap(intList); + * @endcode + * + * Example for creating an empty map + * @code + * // empty map for a simple type, mapping from TQString to double + * TQT_DBusDataMap list(TQT_DBusData::Double); + * + * // empty map for value type string lists + * TQT_DBusData valueType = TQT_DBusData::fromList(TQT_DBusDataList(TQT_DBusData::String)); + * TQT_DBusDataMap map(valueType); + * @endcode + * + * @see TQT_DBusDataList + */ +template +class TQDBUS_EXPORT TQT_DBusDataMap : private TQMap +{ + friend class TQT_DBusData; + +public: + /** + * Constant iterator. A TQMapConstIterator with value type specified + * as TQT_DBusData + */ + typedef TQMapConstIterator const_iterator; + + /** + * @brief Creates an empty and invalid map + * + * @see TQT_DBusData::Invalid + */ + TQT_DBusDataMap() + : TQMap(), m_valueType(TQT_DBusData::Invalid) {} + + /** + * @brief Creates an empty map with the given simple type for values + * + * The given type has be one of the non-container types, i.e. any other than + * TQT_DBusData::Map, TQT_DBusData::List or TQT_DBusData::Struct + * + * For creating a map with elements which are containers themselves, use + * TQT_DBusDataMap(const TQT_DBusData&); + * + * @param simpleValueType the type of the values in the new map + */ + explicit TQT_DBusDataMap(TQT_DBusData::Type simpleValueType) + : TQMap(), m_valueType(simpleValueType) {} + + /** + * @brief Creates an empty map with the given container type for values + * + * For creating a map with simple values you can also use + * TQT_DBusDataMap(TQT_DBusData::Type); + * + * @param containerValueType the type of the values in the new map + * + * @see hasContainerValueType() + */ + explicit TQT_DBusDataMap(const TQT_DBusData& containerValueType) + : TQMap(), m_valueType(containerValueType.type()) + { + if (hasContainerValueType()) m_containerValueType = containerValueType; + } + + /** + * @brief Creates a map from the given @p other map + * + * This behaves basically like copying a TQMap through its copy + * constructor, i.e. no value are actually copied at this time. + * + * @param other the other map object to copy from + */ + TQT_DBusDataMap(const TQT_DBusDataMap& other) + : TQMap(other), m_valueType(other.m_valueType), + m_containerValueType(other.m_containerValueType) {} + + /** + * @brief Creates a map from the given TQMap of TQT_DBusData objects + * + * If the @p other map is empty, this will behave like TQT_DBusDataMap(), + * i.e. create an empty and invalid map object. + * + * Type information for the map object, i.e. value type and, if applicable, + * container value type, will be derived from the @p other map's elements. + * + * \warning if the values of the @p other map do not all have the same + * type, the map object will also be empty and invalid + * + * @param other the TQMap of TQT_DBusData objects to copy from + * + * @see toTQMap() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(other), m_valueType(TQT_DBusData::Invalid) + { + const_iterator it = begin(); + if (it == end()) return; + + m_valueType = (*it).type(); + + TQCString containerSignature; + if (hasContainerValueType()) + { + m_containerValueType = it.data(); + containerSignature = m_containerValueType.buildDBusSignature(); + } + + for (++it; it != end(); ++it) + { + if ((*it).type() != m_valueType) + { + m_valueType = TQT_DBusData::Invalid; + m_containerValueType = TQT_DBusData(); + + clear(); + return; + } + else if (hasContainerValueType()) + { + if (it.data().buildDBusSignature() != containerSignature) + { + m_valueType = TQT_DBusData::Invalid; + m_containerValueType = TQT_DBusData(); + + clear(); + return; + } + } + } + } + + /** + * @brief Creates a list from the given TQMap of boolean values + * + * Type information for the map object will be set to TQT_DBusData::Bool + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Bool + * + * @param other the TQMap of boolean values to copy from + * + * @see toBoolMap() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::Bool) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromBool(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of byte (unsigned char) values + * + * Type information for the map object will be set to TQT_DBusData::Byte + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Byte + * + * @param other the TQMap of byte (unsigned char) values to copy from + * + * @see toByteMap() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::Byte) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromByte(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of signed 16-bit integer values + * + * Type information for the map object will be set to TQT_DBusData::Int16 + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Int16 + * + * @param other the TQMap of signed 16-bit integer values to copy from + * + * @see toInt16Map() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::Int16) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromInt16(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of unsigned 16-bit integer values + * + * Type information for the map object will be set to TQT_DBusData::UInt16 + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::UInt16 + * + * @param other the TQMap of unsigned 16-bit integer values to copy from + * + * @see toUInt16Map() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::UInt16) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromUInt16(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of signed 32-bit integer values + * + * Type information for the map object will be set to TQT_DBusData::Int32 + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Int32 + * + * @param other the TQMap of signed 32-bit integer values to copy from + * + * @see toInt32Map() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::Int32) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromInt32(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of unsigned 32-bit integer values + * + * Type information for the map object will be set to TQT_DBusData::UInt16 + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::UInt32 + * + * @param other the TQMap of unsigned 32-bit integer values to copy from + * + * @see toUInt32Map() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::UInt32) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromUInt32(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of signed 64-bit integer values + * + * Type information for the map object will be set to TQT_DBusData::Int64 + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Int64 + * + * @param other the TQMap of signed 64-bit integer values to copy from + * + * @see toInt64Map() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::Int64) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromInt64(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of unsigned 64-bit integer values + * + * Type information for the map object will be set to TQT_DBusData::UInt64 + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::UInt64 + * + * @param other the TQMap of unsigned 64-bit integer values to copy from + * + * @see toUInt64Map() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::UInt64) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromUInt64(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of double values + * + * Type information for the map object will be set to TQT_DBusData::Double + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Double + * + * @param other the TQMap of double values to copy from + * + * @see toDoubleMap() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::Double) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromDouble(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of TQString values + * + * Type information for the map object will be set to TQT_DBusData::String + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::String + * + * @param other the TQMap of TQString values to copy from + * + * @see toStringMap() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::String) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromString(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of object path values + * + * Type information for the map object will be set to TQT_DBusData::ObjectPath + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::ObjectPath + * + * @param other the TQMap of object path values to copy from + * + * @see toObjectPathMap() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::ObjectPath) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromObjectPath(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of TQT_DBusUnixFd values + * + * Type information for the map object will be set to TQT_DBusData::UnixFd + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::UnixFd + * + * @param other the TQMap of TQT_DBusUnixFd values to copy from + * + * @see toUnixFdMap() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::UnixFd) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromUnixFd(it.data())); + } + } + + /** + * @brief Creates a map from the given TQMap of TQT_DBusVariant values + * + * Type information for the map object will be set to TQT_DBusData::Variant + * also when the @p other map is empty, i.e. this allows to create an + * empty but valid map object, comparable to using + * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Variant + * + * @param other the TQMap of variant values to copy from + * + * @see toVariantMap() + */ + TQT_DBusDataMap(const TQMap& other) + : TQMap(), m_valueType(TQT_DBusData::Variant) + { + typename TQMap::const_iterator it = other.begin(); + typename TQMap::const_iterator endIt = other.end(); + for (; it != endIt; ++it) + { + insert(it.key(), TQT_DBusData::fromVariant(it.data())); + } + } + + /** + * @brief Copies from the given @p other map + * + * This behaves basically like copying a TQMap through its assignment + * operator, i.e. no value are actually copied at this time. + * + * @param other the other map object to copy from + * + * @return a reference to this map object + */ + TQT_DBusDataMap& operator=(const TQT_DBusDataMap& other) + { + TQMap::operator=(other); + + m_valueType = other.m_valueType; + m_containerValueType = other.m_containerValueType; + + return *this; + } + + /** + * @brief Copies from the given @p other map + * + * This behaves basically like copying a TQMap through its assignment + * operator, i.e. no value are actually copied at this time. + * + * \warning the value of the given @p other map have to be of the same + * type. If they aren't this maps's content will cleared and the + * value type will be set to TQT_DBusData::Invalid + * + * @param other the other map object to copy from + * + * @return a reference to this map object + */ + TQT_DBusDataMap& operator=(const TQMap& other) + { + TQMap::operator=(other); + + m_valueType = TQT_DBusData::Invalid; + m_containerValueType = TQT_DBusData(); + + const_iterator it = begin(); + if (it == end()) return *this; + + m_valueType = (*it).type(); + + TQCString containerSignature; + if (hasContainerValueType()) + { + m_containerValueType = it.data(); + containerSignature = m_containerValueType.buildDBusSignature(); + } + + for (++it; it != end(); ++it) + { + if ((*it).type() != m_valueType) + { + m_valueType = TQT_DBusData::Invalid; + m_containerValueType = TQT_DBusData(); + + clear(); + return *this; + } + else if (hasContainerValueType()) + { + if (it.data()->buildSignature() != containerSignature) + { + m_valueType = TQT_DBusData::Invalid; + m_containerValueType = TQT_DBusData(); + + clear(); + return *this; + } + } + } + + return *this; + } + + /** + * @brief Returns the key type of the map object + * + * @return one of the values of the TQT_DBusData#Type enum suitable for + * map keys. See TQT_DBusData::Map for details + * + * @see valueType() + */ + TQT_DBusData::Type keyType() const { return m_keyType; } + + /** + * @brief Returns the value type of the map object + * + * @return one of the values of the TQT_DBusData#Type enum + * + * @see hasContainerValueType() + * @see containerValueType() + * @see keyType() + */ + TQT_DBusData::Type valueType() const { return m_valueType; } + + /** + * @brief Checks whether the value type is a data container itself + * + * If the value of the map are containers as well, this will return + * @c true + * In this case containerValueType() will return a prototype for such a + * container. + * + * @return @c true if the value type is either TQT_DBusData::Map, + * TQT_DBusData::List or TQT_DBusData::Struct, otherwise @c false + * + * @see TQT_DBusDataMap(const TQT_DBusData&) + */ + bool hasContainerValueType() const + { + return m_valueType == TQT_DBusData::List || m_valueType == TQT_DBusData::Struct + || m_valueType == TQT_DBusData::Map; + } + + /** + * @brief Returns a container prototype for the map's value type + * + * Lists which have containers as their elements, i.e. hasContainerValueType() + * returns @c true this will actually specify the details for the use + * container, i.e. the returned data object can be queried for type and + * possible further subtypes. + * + * @return a data object detailing the value type or an invalid data object + * if the map does not have a container as its element type + * + * @see TQT_DBusDataMap(const TQT_DBusData&); + * @see valueType() + * @see TQT_DBusData::Invalid + */ + TQT_DBusData containerValueType() const { return m_containerValueType; } + + /** + * @brief Checks whether this map object has a valid value type + * + * This is equal to checking valueType() for not being TQT_DBusData::Invalid + * + * @return @c true if the map object is valid, otherwise @c false + */ + inline bool isValid() const { return valueType() != TQT_DBusData::Invalid; } + + /** + * @brief Checks whether this map object has any key/value pairs + * + * @return @c true if there are no key/values in this map, otherwise @c false + * + * @see count() + */ + bool isEmpty() const { return TQMap::empty(); } + + /** + * @brief Returns the number of key/value pairs of this map object + * + * @return the number of key/value pairs + * + * @see isEmpty() + */ + uint count() const { return TQMap::count(); } + + /** + * @brief Checks whether the given @p other map is equal to this one + * + * Two maps are considered equal when they have the same value type (and same + * container value type if the have one) and the key/value pairs are equal + * as well. + * + * @param other the other map object to compare with + * + * @return @c true if the maps are equal, otherwise @c false + * + * @see TQT_DBusData::operator==() + */ + bool operator==(const TQT_DBusDataMap& other) const + { + if (m_valueType != other.m_valueType) return false; + + if (count() != other.count()) return false; + + if (hasContainerValueType() != other.hasContainerValueType()) return false; + + if (hasContainerValueType()) + { + if (m_containerValueType.buildDBusSignature() != + other.m_containerValueType.buildDBusSignature()) return false; + } + + const_iterator it = begin(); + const_iterator otherIt = other.begin(); + for (; it != end() && otherIt != other.end(); ++it, ++otherIt) + { + if (it.key() != otherIt.key()) return false; + + if (!(it.data() == otherIt.data())) return false; + } + + return true; + } + + /** + * @brief Clears the map + * + * Value type and, if applicable, container value type will stay untouched. + */ + void clear() { TQMap::clear(); } + + /** + * @brief Returns an iterator to the first item according to the key sort order + * + * @see TQMap::begin() + */ + const_iterator begin() const + { + return TQMap::begin(); + } + + /** + * @brief Returns an iterator to an invalid position + * + * @see TQMap::end() + */ + const_iterator end() const + { + return TQMap::end(); + } + + /** + * @brief Inserts a given value for a given key + * + * Basically works like the respective TQMap method, but checks if + * type of the new value matches the value type of the list. + * Maps that are invalid will accept any new type and will then be + * typed accordingly. + * + * If @p data is invalid itself, it will not be inserted at any time. + * + * \note the more common use case is to work with a TQMap and then + * use the respective constructor to create the TQT_DBusDataMap object + * + * @param key the key were to insert into the map + * @param data the data item to insert into the map + * + * @return @c true on successfull insert, otherwise @c false + */ + bool insert(const T& key, const TQT_DBusData& data) + { + if (data.type() == TQT_DBusData::Invalid) return false; + + if (m_valueType == TQT_DBusData::Invalid) + { + m_valueType = data.type(); + + // TODO: create empty copy of container + if (hasContainerValueType()) m_containerValueType = data; + + TQMap::insert(key, data); + } + else if (data.type() != m_valueType) + { + tqWarning("TQT_DBusDataMap: trying to add data of type %s to map of type %s", + data.typeName(), TQT_DBusData::typeName(m_valueType)); + } + else if (hasContainerValueType()) + { + TQCString ourSignature = m_containerValueType.buildDBusSignature(); + TQCString dataSignature = data.buildDBusSignature(); + + if (ourSignature != dataSignature) + { + tqWarning("TQT_DBusDataMap: trying to add data with signature %s " + "to map with value signature %s", + dataSignature.data(), ourSignature.data()); + } + else + TQMap::insert(key, data); + } + else + TQMap::insert(key, data); + + return true; + } + + /** + * @brief Converts the map object into a TQMap with TQT_DBusData elements + * + * @return the key/value pairs of the map object as a TQMap + */ + TQMap toTQMap() const { return *this; } + + /** + * @brief Tries to get the map object's pairs as a TQMap of bool + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::Bool. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::Bool) + * + * @return a TQMap of bool containing the list object's boolean + * values or an empty map when converting fails + * + * @see TQT_DBusData::toBool() + */ + TQMap toBoolMap(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::Bool) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toBool()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQ_UINT8 + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::Byte. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::Byte) + * + * @return a TQMap of TQ_UINT8 containing the list object's byte + * values or an empty map when converting fails + * + * @see TQT_DBusData::toBool() + */ + TQMap toByteMap(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::Byte) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toByte()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQ_INT16 + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::Int16. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::Int16) + * + * @return a TQMap of TQ_INT16 containing the map object's + * signed 16-bit integer values or an empty map when converting + * fails + * + * @see TQT_DBusData::toInt16() + */ + TQMap toInt16Map(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::Int16) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toInt16()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQ_UINT16 + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::UInt16. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::UInt16) + * + * @return a TQMap of TQ_UINT16 containing the map object's + * unsigned 16-bit integer values or an empty map when converting + * fails + * + * @see TQT_DBusData::toUInt16() + */ + TQMap toUInt16Map(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::UInt16) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toUInt16()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQ_INT32 + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::Int32. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::Int32) + * + * @return a TQMap of TQ_INT32 containing the map object's + * signed 32-bit integer values or an empty map when converting + * fails + * + * @see TQT_DBusData::toInt32() + */ + TQMap toInt32Map(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::Int32) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toInt32()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQ_UINT32 + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::UInt32. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::UInt32) + * + * @return a TQMap of TQ_UINT32 containing the map object's + * unsigned 32-bit integer values or an empty map when converting + * fails + * + * @see TQT_DBusData::toUInt32() + */ + TQMap toUInt32Map(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::UInt32) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toUInt32()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQ_INT64 + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::Int64. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::Int64) + * + * @return a TQMap of TQ_INT64 containing the map object's + * signed 64-bit integer values or an empty map when converting + * fails + * + * @see TQT_DBusData::toInt64() + */ + TQMap toInt64Map(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::Int64) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toInt64()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQ_UINT64 + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::UInt64. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::UInt64) + * + * @return a TQMap of TQ_UINT64 containing the map object's + * unsigned 64-bit integer values or an empty map when converting + * fails + * + * @see TQT_DBusData::toUInt64() + */ + TQMap toUInt64Map(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::UInt64) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toUInt64()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of double + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::Double. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::Double) + * + * @return a TQMap of double containing the map object's double + * values or an empty map when converting fails + * + * @see TQT_DBusData::toDouble() + */ + TQMap toDoubleMap(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::Double) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toDouble()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQString + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::String, see also toTQStringList(). + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::String) + * + * @return a TQMap of TQString containing the map object's string + * values or an empty map when converting fails + * + * @see TQT_DBusData::toString() + */ + TQMap toStringMap(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::String) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toString()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of object paths + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::ObjectPath) + * + * @return a TQMap of object paths containing the map object's object path + * values or an empty map when converting fails + * + * @see TQT_DBusData::toObjectPath() + */ + TQMap toObjectPathMap(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::ObjectPath) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toObjectPath()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQT_DBusUnixFd + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::UnixFd) + * + * @return a TQMap of TQT_DBusUnixFd containing the map object's TQT_DBusUnixFd + * values or an empty map when converting fails + * + * @see TQT_DBusData::toUnixFd() + */ + TQMap toUnixFdMap(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::UnixFd) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toUnixFd()); + } + + if (ok != 0) *ok = true; + + return result; + } + + /** + * @brief Tries to get the map object's pairs as a TQMap of TQT_DBusVariant + * + * This is a convenience overload for the case when the map is of + * value type TQT_DBusData::Variant. + * + * @param ok optional pointer to a bool variable to store the + * success information in, i.e. will be set to @c true on success + * and to @c false if the conversion failed (not of value type + * TQT_DBusData::Variant) + * + * @return a TQMap of TQT_DBusVariant containing the map object's + * TQT_DBusVariant values or an empty map when converting fails + * + * @see TQT_DBusData::toVariant() + */ + TQMap toVariantMap(bool* ok = 0) const + { + if (m_valueType != TQT_DBusData::Variant) + { + if (ok != 0) *ok = false; + return TQMap(); + } + + TQMap result; + + const_iterator it = begin(); + const_iterator endIt = end(); + for (; it != endIt; ++it) + { + result.insert(it.key(), (*it).toVariant()); + } + + if (ok != 0) *ok = true; + + return result; + } + +private: + TQT_DBusData::Type m_valueType; + TQT_DBusData m_containerValueType; + + static const TQT_DBusData::Type m_keyType; +}; + +#endif diff --git a/src/tqdbuserror.cpp b/src/tqdbuserror.cpp new file mode 100644 index 0000000..d0b1eb9 --- /dev/null +++ b/src/tqdbuserror.cpp @@ -0,0 +1,216 @@ +/* qdbuserror.cpp TQT_DBusError object + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2005-2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include "tqdbuserror.h" + +#include + +#include + +typedef TQMap ErrorNameMap; +static ErrorNameMap errorTypesByName; + +static TQString qDBusErrorNameForType(TQT_DBusError::ErrorType type) +{ + switch (type) + { + case TQT_DBusError::InvalidError: + Q_ASSERT(false); + return TQString(); + + case TQT_DBusError::Failed: + return TQString::fromUtf8(DBUS_ERROR_FAILED); + case TQT_DBusError:: NoMemory: + return TQString::fromUtf8(DBUS_ERROR_NO_MEMORY); + case TQT_DBusError:: ServiceUnknown: + return TQString::fromUtf8(DBUS_ERROR_SERVICE_UNKNOWN); + case TQT_DBusError:: NameHasNoOwner: + return TQString::fromUtf8(DBUS_ERROR_NAME_HAS_NO_OWNER); + case TQT_DBusError:: NoReply: + return TQString::fromUtf8(DBUS_ERROR_NO_REPLY); + case TQT_DBusError:: IOError: + return TQString::fromUtf8(DBUS_ERROR_IO_ERROR); + case TQT_DBusError:: BadAddress: + return TQString::fromUtf8(DBUS_ERROR_BAD_ADDRESS); + case TQT_DBusError:: NotSupported: + return TQString::fromUtf8(DBUS_ERROR_NOT_SUPPORTED); + case TQT_DBusError:: LimitsExceeded: + return TQString::fromUtf8(DBUS_ERROR_LIMITS_EXCEEDED); + case TQT_DBusError:: AccessDenied: + return TQString::fromUtf8(DBUS_ERROR_ACCESS_DENIED); + case TQT_DBusError:: AuthFailed: + return TQString::fromUtf8(DBUS_ERROR_AUTH_FAILED); + case TQT_DBusError:: NoServer: + return TQString::fromUtf8(DBUS_ERROR_NO_SERVER); + case TQT_DBusError:: Timeout: + return TQString::fromUtf8(DBUS_ERROR_TIMEOUT); + case TQT_DBusError:: NoNetwork: + return TQString::fromUtf8(DBUS_ERROR_NO_NETWORK); + case TQT_DBusError:: Disconnected: + return TQString::fromUtf8(DBUS_ERROR_DISCONNECTED); + case TQT_DBusError:: InvalidArgs: + return TQString::fromUtf8(DBUS_ERROR_INVALID_ARGS); + case TQT_DBusError:: FileNotFound: + return TQString::fromUtf8(DBUS_ERROR_FILE_NOT_FOUND); + case TQT_DBusError:: FileExists: + return TQString::fromUtf8(DBUS_ERROR_FILE_EXISTS); + case TQT_DBusError:: UnknownMethod: + return TQString::fromUtf8(DBUS_ERROR_UNKNOWN_METHOD); + case TQT_DBusError:: TimedOut: + return TQString::fromUtf8(DBUS_ERROR_TIMED_OUT); + case TQT_DBusError:: InvalidSignature: + return TQString::fromUtf8(DBUS_ERROR_INVALID_SIGNATURE); + + case TQT_DBusError::UserDefined: + Q_ASSERT(false); + return TQString(); + } + + Q_ASSERT(false); + return TQString(); +} + +static void qDBusErrorSetupNameMapping() +{ + for (int i = TQT_DBusError::InvalidError + 1; i < TQT_DBusError::UserDefined; ++i) + { + TQT_DBusError::ErrorType type = static_cast(i); + errorTypesByName[qDBusErrorNameForType(type)] = type; + } +} + +static TQT_DBusError::ErrorType qDBusErrorTypeForName(const TQString& name) +{ + if (name.isEmpty()) return TQT_DBusError::InvalidError; + + if (errorTypesByName.isEmpty()) + qDBusErrorSetupNameMapping(); + + ErrorNameMap::const_iterator it = errorTypesByName.find(name); + if (it != errorTypesByName.end()) return it.data(); + + return TQT_DBusError::UserDefined; +} + +TQT_DBusError::TQT_DBusError() : errorType(InvalidError), m_dbusErrorSet(false) +{ +} + +TQT_DBusError::TQT_DBusError(const DBusError *error) : errorType(InvalidError), m_dbusErrorSet(false) +{ + if (!error || !dbus_error_is_set(error)) + return; + + nm = TQString::fromUtf8(error->name); + msg = TQString::fromUtf8(error->message); + + errorType = qDBusErrorTypeForName(nm); +} + +TQT_DBusError::TQT_DBusError(const TQString& error, const TQString& message) + : errorType(UserDefined), m_dbusErrorSet(false), nm(error), msg(message) +{ + errorType = qDBusErrorTypeForName(nm); +} + +bool TQT_DBusError::isValid() const +{ + return errorType != InvalidError && !nm.isEmpty() && !msg.isEmpty(); +} + +TQT_DBusError::TQT_DBusError(ErrorType type, const TQString& message) + : errorType(type), m_dbusErrorSet(false), msg(message) +{ + nm = qDBusErrorNameForType(type); +} + +TQT_DBusError TQT_DBusError::stdFailed(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::Failed, message); +} + +TQT_DBusError TQT_DBusError::stdNoMemory(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::NoMemory, message); +} + +TQT_DBusError TQT_DBusError::stdNoReply(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::NoReply, message); +} + +TQT_DBusError TQT_DBusError::stdIOError(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::IOError, message); +} + +TQT_DBusError TQT_DBusError::stdNotSupported(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::NotSupported, message); +} + +TQT_DBusError TQT_DBusError::stdLimitsExceeded(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::LimitsExceeded, message); +} + +TQT_DBusError TQT_DBusError::stdAccessDenied(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::AccessDenied, message); +} + +TQT_DBusError TQT_DBusError::stdAuthFailed(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::AuthFailed, message); +} + +TQT_DBusError TQT_DBusError::stdTimeout(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::Timeout, message); +} + +TQT_DBusError TQT_DBusError::stdInvalidArgs(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::InvalidArgs, message); +} + +TQT_DBusError TQT_DBusError::stdFileNotFound(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::FileNotFound, message); +} + +TQT_DBusError TQT_DBusError::stdFileExists(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::FileExists, message); +} + +TQT_DBusError TQT_DBusError::stdUnknownMethod(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::UnknownMethod, message); +} + +TQT_DBusError TQT_DBusError::stdInvalidSignature(const TQString& message) +{ + return TQT_DBusError(TQT_DBusError::InvalidSignature, message); +} diff --git a/src/tqdbuserror.h b/src/tqdbuserror.h new file mode 100644 index 0000000..ff11ffb --- /dev/null +++ b/src/tqdbuserror.h @@ -0,0 +1,476 @@ +/* qdbuserror.h TQT_DBusError object + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2005 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSERROR_H +#define TQDBUSERROR_H + +#include "tqdbusmacros.h" +#include + +struct DBusError; + +/** + * @brief Class for transporting D-Bus errors + * + * A D-Bus error has two parts: an error name (see section + * @ref dbusconventions-errorname) and a message string detailing the error in + * human presentable form. + */ +class TQDBUS_EXPORT TQT_DBusError +{ +public: + /** + * @brief Enum of standard D-Bus error types + * + * D-Bus defines a list of common error types and their names. + * The values of this enum map to those an application is likely to encounter + * and likely to create itself. + * + * Standard errors can either be created by specifying the D-Bus error name + * or, as a convenience, by using factory methods of this class for the + * most common ones. + * + * All D-Bus standard error names are within the @c "org.freedesktop.DBus.Error" + * namespace. + * + * @see name() + */ + enum ErrorType + { + /** + * @brief TQT_DBusError specific value, to represent invalid error objects. + * + * @see isValid() + */ + InvalidError, + + /** + * @brief Generic failure cause + * + * Can be used whenever the other predefined errors do no match. Basically + * just meaning "something when wrong, see message() for details" + * + * @see stdFailed() + */ + Failed, + + /** + * @brief An operation could not allocate enough memory + * + * @see stdNoMemory() + */ + NoMemory, + + /** + * @brief An addressed service is neither connected nor can it be activated + */ + ServiceUnknown, + + /** + * @brief A non-unique name used in a message is not known + * + * If a message addresses a D-Bus connection through a non-unique + * (requested) name and the D-Bus does not have a mapping to any of the + * unique names. + */ + NameHasNoOwner, + + /** + * @brief An call failed to send a reply but one was expected + * + * @see stdNoReply() + */ + NoReply, + + /** + * @brief An IO error occured during an operation + * + * Generic indicator that some kind of IO operation failed, e.g. + * reading from a socket. + * + * @see stdIOError() + */ + IOError, + + /** + * @brief Caused by trying to connect to a malformed address + * + * Returned by TQT_DBusConnection's addConnection if the specified address + * isn't a valid D-Bus bus address. + * + * @see TQT_DBusConnection::addConnection(const TQString&,const TQString&); + */ + BadAddress, + + /** + * @brief An otherwise valid operation request could not be handled + * + * Primarily useful when a service implements a specific interface but + * does not (yet) handle all possible situations. + * + * @see stdNotSupported() + */ + NotSupported, + + /** + * @brief Use of a limited resource reached its limit + * + * @see stdLimitsExceeded() + */ + LimitsExceeded, + + /** + * @brief Caused by security restrictions denying an operation + * + * Primarily useful when a client tries to manipulate resources a service + * has associated with a different client and which should not be changable + * by anyone else. + * + * @see stdAccessDenied() + */ + AccessDenied, + + /** + * @brief An authentification mechanism failed + * + * @see stdAuthFailed() + */ + AuthFailed, + + /** + * @brief Connection to a D-Bus server failed + */ + NoServer, + + /** + * @brief An timeout occured during an operation + * + * @warning D-Bus defined to quite similar errors but does not detail + * when either one can occur. See #TimedOut + * + * @see stdTimeout() + */ + Timeout, + + /** + * @brief The network intended as a transport channel is not available + */ + NoNetwork, + + /** + * @brief Caused by trying to use an unconnected D-Bus connection + * + * @see TQT_DBusConnection::isConnected() + */ + Disconnected, + + /** + * @brief Caused by invalid arguments passed to a method call + * + * Primarily usefull for service implementations when the incoming + * call does not transport the expected parameters, e.g. wrong types + * or wrong values. + * + * @see stdInvalidArgs() + */ + InvalidArgs, + + /** + * @brief A file necessary for an operation is not avaiable + * + * @see stdFileNotFound() + */ + FileNotFound, + + /** + * @brief Target file exists but operation does not allow overwriting + * + * @see stdFileExists() + */ + FileExists, + + /** + * @brief A method call addresses and unknown method + * + * @see stdUnknownMethod() + */ + UnknownMethod, + + /** + * @brief An operation timed out + * + * @warning D-Bus defined to quite similar errors but does not detail + * when either one can occur. See #Timeout + */ + TimedOut, + + /** + * @brief An type signature is not valid + * + * A possible cause is a TQT_DBusVariant with an invalid signature, i.e. + * the transported signature is empty, contains unknown type characters + * or has mismatched container enclosings. + * + * @note in case a service implementation wants to indicate that a method + * call did not transport the correct parameter types, use + * #InvalidArgs instead + * + * @see stdInvalidSignature() + */ + InvalidSignature, + + /** + * @brief Generic type for all errors not matching on of the other predefined + * + * @see TQT_DBusError(const TQString&,const TQString&); + */ + UserDefined + }; + + /** + * @brief Creates an empty and invalid error object + */ + TQT_DBusError(); + + /** + * @brief Creates an error object from an C API D-Bus error object + * + * @param error a pointer to the C API D-Bus error + */ + TQT_DBusError(const DBusError *error); + + /** + * @brief Creates an error object for its two given components + * + * @param error a D-Bus error name + * @param message the potentially i18n'ed error description message + * + * @see name() + */ + TQT_DBusError(const TQString& error, const TQString& message); + + /** + * @brief Returns the D-Bus error name + * + * See section @ref dbusconventions-errorname for details. + * + * @return the D-Bus error name + * + * @see message() + */ + inline TQString name() const { return nm; } + + /** + * @brief Returns a string describing the error + * + * The message is meant to further detail or describe the error. + * It is usually a translated error message meant for direct + * presentation to the user. + * + * @return the error's message + * + * @see name() + */ + inline TQString message() const { return msg; } + + /** + * @brief Returns a type for checking of standard errors + * + * D-Bus specifies a couple of standard error names, which are mapped to + * TQT_DBusError types in order to make creating and checking for them easier. + * + * @return the error's type + * + * @see name() + */ + inline ErrorType type() const { return errorType; } + + /** + * @brief Returns whether the error was caused by DBUS itself + * + * A TQT_DBusError is considered valid if both name and message are set. + * + * @return @c true if dbus_error_is_set was true after DBUS call completion + */ + inline bool dbusErrorSet() const { return m_dbusErrorSet; } + + /** + * @internal + */ + inline void setDBUSError(bool err) const { m_dbusErrorSet = err; } + + /** + * @brief Returns whether the error object is valid + * + * A TQT_DBusError is considered valid if both name and message are set. + * + * @return @c true if neither name nor message is @c TQString() and the + * error type is a valid type + */ + bool isValid() const; + + /** + * @brief Creates a D-Bus standard error for generic failure + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #Failed with the given @p message + */ + static TQT_DBusError stdFailed(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for out of memory situations + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #NoMemory with the given @p message + */ + static TQT_DBusError stdNoMemory(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for expected reply missing + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #NoReply with the given @p message + */ + static TQT_DBusError stdNoReply(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for generic IO errors + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #IOError with the given @p message + */ + static TQT_DBusError stdIOError(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for unsupported operations + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #NotSupported with the given @p message + */ + static TQT_DBusError stdNotSupported(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for exceeding a limited resource + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #LimitsExceeded with the given @p message + */ + static TQT_DBusError stdLimitsExceeded(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for access to a resource being denied + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #AccessDenied with the given @p message + */ + static TQT_DBusError stdAccessDenied(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for failed authentification + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #AuthFailed with the given @p message + */ + static TQT_DBusError stdAuthFailed(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for timeouts during operations + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #Timeout with the given @p message + */ + static TQT_DBusError stdTimeout(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for call arguments being invalid + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #InvalidArgs with the given @p message + */ + static TQT_DBusError stdInvalidArgs(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for a file not being available + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #FileNotFound with the given @p message + */ + static TQT_DBusError stdFileNotFound(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for a file being in the way + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #FileExists with the given @p message + */ + static TQT_DBusError stdFileExists(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for an unknown methods being called + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #UnknownMethod with the given @p message + */ + static TQT_DBusError stdUnknownMethod(const TQString& message); + + /** + * @brief Creates a D-Bus standard error for D-Bus type signature not valid + * + * @param message the message detailing the encountered problem + * + * @return an error object of type #InvalidSignature with the given @p message + */ + static TQT_DBusError stdInvalidSignature(const TQString& message); + +private: + ErrorType errorType; + mutable bool m_dbusErrorSet; + + TQString nm, msg; + + /** + * @brief Creates an error object for one of the standard D-Bus errors + * + * @param type one of the standard error causes + * @param message the potentially i18n'ed error description message + * + * @see ErrorType + */ + TQT_DBusError(ErrorType type, const TQString& message); +}; + +#endif diff --git a/src/tqdbusintegrator.cpp b/src/tqdbusintegrator.cpp new file mode 100644 index 0000000..c7129bd --- /dev/null +++ b/src/tqdbusintegrator.cpp @@ -0,0 +1,689 @@ +/* qdbusintegrator.cpp TQT_DBusConnection private implementation + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2005 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include "tqdbusconnection_p.h" +#include "tqdbusmessage.h" + +Atomic::Atomic(int value) : m_value(value) +{ +} + +void Atomic::ref() +{ + m_value++; +} + +bool Atomic::deref() +{ + m_value--; + return m_value > 0; +} + +int TQT_DBusConnectionPrivate::messageMetaType = 0; + +static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data) +{ + Q_ASSERT(timeout); + Q_ASSERT(data); + + // tqDebug("addTimeout %d", dbus_timeout_get_interval(timeout)); + + TQT_DBusConnectionPrivate *d = static_cast(data); + + if (!dbus_timeout_get_enabled(timeout)) + return true; + + if (!tqApp) { + d->pendingTimeouts.append(timeout); + return true; + } + int timerId = d->startTimer(dbus_timeout_get_interval(timeout)); + if (!timerId) + return false; + + d->timeouts[timerId] = timeout; + return true; +} + +static void qDBusRemoveTimeout(DBusTimeout *timeout, void *data) +{ + Q_ASSERT(timeout); + Q_ASSERT(data); + + // tqDebug("removeTimeout"); + + TQT_DBusConnectionPrivate *d = static_cast(data); + for (TQValueList::iterator it = d->pendingTimeouts.begin(); + it != d->pendingTimeouts.end();) { + if ((*it) == timeout) { + it = d->pendingTimeouts.erase(it); + } + else + ++it; + } + + TQT_DBusConnectionPrivate::TimeoutHash::iterator it = d->timeouts.begin(); + while (it != d->timeouts.end()) { + if (it.data() == timeout) { + d->killTimer(it.key()); + TQT_DBusConnectionPrivate::TimeoutHash::iterator copyIt = it; + ++it; + d->timeouts.erase(copyIt); + } else { + ++it; + } + } +} + +static void qDBusToggleTimeout(DBusTimeout *timeout, void *data) +{ + Q_ASSERT(timeout); + Q_ASSERT(data); + + //tqDebug("ToggleTimeout"); + + qDBusRemoveTimeout(timeout, data); + qDBusAddTimeout(timeout, data); +} + +static dbus_bool_t qDBusAddWatch(DBusWatch *watch, void *data) +{ + Q_ASSERT(watch); + Q_ASSERT(data); + + TQT_DBusConnectionPrivate *d = static_cast(data); + + int flags = dbus_watch_get_flags(watch); + int fd = dbus_watch_get_unix_fd(watch); + + TQT_DBusConnectionPrivate::Watcher watcher; + if (flags & DBUS_WATCH_READABLE) { + bool enabled = dbus_watch_get_enabled(watch); + //tqDebug("addReadWatch %d %s", fd, (enabled ? "enabled" : "disabled")); + watcher.watch = watch; + if (tqApp) { + watcher.read = new TQSocketNotifier(fd, TQSocketNotifier::Read, d); + if (!enabled) watcher.read->setEnabled(false); + d->connect(watcher.read, TQT_SIGNAL(activated(int)), TQT_SLOT(socketRead(int))); + } + } + if (flags & DBUS_WATCH_WRITABLE) { + bool enabled = dbus_watch_get_enabled(watch); + //tqDebug("addWriteWatch %d %s", fd, (enabled ? "enabled" : "disabled")); + watcher.watch = watch; + if (tqApp) { + watcher.write = new TQSocketNotifier(fd, TQSocketNotifier::Write, d); + if (!enabled) watcher.write->setEnabled(false); + d->connect(watcher.write, TQT_SIGNAL(activated(int)), TQT_SLOT(socketWrite(int))); + } + } + // FIXME-QT4 d->watchers.insertMulti(fd, watcher); + TQT_DBusConnectionPrivate::WatcherHash::iterator it = d->watchers.find(fd); + if (it == d->watchers.end()) + { + it = d->watchers.insert(fd, TQT_DBusConnectionPrivate::WatcherList()); + } + it.data().append(watcher); + + return true; +} + +static void qDBusRemoveWatch(DBusWatch *watch, void *data) +{ + Q_ASSERT(watch); + Q_ASSERT(data); + + //tqDebug("remove watch"); + + TQT_DBusConnectionPrivate *d = static_cast(data); + int fd = dbus_watch_get_unix_fd(watch); + + TQT_DBusConnectionPrivate::WatcherHash::iterator it = d->watchers.find(fd); + if (it != d->watchers.end()) + { + TQT_DBusConnectionPrivate::WatcherList& list = *it; + for (TQT_DBusConnectionPrivate::WatcherList::iterator wit = list.begin(); + wit != list.end(); ++wit) + { + if ((*wit).watch == watch) + { + // migth be called from a function triggered by a socket listener + // so just disconnect them and schedule their delayed deletion. + + d->removedWatches.append(*wit); + if ((*wit).read) + { + (*wit).read->disconnect(d); + (*wit).read = 0; + } + if ((*wit).write) + { + (*wit).write->disconnect(d); + (*wit).write = 0; + } + (*wit).watch = 0; + } + } + } + + if (d->removedWatches.count() > 0) + TQTimer::singleShot(0, d, TQT_SLOT(purgeRemovedWatches())); +} + +static void qDBusToggleWatch(DBusWatch *watch, void *data) +{ + Q_ASSERT(watch); + Q_ASSERT(data); + + //tqDebug("toggle watch"); + + TQT_DBusConnectionPrivate *d = static_cast(data); + int fd = dbus_watch_get_unix_fd(watch); + + TQT_DBusConnectionPrivate::WatcherHash::iterator it = d->watchers.find(fd); + if (it != d->watchers.end()) { + TQT_DBusConnectionPrivate::WatcherList& list = *it; + for (TQT_DBusConnectionPrivate::WatcherList::iterator wit = list.begin(); wit != list.end(); + ++wit) + { + if ((*wit).watch == watch) { + bool enabled = dbus_watch_get_enabled(watch); + int flags = dbus_watch_get_flags(watch); + +// tqDebug("toggle watch %d to %d (write: %d, read: %d)", +// dbus_watch_get_unix_fd(watch), enabled, +// flags & DBUS_WATCH_WRITABLE, flags & DBUS_WATCH_READABLE); + + if (flags & DBUS_WATCH_READABLE && (*wit).read) + (*wit).read->setEnabled(enabled); + if (flags & DBUS_WATCH_WRITABLE && (*wit).write) + (*wit).write->setEnabled(enabled); + return; + } + } + } +} + +static void qDBusNewConnection(DBusServer *server, DBusConnection *c, void *data) +{ + Q_ASSERT(data); Q_ASSERT(server); Q_ASSERT(c); + + tqDebug("SERVER: GOT A NEW CONNECTION"); // TODO +} + +static DBusHandlerResult qDBusSignalFilter(DBusConnection *connection, + DBusMessage *message, void *data) +{ + Q_ASSERT(data); + Q_UNUSED(connection); + + TQT_DBusConnectionPrivate *d = static_cast(data); + if (d->mode == TQT_DBusConnectionPrivate::InvalidMode) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + int msgType = dbus_message_get_type(message); + bool handled = false; + + //TQT_DBusMessage amsg = TQT_DBusMessage::fromDBusMessage(message); + //tqDebug() << "got message: " << dbus_message_get_type(message) << amsg; + + if (msgType == DBUS_MESSAGE_TYPE_SIGNAL) { + handled = d->handleSignal(message); + } else if (msgType == DBUS_MESSAGE_TYPE_METHOD_CALL) { + handled = d->handleObjectCall(message); + } + + return handled ? DBUS_HANDLER_RESULT_HANDLED : + DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +int TQT_DBusConnectionPrivate::registerMessageMetaType() +{ + // FIXME-QT4 int tp = messageMetaType = qRegisterMetaType("TQT_DBusMessage"); + int tp = 0; + return tp; +} + +TQT_DBusConnectionPrivate::TQT_DBusConnectionPrivate(TQObject *parent) + : TQObject(parent), ref(1), mode(InvalidMode), connection(0), server(0), + dispatcher(0), inDispatch(false) +{ + static const int msgType = registerMessageMetaType(); + Q_UNUSED(msgType); + + dbus_error_init(&error); + + dispatcher = new TQTimer(this); + TQObject::connect(dispatcher, TQT_SIGNAL(timeout()), this, TQT_SLOT(dispatch())); + + m_resultEmissionQueueTimer = new TQTimer(this); + TQObject::connect(m_resultEmissionQueueTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(transmitResultEmissionQueue())); + m_messageEmissionQueueTimer = new TQTimer(this); + TQObject::connect(m_messageEmissionQueueTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(transmitMessageEmissionQueue())); +} + +TQT_DBusConnectionPrivate::~TQT_DBusConnectionPrivate() +{ + for (PendingCallMap::iterator it = pendingCalls.begin(); it != pendingCalls.end();) + { + PendingCallMap::iterator copyIt = it; + ++it; + dbus_pending_call_cancel(copyIt.key()); + dbus_pending_call_unref(copyIt.key()); + delete copyIt.data(); + pendingCalls.erase(copyIt); + } + + if (dbus_error_is_set(&error)) + dbus_error_free(&error); + + closeConnection(); +} + +void TQT_DBusConnectionPrivate::closeConnection() +{ + ConnectionMode oldMode = mode; + mode = InvalidMode; // prevent reentrancy + if (oldMode == ServerMode) { + if (server) { + dbus_server_disconnect(server); + dbus_server_unref(server); + server = 0; + } + } else if (oldMode == ClientMode) { + if (connection) { + // closing shared connections is forbidden +#if 0 + dbus_connection_close(connection); + // send the "close" message + while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS); +#endif + dbus_connection_unref(connection); + connection = 0; + } + } +} + +bool TQT_DBusConnectionPrivate::handleError() +{ + lastError = TQT_DBusError(&error); + if (dbus_error_is_set(&error)) + dbus_error_free(&error); + return lastError.isValid(); +} + +void TQT_DBusConnectionPrivate::emitPendingCallReply(const TQT_DBusMessage& message) +{ + emit dbusPendingCallReply(message); +} + +void TQT_DBusConnectionPrivate::bindToApplication() +{ + // Yay, now that we have an application we are in business + // Re-add all watchers + WatcherHash oldWatchers = watchers; + watchers.clear(); + // FIXME-QT4 TQHashIterator it(oldWatchers); + for (WatcherHash::const_iterator it = oldWatchers.begin(); it != oldWatchers.end(); ++it) + { + const WatcherList& list = *it; + for (WatcherList::const_iterator wit = list.begin(); wit != list.end(); ++wit) + { + if (!(*wit).read && !(*wit).write) { + qDBusAddWatch((*wit).watch, this); + } + } + } + + // Re-add all timeouts + while (!pendingTimeouts.isEmpty()) { + qDBusAddTimeout(pendingTimeouts.first(), this); + pendingTimeouts.pop_front(); + } +} + +void TQT_DBusConnectionPrivate::socketRead(int fd) +{ + // FIXME-QT4 TQHashIterator it(watchers); + WatcherHash::const_iterator it = watchers.find(fd); + if (it != watchers.end()) { + const WatcherList& list = *it; + for (WatcherList::const_iterator wit = list.begin(); wit != list.end(); ++wit) { + if ((*wit).read && (*wit).read->isEnabled()) { + if (!dbus_watch_handle((*wit).watch, DBUS_WATCH_READABLE)) + tqDebug("OUT OF MEM"); + } + } + } + if (mode == ClientMode) + scheduleDispatch(); +} + +void TQT_DBusConnectionPrivate::socketWrite(int fd) +{ + // FIXME-QT4 TQHashIterator it(watchers); + WatcherHash::const_iterator it = watchers.find(fd); + if (it != watchers.end()) { + const WatcherList& list = *it; + for (WatcherList::const_iterator wit = list.begin(); wit != list.end(); ++wit) { + if ((*wit).write && (*wit).write->isEnabled()) { + if (!dbus_watch_handle((*wit).watch, DBUS_WATCH_WRITABLE)) + tqDebug("OUT OF MEM"); + } + } + } +} + +void TQT_DBusConnectionPrivate::objectDestroyed(TQObject* object) +{ + //tqDebug("Object destroyed"); + for (PendingCallMap::iterator it = pendingCalls.begin(); it != pendingCalls.end();) + { + TQObject* receiver = (TQObject*) it.data()->receiver; + if (receiver == object || receiver == 0) + { + PendingCallMap::iterator copyIt = it; + ++it; + + dbus_pending_call_cancel(copyIt.key()); + dbus_pending_call_unref(copyIt.key()); + delete copyIt.data(); + pendingCalls.erase(copyIt); + } + else + ++it; + } +} + +void TQT_DBusConnectionPrivate::purgeRemovedWatches() +{ + if (removedWatches.isEmpty()) return; + + WatcherList::iterator listIt = removedWatches.begin(); + for (; listIt != removedWatches.end(); ++listIt) + { + delete (*listIt).read; + delete (*listIt).write; + } + removedWatches.clear(); + + uint count = 0; + WatcherHash::iterator it = watchers.begin(); + while (it != watchers.end()) + { + WatcherList& list = *it; + listIt = list.begin(); + while (listIt != list.end()) + { + if (!((*listIt).read) && !((*listIt).write)) + { + listIt = list.erase(listIt); + ++count; + } + } + + if (list.isEmpty()) + { + WatcherHash::iterator copyIt = it; + ++it; + watchers.erase(copyIt); + } + else + ++it; + } +} + +void TQT_DBusConnectionPrivate::scheduleDispatch() +{ + dispatcher->start(0); +} + +void TQT_DBusConnectionPrivate::dispatch() +{ + // dbus_connection_dispatch will hang if called recursively + if (inDispatch) { + printf("[dbus-1-tqt] WARNING: Attempt to call dispatch() recursively was silently ignored to prevent lockup!\n\r"); fflush(stdout); + return; + } + inDispatch = true; + + if (mode == ClientMode) + { + if (dbus_connection_dispatch(connection) != DBUS_DISPATCH_DATA_REMAINS) + { + // stop dispatch timer + dispatcher->stop(); + } + } + + inDispatch = false; +} + +void TQT_DBusConnectionPrivate::transmitMessageEmissionQueue() +{ + TQT_DBusConnectionPrivate::PendingMessagesForEmit::iterator pmfe; + pmfe = pendingMessages.begin(); + while (pmfe != pendingMessages.end()) { + TQT_DBusMessage msg = *pmfe; + pmfe = pendingMessages.remove(pmfe); + dbusSignal(msg); + } +} + +bool TQT_DBusConnectionPrivate::handleObjectCall(DBusMessage *message) +{ + TQT_DBusMessage msg = TQT_DBusMessage::fromDBusMessage(message); + + ObjectMap::iterator it = registeredObjects.find(msg.path()); + if (it == registeredObjects.end()) + return false; + + return it.data()->handleMethodCall(msg); +} + +bool TQT_DBusConnectionPrivate::handleSignal(DBusMessage *message) +{ + TQT_DBusMessage msg = TQT_DBusMessage::fromDBusMessage(message); + + // yes, it is a single "|" below... + // FIXME-QT4 + //return handleSignal(TQString(), msg) | handleSignal(msg.path(), msg); + + // If dbusSignal(msg) were called here, it could easily cause a lockup as it would enter the TQt3 event loop, + // which could result in arbitrary methods being called while still inside dbus_connection_dispatch. + // Instead, I enqueue the messages here for TQt3 event loop transmission after dbus_connection_dispatch is finished. + pendingMessages.append(msg); + if (!m_messageEmissionQueueTimer->isActive()) m_messageEmissionQueueTimer->start(0, TRUE); + + return true; +} + +static dbus_int32_t server_slot = -1; + +void TQT_DBusConnectionPrivate::setServer(DBusServer *s) +{ + if (!server) { + handleError(); + return; + } + + server = s; + mode = ServerMode; + + dbus_server_allocate_data_slot(&server_slot); + if (server_slot < 0) + return; + + dbus_server_set_watch_functions(server, qDBusAddWatch, qDBusRemoveWatch, + qDBusToggleWatch, this, 0); // ### check return type? + dbus_server_set_timeout_functions(server, qDBusAddTimeout, qDBusRemoveTimeout, + qDBusToggleTimeout, this, 0); + dbus_server_set_new_connection_function(server, qDBusNewConnection, this, 0); + + dbus_server_set_data(server, server_slot, this, 0); +} + +void TQT_DBusConnectionPrivate::setConnection(DBusConnection *dbc) +{ + if (!dbc) { + handleError(); + return; + } + + connection = dbc; + mode = ClientMode; + + dbus_connection_set_exit_on_disconnect(connection, false); + dbus_connection_set_watch_functions(connection, qDBusAddWatch, qDBusRemoveWatch, + qDBusToggleWatch, this, 0); + dbus_connection_set_timeout_functions(connection, qDBusAddTimeout, qDBusRemoveTimeout, + qDBusToggleTimeout, this, 0); +// dbus_bus_add_match(connection, "type='signal',interface='com.trolltech.dbus.Signal'", &error); +// dbus_bus_add_match(connection, "type='signal'", &error); + + dbus_bus_add_match(connection, "type='signal'", &error); + if (handleError()) { + closeConnection(); + return; + } + + const char *service = dbus_bus_get_unique_name(connection); + if (service) { + TQCString filter; + filter += "destination='"; + filter += service; + filter += "\'"; + + dbus_bus_add_match(connection, filter.data(), &error); + if (handleError()) { + closeConnection(); + return; + } + } else { + tqWarning("TQT_DBusConnectionPrivate::SetConnection: Unable to get unique name"); + } + + dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0); + + //tqDebug("unique name: %s", service); +} + +static void qDBusResultReceived(DBusPendingCall *pending, void *user_data) +{ + //tqDebug("Pending Call Result received"); + TQT_DBusConnectionPrivate* d = reinterpret_cast(user_data); + TQT_DBusConnectionPrivate::PendingCallMap::iterator it = d->pendingCalls.find(pending); + + DBusMessage *dbusReply = dbus_pending_call_steal_reply(pending); + + dbus_set_error_from_message(&d->error, dbusReply); + d->handleError(); + + if (it != d->pendingCalls.end()) + { + TQT_DBusMessage reply = TQT_DBusMessage::fromDBusMessage(dbusReply); + + TQT_DBusResultInfo dbusResult; + dbusResult.message = reply; + dbusResult.receiver = it.data()->receiver; + dbusResult.method = it.data()->method.data(); + d->m_resultEmissionQueue.append(dbusResult); + d->newMethodInResultEmissionQueue(); + } + + dbus_message_unref(dbusReply); + dbus_pending_call_unref(pending); + delete it.data(); + + d->pendingCalls.erase(it); +} + +int TQT_DBusConnectionPrivate::sendWithReplyAsync(const TQT_DBusMessage &message, TQObject *receiver, + const char *method) +{ + if (!receiver || !method) + return 0; + + if (!TQObject::connect(receiver, TQT_SIGNAL(destroyed(TQObject*)), + this, TQT_SLOT(objectDestroyed(TQObject*)))) + return false; + + DBusMessage *msg = message.toDBusMessage(); + if (!msg) + return 0; + + int msg_serial = 0; + DBusPendingCall *pending = 0; + if (dbus_connection_send_with_reply(connection, msg, &pending, message.timeout())) { + TQT_DBusPendingCall *pcall = new TQT_DBusPendingCall; + pcall->receiver = receiver; + pcall->method = method; + pcall->pending = pending; + pendingCalls.insert(pcall->pending, pcall); + + dbus_pending_call_set_notify(pending, qDBusResultReceived, this, 0); + + msg_serial = dbus_message_get_serial(msg); + } + + dbus_message_unref(msg); + return msg_serial; +} + +void TQT_DBusConnectionPrivate::flush() +{ + if (!connection) return; + + dbus_connection_flush(connection); +} + +void TQT_DBusConnectionPrivate::newMethodInResultEmissionQueue() +{ + if (!m_resultEmissionQueueTimer->isActive()) m_resultEmissionQueueTimer->start(0, TRUE); +} + +void TQT_DBusConnectionPrivate::transmitResultEmissionQueue() +{ + if (!m_resultEmissionQueue.isEmpty()) { + TQT_DBusResultInfoList::Iterator it; + it = m_resultEmissionQueue.begin(); + while (it != m_resultEmissionQueue.end()) { + TQT_DBusResultInfo dbusResult = (*it); + m_resultEmissionQueue.remove(it); + it = m_resultEmissionQueue.begin(); + + TQObject::connect(this, TQT_SIGNAL(dbusPendingCallReply(const TQT_DBusMessage&)), dbusResult.receiver, dbusResult.method.data()); + emitPendingCallReply(dbusResult.message); + TQObject::disconnect(this, TQT_SIGNAL(dbusPendingCallReply(const TQT_DBusMessage&)), dbusResult.receiver, dbusResult.method.data()); + } + } +} + +#include "tqdbusconnection_p.moc" diff --git a/src/tqdbusmacros.h b/src/tqdbusmacros.h new file mode 100644 index 0000000..2470094 --- /dev/null +++ b/src/tqdbusmacros.h @@ -0,0 +1,31 @@ +/* qdbusmacros TQDBUS macro definitions + * + * Copyright (C) 2005 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSMACROS_H +#define TQDBUSMACROS_H + +#include + +#define TQDBUS_EXPORT TQ_EXPORT + +#endif diff --git a/src/tqdbusmarshall.cpp b/src/tqdbusmarshall.cpp new file mode 100644 index 0000000..7f0781f --- /dev/null +++ b/src/tqdbusmarshall.cpp @@ -0,0 +1,1254 @@ +/* qdbusmarshall.cpp + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include "tqdbusmarshall.h" +#include "tqdbusdata.h" +#include "tqdbusdatalist.h" +#include "tqdbusdatamap.h" +#include "tqdbusobjectpath.h" +#include "tqdbusunixfd.h" +#include "tqdbusvariant.h" + +#include +#include +#include +#include +#include + +#include + +template +inline T qIterGet(DBusMessageIter *it) +{ + T t; + dbus_message_iter_get_basic(it, &t); + return t; +} + +static TQT_DBusData::Type qSingleTypeForDBusSignature(char signature) +{ + switch (signature) + { + case 'b': return TQT_DBusData::Bool; + case 'y': return TQT_DBusData::Byte; + case 'n': return TQT_DBusData::Int16; + case 'q': return TQT_DBusData::UInt16; + case 'i': return TQT_DBusData::Int32; + case 'u': return TQT_DBusData::UInt32; + case 'x': return TQT_DBusData::Int64; + case 't': return TQT_DBusData::UInt64; + case 'd': return TQT_DBusData::Double; + case 's': return TQT_DBusData::String; + case 'o': return TQT_DBusData::ObjectPath; + case 'g': return TQT_DBusData::String; + case 'v': return TQT_DBusData::Variant; + case 'h': return TQT_DBusData::UnixFd; + + default: + break; + } + + return TQT_DBusData::Invalid; +} + +static TQValueList parseSignature(TQCString& signature) +{ +// tqDebug("parseSignature(%s)", signature.data()); + TQValueList result; + + while (!signature.isEmpty()) + { + switch (signature[0]) + { + case '(': { + signature = signature.mid(1); + TQValueList memberList = parseSignature(signature); + result << TQT_DBusData::fromStruct(memberList); + Q_ASSERT(!signature.isEmpty() && signature[0] == ')'); + signature = signature.mid(1); + break; + } + case ')': return result; + case '{': { + TQT_DBusData::Type keyType = + qSingleTypeForDBusSignature(signature[1]); + TQT_DBusData::Type valueType = + qSingleTypeForDBusSignature(signature[2]); + if (valueType != TQT_DBusData::Invalid) + { + switch (keyType) + { + case TQT_DBusData::Byte: + result << TQT_DBusData::fromByteKeyMap( + TQT_DBusDataMap(valueType)); + break; + case TQT_DBusData::Int16: + result << TQT_DBusData::fromInt16KeyMap( + TQT_DBusDataMap(valueType)); + break; + case TQT_DBusData::UInt16: + result << TQT_DBusData::fromUInt16KeyMap( + TQT_DBusDataMap(valueType)); + break; + case TQT_DBusData::Int32: + result << TQT_DBusData::fromInt32KeyMap( + TQT_DBusDataMap(valueType)); + break; + case TQT_DBusData::UInt32: + result << TQT_DBusData::fromUInt32KeyMap( + TQT_DBusDataMap(valueType)); + break; + case TQT_DBusData::Int64: + result << TQT_DBusData::fromInt64KeyMap( + TQT_DBusDataMap(valueType)); + break; + case TQT_DBusData::UInt64: + result << TQT_DBusData::fromUInt64KeyMap( + TQT_DBusDataMap(valueType)); + break; + case TQT_DBusData::String: + result << TQT_DBusData::fromStringKeyMap( + TQT_DBusDataMap(valueType)); + break; + case TQT_DBusData::ObjectPath: + result << TQT_DBusData::fromObjectPathKeyMap( + TQT_DBusDataMap(valueType)); + break; + case TQT_DBusData::UnixFd: + result << TQT_DBusData::fromUnixFdKeyMap( + TQT_DBusDataMap(valueType)); + break; + default: + tqWarning("TQT_DBusMarshall: unsupported map key type %s " + "at de-marshalling", + TQT_DBusData::typeName(keyType)); + break; + } + signature = signature.mid(3); + } + else + { + signature = signature.mid(2); + TQValueList valueContainer = + parseSignature(signature); + Q_ASSERT(valueContainer.count() == 1); + + switch (keyType) + { + case TQT_DBusData::Byte: + result << TQT_DBusData::fromByteKeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + case TQT_DBusData::Int16: + result << TQT_DBusData::fromInt16KeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + case TQT_DBusData::UInt16: + result << TQT_DBusData::fromUInt16KeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + case TQT_DBusData::Int32: + result << TQT_DBusData::fromInt32KeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + case TQT_DBusData::UInt32: + result << TQT_DBusData::fromUInt32KeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + case TQT_DBusData::Int64: + result << TQT_DBusData::fromInt64KeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + case TQT_DBusData::UInt64: + result << TQT_DBusData::fromUInt64KeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + case TQT_DBusData::String: + result << TQT_DBusData::fromStringKeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + case TQT_DBusData::ObjectPath: + result << TQT_DBusData::fromObjectPathKeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + case TQT_DBusData::UnixFd: + result << TQT_DBusData::fromUnixFdKeyMap( + TQT_DBusDataMap(valueContainer[0])); + break; + default: + tqWarning("TQT_DBusMarshall: unsupported map key type %s " + "at de-marshalling", + TQT_DBusData::typeName(keyType)); + break; + } + } + Q_ASSERT(!signature.isEmpty() && signature[0] == '}'); + signature = signature.mid(1); + break; + } + case '}': return result; + case 'a': { + TQT_DBusData::Type elementType = + qSingleTypeForDBusSignature(signature[1]); + if (elementType != TQT_DBusData::Invalid) + { + TQT_DBusDataList list(elementType); + result << TQT_DBusData::fromList(list); + signature = signature.mid(2); + } + else + { + signature = signature.mid(1); + bool array = signature[0] != '{'; + + TQValueList elementContainer = + parseSignature(signature); + Q_ASSERT(elementContainer.count() == 1); + + if (array) + { + TQT_DBusDataList list(elementContainer[0]); + result << TQT_DBusData::fromList(list); + } + else + result << elementContainer[0]; + } + break; + } + default: + TQT_DBusData::Type elementType = + qSingleTypeForDBusSignature(signature[0]); + if (elementType != TQT_DBusData::Invalid) + { + switch (elementType) + { + case TQT_DBusData::Bool: + result << TQT_DBusData::fromBool( + (0)); + break; + case TQT_DBusData::Byte: + result << TQT_DBusData::fromByte( + (0)); + break; + case TQT_DBusData::Int16: + result << TQT_DBusData::fromInt16( + (0)); + break; + case TQT_DBusData::UInt16: + result << TQT_DBusData::fromUInt16( + (0)); + break; + case TQT_DBusData::Int32: + result << TQT_DBusData::fromInt32( + (0)); + break; + case TQT_DBusData::UInt32: + result << TQT_DBusData::fromUInt32( + (0)); + break; + case TQT_DBusData::Int64: + result << TQT_DBusData::fromInt64( + (0)); + break; + case TQT_DBusData::UInt64: + result << TQT_DBusData::fromUInt64( + (0)); + break; + case TQT_DBusData::String: + result << TQT_DBusData::fromString( + (TQString())); + break; + case TQT_DBusData::ObjectPath: + result << TQT_DBusData::fromObjectPath( + (TQT_DBusObjectPath())); + break; + case TQT_DBusData::UnixFd: + result << TQT_DBusData::fromUnixFd( + (TQT_DBusUnixFd())); + break; + default: + result << TQT_DBusData(); + tqWarning("TQT_DBusMarshall: unsupported element type %s " + "at de-marshalling", + TQT_DBusData::typeName(elementType)); + break; + } + signature = signature.mid(1); + } + else { + result << TQT_DBusData(); + signature = signature.mid(1); + } + break; + } + } + + return result; +} + +static TQT_DBusData qFetchParameter(DBusMessageIter *it); + +void qFetchByteKeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) +{ + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + Q_ASSERT(dbus_message_iter_has_next(&itemIter)); + + TQ_UINT8 key = qFetchParameter(&itemIter).toByte(); + + dbus_message_iter_next(&itemIter); + + map.insert(key, qFetchParameter(&itemIter)); +} + +void qFetchInt16KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) +{ + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + Q_ASSERT(dbus_message_iter_has_next(&itemIter)); + + TQ_INT16 key = qFetchParameter(&itemIter).toInt16(); + + dbus_message_iter_next(&itemIter); + + map.insert(key, qFetchParameter(&itemIter)); +} + +void qFetchUInt16KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) +{ + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + Q_ASSERT(dbus_message_iter_has_next(&itemIter)); + + TQ_UINT16 key = qFetchParameter(&itemIter).toUInt16(); + + dbus_message_iter_next(&itemIter); + + map.insert(key, qFetchParameter(&itemIter)); +} + +void qFetchInt32KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) +{ + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + Q_ASSERT(dbus_message_iter_has_next(&itemIter)); + + TQ_INT32 key = qFetchParameter(&itemIter).toInt32(); + + dbus_message_iter_next(&itemIter); + + map.insert(key, qFetchParameter(&itemIter)); +} + +void qFetchUInt32KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) +{ + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + Q_ASSERT(dbus_message_iter_has_next(&itemIter)); + + TQ_UINT32 key = qFetchParameter(&itemIter).toUInt32(); + + dbus_message_iter_next(&itemIter); + + map.insert(key, qFetchParameter(&itemIter)); +} + +void qFetchInt64KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) +{ + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + Q_ASSERT(dbus_message_iter_has_next(&itemIter)); + + TQ_INT64 key = qFetchParameter(&itemIter).toInt64(); + + dbus_message_iter_next(&itemIter); + + map.insert(key, qFetchParameter(&itemIter)); +} + +void qFetchUInt64KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) +{ + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + Q_ASSERT(dbus_message_iter_has_next(&itemIter)); + + TQ_UINT64 key = qFetchParameter(&itemIter).toUInt64(); + + dbus_message_iter_next(&itemIter); + + map.insert(key, qFetchParameter(&itemIter)); +} + +void qFetchObjectPathKeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) +{ + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + Q_ASSERT(dbus_message_iter_has_next(&itemIter)); + + TQT_DBusObjectPath key = qFetchParameter(&itemIter).toObjectPath(); + + dbus_message_iter_next(&itemIter); + + map.insert(key, qFetchParameter(&itemIter)); +} + +void qFetchStringKeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) +{ + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + Q_ASSERT(dbus_message_iter_has_next(&itemIter)); + + TQString key = qFetchParameter(&itemIter).toString(); + + dbus_message_iter_next(&itemIter); + + map.insert(key, qFetchParameter(&itemIter)); +} + +static TQT_DBusData qFetchMap(DBusMessageIter *it, const TQT_DBusData& prototype) +{ + if (dbus_message_iter_get_arg_type(it) == DBUS_TYPE_INVALID) + return prototype; + + DBusMessageIter itemIter; + dbus_message_iter_recurse(it, &itemIter); + if (dbus_message_iter_get_arg_type(&itemIter) == DBUS_TYPE_INVALID) + return prototype; + + switch (dbus_message_iter_get_arg_type(&itemIter)) { + case DBUS_TYPE_BYTE: { + TQT_DBusDataMap map = prototype.toByteKeyMap(); + do { + qFetchByteKeyMapEntry(map, it); + } while (dbus_message_iter_next(it)); + + return TQT_DBusData::fromByteKeyMap(map); + } + + case DBUS_TYPE_INT16: { + TQT_DBusDataMap map = prototype.toInt16KeyMap(); + do { + qFetchInt16KeyMapEntry(map, it); + } while (dbus_message_iter_next(it)); + + return TQT_DBusData::fromInt16KeyMap(map); + } + + case DBUS_TYPE_UINT16: { + TQT_DBusDataMap map = prototype.toUInt16KeyMap(); + do { + qFetchUInt16KeyMapEntry(map, it); + } while (dbus_message_iter_next(it)); + + return TQT_DBusData::fromUInt16KeyMap(map); + } + + case DBUS_TYPE_INT32: { + TQT_DBusDataMap map = prototype.toInt32KeyMap(); + do { + qFetchInt32KeyMapEntry(map, it); + } while (dbus_message_iter_next(it)); + + return TQT_DBusData::fromInt32KeyMap(map); + } + + case DBUS_TYPE_UINT32: { + TQT_DBusDataMap map = prototype.toUInt32KeyMap(); + do { + qFetchUInt32KeyMapEntry(map, it); + } while (dbus_message_iter_next(it)); + + return TQT_DBusData::fromUInt32KeyMap(map); + } + + case DBUS_TYPE_INT64: { + TQT_DBusDataMap map = prototype.toInt64KeyMap(); + do { + qFetchInt64KeyMapEntry(map, it); + } while (dbus_message_iter_next(it)); + + return TQT_DBusData::fromInt64KeyMap(map); + } + + case DBUS_TYPE_UINT64: { + TQT_DBusDataMap map = prototype.toUInt64KeyMap(); + do { + qFetchUInt64KeyMapEntry(map, it); + } while (dbus_message_iter_next(it)); + + return TQT_DBusData::fromUInt64KeyMap(map); + } + + case DBUS_TYPE_OBJECT_PATH: { + TQT_DBusDataMap map = prototype.toObjectPathKeyMap(); + do { + qFetchObjectPathKeyMapEntry(map, it); + } while (dbus_message_iter_next(it)); + + return TQT_DBusData::fromObjectPathKeyMap(map); + } + case DBUS_TYPE_STRING: // fall through + case DBUS_TYPE_SIGNATURE: { + TQT_DBusDataMap map = prototype.toStringKeyMap(); + do { + qFetchStringKeyMapEntry(map, it); + } while (dbus_message_iter_next(it)); + + return TQT_DBusData::fromStringKeyMap(map); + } + + default: + break; + } + + return prototype; +} + +static TQT_DBusData qFetchParameter(DBusMessageIter *it) +{ + switch (dbus_message_iter_get_arg_type(it)) { + case DBUS_TYPE_BOOLEAN: + return TQT_DBusData::fromBool(qIterGet(it)); + case DBUS_TYPE_BYTE: + return TQT_DBusData::fromByte(qIterGet(it)); + case DBUS_TYPE_INT16: + return TQT_DBusData::fromInt16(qIterGet(it)); + case DBUS_TYPE_UINT16: + return TQT_DBusData::fromUInt16(qIterGet(it)); + case DBUS_TYPE_INT32: + return TQT_DBusData::fromInt32(qIterGet(it)); + case DBUS_TYPE_UINT32: + return TQT_DBusData::fromUInt32(qIterGet(it)); + case DBUS_TYPE_INT64: + return TQT_DBusData::fromInt64(qIterGet(it)); + case DBUS_TYPE_UINT64: + return TQT_DBusData::fromUInt64(qIterGet(it)); + case DBUS_TYPE_DOUBLE: + return TQT_DBusData::fromDouble(qIterGet(it)); + case DBUS_TYPE_STRING: + case DBUS_TYPE_SIGNATURE: + return TQT_DBusData::fromString(TQString::fromUtf8(qIterGet(it))); + case DBUS_TYPE_OBJECT_PATH: + return TQT_DBusData::fromObjectPath(TQT_DBusObjectPath(qIterGet(it))); + case DBUS_TYPE_ARRAY: { + int arrayType = dbus_message_iter_get_element_type(it); + + char* sig = dbus_message_iter_get_signature(it); + TQCString signature = sig; + dbus_free(sig); + + TQValueList prototypeList = parseSignature(signature); + + if (arrayType == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter sub; + dbus_message_iter_recurse(it, &sub); + + return qFetchMap(&sub, prototypeList[0]); + } else { + TQT_DBusDataList list = prototypeList[0].toList(); + + DBusMessageIter arrayIt; + dbus_message_iter_recurse(it, &arrayIt); + + while (dbus_message_iter_get_arg_type(&arrayIt) != DBUS_TYPE_INVALID) { + list << qFetchParameter(&arrayIt); + + dbus_message_iter_next(&arrayIt); + } + + return TQT_DBusData::fromList(list); + } + } + case DBUS_TYPE_VARIANT: { + TQT_DBusVariant dvariant; + DBusMessageIter sub; + dbus_message_iter_recurse(it, &sub); + + char* signature = dbus_message_iter_get_signature(&sub); + dvariant.signature = TQString::fromUtf8(signature); + dbus_free(signature); + + dvariant.value = qFetchParameter(&sub); + + return TQT_DBusData::fromVariant(dvariant); + } + case DBUS_TYPE_STRUCT: { + TQValueList memberList; + + DBusMessageIter subIt; + dbus_message_iter_recurse(it, &subIt); + + uint index = 0; + while (dbus_message_iter_get_arg_type(&subIt) != DBUS_TYPE_INVALID) { + memberList << qFetchParameter(&subIt); + + dbus_message_iter_next(&subIt); + ++index; + } + + return TQT_DBusData::fromStruct(memberList); + } + case DBUS_TYPE_UNIX_FD: { + TQT_DBusUnixFd unixFd; + unixFd.giveFileDescriptor(qIterGet(it)); + return TQT_DBusData::fromUnixFd(unixFd); + } +#if 0 + case DBUS_TYPE_INVALID: + // TODO: check if there is better way to detect empty arrays + return TQT_DBusData(); + break; +#endif + default: + tqWarning("TQT_DBusMarshall: Don't know how to de-marshall type %d '%c'", + dbus_message_iter_get_arg_type(it), + dbus_message_iter_get_arg_type(it)); + return TQT_DBusData(); + break; + } +} + +void TQT_DBusMarshall::messageToList(TQValueList& list, DBusMessage* message) +{ + Q_ASSERT(message); + + DBusMessageIter it; + if (!dbus_message_iter_init(message, &it)) return; + + do + { + list << qFetchParameter(&it); + } + while (dbus_message_iter_next(&it)); +} + +static void tqAppendToMessage(DBusMessageIter *it, const TQString &str) +{ + TQByteArray ba = str.utf8(); + const char *cdata = ba.data(); + dbus_message_iter_append_basic(it, DBUS_TYPE_STRING, &cdata); +} + +static void tqAppendToMessage(DBusMessageIter *it, const TQT_DBusObjectPath &path) +{ + const char *cdata = path.data(); + dbus_message_iter_append_basic(it, DBUS_TYPE_OBJECT_PATH, &cdata); +} + +static void tqAppendToMessage(DBusMessageIter *it, const TQT_DBusUnixFd &unixFd) +{ + const dbus_int32_t cdata = unixFd.fileDescriptor(); + dbus_message_iter_append_basic(it, DBUS_TYPE_UNIX_FD, &cdata); +} + +static const char* qDBusTypeForTQT_DBusType(TQT_DBusData::Type type) +{ + switch (type) + { + case TQT_DBusData::Invalid: + return 0; + + case TQT_DBusData::Bool: + return DBUS_TYPE_BOOLEAN_AS_STRING; + + case TQT_DBusData::Byte: + return DBUS_TYPE_BYTE_AS_STRING; + + case TQT_DBusData::Int16: + return DBUS_TYPE_INT16_AS_STRING; + + case TQT_DBusData::UInt16: + return DBUS_TYPE_UINT16_AS_STRING; + + case TQT_DBusData::Int32: + return DBUS_TYPE_INT32_AS_STRING; + + case TQT_DBusData::UInt32: + return DBUS_TYPE_UINT32_AS_STRING; + + case TQT_DBusData::Int64: + return DBUS_TYPE_INT64_AS_STRING; + + case TQT_DBusData::UInt64: + return DBUS_TYPE_UINT64_AS_STRING; + + case TQT_DBusData::Double: + return DBUS_TYPE_DOUBLE_AS_STRING; + + case TQT_DBusData::String: + return DBUS_TYPE_STRING_AS_STRING; + + case TQT_DBusData::ObjectPath: + return DBUS_TYPE_OBJECT_PATH_AS_STRING; + + case TQT_DBusData::List: + return DBUS_TYPE_ARRAY_AS_STRING; + + case TQT_DBusData::Struct: + return DBUS_TYPE_STRUCT_AS_STRING; + + case TQT_DBusData::Variant: + return DBUS_TYPE_VARIANT_AS_STRING; + + case TQT_DBusData::Map: + return DBUS_TYPE_DICT_ENTRY_AS_STRING; + + case TQT_DBusData::UnixFd: + return DBUS_TYPE_UNIX_FD_AS_STRING; + } + return 0; +} + +static void qDBusDataToIterator(DBusMessageIter* it, const TQT_DBusData& var); + +static void qDBusByteKeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toByteKeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + dbus_message_iter_append_basic(it, DBUS_TYPE_BYTE, &(mit.key())); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusInt16KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toInt16KeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + dbus_message_iter_append_basic(it, DBUS_TYPE_INT16, &(mit.key())); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusUInt16KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toUInt16KeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + dbus_message_iter_append_basic(it, DBUS_TYPE_UINT16, &(mit.key())); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusInt32KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toInt32KeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + dbus_message_iter_append_basic(it, DBUS_TYPE_INT32, &(mit.key())); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusUInt32KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toUInt32KeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + dbus_message_iter_append_basic(it, DBUS_TYPE_UINT32, &(mit.key())); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusInt64KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toInt64KeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + dbus_message_iter_append_basic(it, DBUS_TYPE_INT64, &(mit.key())); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusUInt64KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toUInt64KeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + dbus_message_iter_append_basic(it, DBUS_TYPE_UINT64, &(mit.key())); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusStringKeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toStringKeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + tqAppendToMessage(&itemIterator, mit.key()); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusObjectPathKeyMapToIterator(DBusMessageIter* it, + const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toObjectPathKeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + tqAppendToMessage(&itemIterator, mit.key()); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusUnixFdKeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + DBusMessageIter sub; + TQCString sig; + + TQT_DBusDataMap map = var.toUnixFdKeyMap(); + + sig += DBUS_DICT_ENTRY_BEGIN_CHAR; + sig += qDBusTypeForTQT_DBusType(map.keyType()); + + if (map.hasContainerValueType()) + sig += map.containerValueType().buildDBusSignature(); + else + sig += qDBusTypeForTQT_DBusType(map.valueType()); + sig += DBUS_DICT_ENTRY_END_CHAR; + + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); + + TQT_DBusDataMap::const_iterator mit = map.begin(); + for (; mit != map.end(); ++mit) + { + DBusMessageIter itemIterator; + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, + 0, &itemIterator); + + dbus_message_iter_append_basic(it, DBUS_TYPE_UNIX_FD, &(mit.key())); + qDBusDataToIterator(&itemIterator, mit.data()); + + dbus_message_iter_close_container(&sub, &itemIterator); + } + + dbus_message_iter_close_container(it, &sub); +} + +static void qDBusDataToIterator(DBusMessageIter* it, const TQT_DBusData& var) +{ + switch (var.type()) + { + case TQT_DBusData::Bool: + { + dbus_bool_t value = var.toBool(); + dbus_message_iter_append_basic(it, DBUS_TYPE_BOOLEAN, &value); + break; + } + case TQT_DBusData::Byte: + { + TQ_UINT8 value = var.toByte(); + dbus_message_iter_append_basic(it, DBUS_TYPE_BYTE, &value); + break; + } + case TQT_DBusData::Int16: { + TQ_INT16 value = var.toInt16(); + dbus_message_iter_append_basic(it, DBUS_TYPE_INT16, &value); + break; + } + case TQT_DBusData::UInt16: { + TQ_UINT16 value = var.toUInt16(); + dbus_message_iter_append_basic(it, DBUS_TYPE_UINT16, &value); + break; + } + case TQT_DBusData::Int32: { + TQ_INT32 value = var.toInt32(); + dbus_message_iter_append_basic(it, DBUS_TYPE_INT32, &value); + break; + } + case TQT_DBusData::UInt32: { + TQ_UINT32 value = var.toUInt32(); + dbus_message_iter_append_basic(it, DBUS_TYPE_UINT32, &value); + break; + } + case TQT_DBusData::Int64: { + TQ_INT64 value = var.toInt64(); + dbus_message_iter_append_basic(it, DBUS_TYPE_INT64, &value); + break; + } + case TQT_DBusData::UInt64: { + TQ_UINT64 value = var.toUInt64(); + dbus_message_iter_append_basic(it, DBUS_TYPE_UINT64, &value); + break; + } + case TQT_DBusData::Double: { + double value = var.toDouble(); + dbus_message_iter_append_basic(it, DBUS_TYPE_DOUBLE, &value); + break; + } + case TQT_DBusData::String: + tqAppendToMessage(it, var.toString()); + break; + case TQT_DBusData::ObjectPath: + tqAppendToMessage(it, var.toObjectPath()); + break; + case TQT_DBusData::UnixFd: { + tqAppendToMessage(it, var.toUnixFd()); + break; + } + case TQT_DBusData::List: { + TQT_DBusDataList list = var.toList(); + + TQCString signature = 0; + if (list.hasContainerItemType()) + signature = list.containerItemType().buildDBusSignature(); + else + signature = qDBusTypeForTQT_DBusType(list.type()); + + DBusMessageIter sub; + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, + signature.data(), &sub); + + const TQValueList valueList = var.toTQValueList(); + TQValueList::const_iterator listIt = valueList.begin(); + TQValueList::const_iterator listEndIt = valueList.end(); + for (; listIt != listEndIt; ++listIt) + { + qDBusDataToIterator(&sub, *listIt); + } + dbus_message_iter_close_container(it, &sub); + break; + } + case TQT_DBusData::Map: { + switch (var.keyType()) { + case TQT_DBusData::Byte: + qDBusByteKeyMapToIterator(it, var); + break; + case TQT_DBusData::Int16: + qDBusInt16KeyMapToIterator(it, var); + break; + case TQT_DBusData::UInt16: + qDBusUInt16KeyMapToIterator(it, var); + break; + case TQT_DBusData::Int32: + qDBusInt32KeyMapToIterator(it, var); + break; + case TQT_DBusData::UInt32: + qDBusUInt32KeyMapToIterator(it, var); + break; + case TQT_DBusData::Int64: + qDBusInt64KeyMapToIterator(it, var); + break; + case TQT_DBusData::UInt64: + qDBusUInt64KeyMapToIterator(it, var); + break; + case TQT_DBusData::String: + qDBusStringKeyMapToIterator(it, var); + break; + case TQT_DBusData::ObjectPath: + qDBusObjectPathKeyMapToIterator(it, var); + break; + case TQT_DBusData::UnixFd: + qDBusUnixFdKeyMapToIterator(it, var); + break; + default: + tqWarning("TQT_DBusMarshall: unhandled map key type %s " + "at marshalling", + TQT_DBusData::typeName(var.keyType())); + break; + } + break; + } + case TQT_DBusData::Variant: { + TQT_DBusVariant variant = var.toVariant(); + if (variant.signature.isEmpty() || !variant.value.isValid()) break; + + DBusMessageIter sub; + dbus_message_iter_open_container(it, DBUS_TYPE_VARIANT, + variant.signature.utf8(), &sub); + + qDBusDataToIterator(&sub, variant.value); + + dbus_message_iter_close_container(it, &sub); + break; + } + case TQT_DBusData::Struct: { + TQValueList memberList = var.toStruct(); + if (memberList.isEmpty()) break; + + DBusMessageIter sub; + dbus_message_iter_open_container(it, DBUS_TYPE_STRUCT, NULL, &sub); + + TQValueList::const_iterator memberIt = memberList.begin(); + TQValueList::const_iterator memberEndIt = memberList.end(); + for (; memberIt != memberEndIt; ++memberIt) + { + qDBusDataToIterator(&sub, *memberIt); + } + + dbus_message_iter_close_container(it, &sub); + } +#if 0 + case TQVariant::ByteArray: { + const TQByteArray array = var.toByteArray(); + const char* cdata = array.data(); + DBusMessageIter sub; + dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &sub); + dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &cdata, array.size()); + dbus_message_iter_close_container(it, &sub); + break; + } +#endif + default: + //tqWarning("Don't know how to handle type %s", var.typeName()); + break; + } +} + +void qListToIterator(DBusMessageIter* it, const TQValueList& list) +{ + if (list.isEmpty()) return; + + TQValueList::const_iterator listIt = list.begin(); + TQValueList::const_iterator listEndIt = list.end(); + for (; listIt != listEndIt; ++listIt) + { + qDBusDataToIterator(it, *listIt); + } +} + +void TQT_DBusMarshall::listToMessage(const TQValueList &list, DBusMessage *msg) +{ + Q_ASSERT(msg); + DBusMessageIter it; + dbus_message_iter_init_append(msg, &it); + qListToIterator(&it, list); +} diff --git a/src/tqdbusmarshall.h b/src/tqdbusmarshall.h new file mode 100644 index 0000000..6c41587 --- /dev/null +++ b/src/tqdbusmarshall.h @@ -0,0 +1,40 @@ +/* qdbusmarshall.h TQT_DBusMarshall object + * + * Copyright (C) 2005 Harald Fernengel + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSMARSHALL_H +#define TQDBUSMARSHALL_H + +struct DBusMessage; + +class TQT_DBusData; + +template class TQValueList; + +class TQT_DBusMarshall +{ +public: + static void listToMessage(const TQValueList &list, DBusMessage* message); + static void messageToList(TQValueList& list, DBusMessage* message); +}; + +#endif diff --git a/src/tqdbusmessage.cpp b/src/tqdbusmessage.cpp new file mode 100644 index 0000000..455e549 --- /dev/null +++ b/src/tqdbusmessage.cpp @@ -0,0 +1,263 @@ +/* qdbusmessage.cpp + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2005 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include "tqdbusmessage.h" + +#include + +#include + +#include "tqdbusmarshall.h" +#include "tqdbusmessage_p.h" + +TQT_DBusMessagePrivate::TQT_DBusMessagePrivate(TQT_DBusMessage *qq) + : msg(0), reply(0), q(qq), type(DBUS_MESSAGE_TYPE_INVALID), timeout(-1), ref(1) +{ +} + +TQT_DBusMessagePrivate::~TQT_DBusMessagePrivate() +{ + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); +} + +/////////////// + + +TQT_DBusMessage TQT_DBusMessage::signal(const TQString &path, const TQString &interface, + const TQString &member) +{ + TQT_DBusMessage message; + message.d->type = DBUS_MESSAGE_TYPE_SIGNAL; + message.d->path = path; + message.d->interface = interface; + message.d->member = member; + + return message; +} + +TQT_DBusMessage TQT_DBusMessage::methodCall(const TQString &service, const TQString &path, + const TQString &interface, const TQString &method) +{ + TQT_DBusMessage message; + message.d->type = DBUS_MESSAGE_TYPE_METHOD_CALL; + message.d->service = service; + message.d->path = path; + message.d->interface = interface; + message.d->member = method; + + return message; +} + +TQT_DBusMessage TQT_DBusMessage::methodReply(const TQT_DBusMessage &other) +{ + Q_ASSERT(other.d->msg); + + TQT_DBusMessage message; + message.d->type = DBUS_MESSAGE_TYPE_METHOD_RETURN; + message.d->reply = dbus_message_ref(other.d->msg); + + return message; +} + +TQT_DBusMessage TQT_DBusMessage::methodError(const TQT_DBusMessage &other, const TQT_DBusError& error) +{ + Q_ASSERT(other.d->msg); + + TQT_DBusMessage message; + if (!error.isValid()) + { + tqWarning("TQT_DBusMessage: error passed to methodError() is not valid!"); + return message; + } + + message.d->type = DBUS_MESSAGE_TYPE_ERROR; + message.d->reply = dbus_message_ref(other.d->msg); + message.d->error = error; + + return message; +} + +TQT_DBusMessage::TQT_DBusMessage() +{ + d = new TQT_DBusMessagePrivate(this); +} + +TQT_DBusMessage::TQT_DBusMessage(const TQT_DBusMessage &other) + : TQValueList(other) +{ + d = other.d; + d->ref.ref(); +} + +TQT_DBusMessage::~TQT_DBusMessage() +{ + if (!d->ref.deref()) + delete d; +} + +TQT_DBusMessage &TQT_DBusMessage::operator=(const TQT_DBusMessage &other) +{ + TQValueList::operator=(other); + // FIXME-QT4 qAtomicAssign(d, other.d); + if (other.d) other.d->ref.ref(); + TQT_DBusMessagePrivate* old = d; + d = other.d; + if (old && !old->ref.deref()) + delete old; + return *this; +} + +DBusMessage *TQT_DBusMessage::toDBusMessage() const +{ + DBusMessage *msg = 0; + switch (d->type) { + case DBUS_MESSAGE_TYPE_METHOD_CALL: + msg = dbus_message_new_method_call(d->service.utf8().data(), + d->path.utf8().data(), d->interface.utf8().data(), + d->member.utf8().data()); + break; + case DBUS_MESSAGE_TYPE_SIGNAL: + msg = dbus_message_new_signal(d->path.utf8().data(), + d->interface.utf8().data(), d->member.utf8().data()); + break; + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + msg = dbus_message_new_method_return(d->reply); + break; + case DBUS_MESSAGE_TYPE_ERROR: + msg = dbus_message_new_error(d->reply, d->error.name().utf8().data(), + d->error.message().utf8().data()); + break; + } + if (!msg) + return 0; + + TQT_DBusMarshall::listToMessage(*this, msg); + return msg; +} + +TQT_DBusMessage TQT_DBusMessage::fromDBusMessage(DBusMessage *dmsg) +{ + TQT_DBusMessage message; + if (!dmsg) + return message; + + message.d->type = dbus_message_get_type(dmsg); + message.d->path = TQString::fromUtf8(dbus_message_get_path(dmsg)); + message.d->interface = TQString::fromUtf8(dbus_message_get_interface(dmsg)); + message.d->member = TQString::fromUtf8(dbus_message_get_member(dmsg)); + message.d->sender = TQString::fromUtf8(dbus_message_get_sender(dmsg)); + message.d->msg = dbus_message_ref(dmsg); + + DBusError dbusError; + dbus_error_init(&dbusError); + if (dbus_set_error_from_message(&dbusError, dmsg)) + { + message.d->error = TQT_DBusError(&dbusError); + } + + TQT_DBusMarshall::messageToList(message, dmsg); + + return message; +} + +TQString TQT_DBusMessage::path() const +{ + return d->path; +} + +TQString TQT_DBusMessage::interface() const +{ + return d->interface; +} + +TQString TQT_DBusMessage::member() const +{ + return d->member; +} + +TQString TQT_DBusMessage::sender() const +{ + return d->sender; +} + +TQT_DBusError TQT_DBusMessage::error() const +{ + return d->error; +} + +int TQT_DBusMessage::timeout() const +{ + return d->timeout; +} + +void TQT_DBusMessage::setTimeout(int ms) +{ + d->timeout = ms; +} + +/*! + Returns the unique serial number assigned to this message + or 0 if the message was not sent yet. + */ +int TQT_DBusMessage::serialNumber() const +{ + if (!d->msg) + return 0; + return dbus_message_get_serial(d->msg); +} + +/*! + Returns the unique serial number assigned to the message + that triggered this reply message. + + If this message is not a reply to another message, 0 + is returned. + + */ +int TQT_DBusMessage::replySerialNumber() const +{ + if (!d->msg) + return 0; + return dbus_message_get_reply_serial(d->msg); +} + +TQT_DBusMessage::MessageType TQT_DBusMessage::type() const +{ + switch (d->type) { + case DBUS_MESSAGE_TYPE_METHOD_CALL: + return MethodCallMessage; + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + return ReplyMessage; + case DBUS_MESSAGE_TYPE_ERROR: + return ErrorMessage; + case DBUS_MESSAGE_TYPE_SIGNAL: + return SignalMessage; + default: + return InvalidMessage; + } +} + diff --git a/src/tqdbusmessage.h b/src/tqdbusmessage.h new file mode 100644 index 0000000..665a83f --- /dev/null +++ b/src/tqdbusmessage.h @@ -0,0 +1,514 @@ +/* qdbusmessage.h TQT_DBusMessage object + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2005-2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSMESSAGE_H +#define TQDBUSMESSAGE_H + +#include "tqdbusmacros.h" +#include "tqdbusdata.h" + +#include + +#include + +class TQT_DBusError; +class TQT_DBusMessagePrivate; +struct DBusMessage; + +/** + * @brief A message converts and transports data over D-Bus + * + * A TQT_DBusMessage is implicitly shared, similar to a TQString, i.e. copying + * a message creates just a shallow copy. + * + * The TQT_DBusMessage is the TQt3 bindings means of encapsulating data for a + * method call, a method reply or an error. + * + * Data specifying the sender and receipient is directly accessible through + * getter methods, while data, e.g. method parameters or return values, are + * managed as a list of TQT_DBusData. + * + * To create a message suitable for sending use one of the static factory + * methods: + * - signal() for creating a D-Bus signal message + * + * - methodCall() for creating a D-Bus method calls to a service object + * + * - methodReply() for creating a method reply on success + * + * - methodError() for creating a method reply on error + * + * @note for applications that just want to perform method calls and/or receive + * signals, it is usually more convenient to use TQT_DBusProxy instead. + * + * Message sending is achieved through TQT_DBusConnection + * + * Example: + * @code + * TQT_DBusConnection con = TQT_DBusConnection::sessionBus(); + * + * // receipient service is the bus' main interface + * + * TQString service = "org.freedesktop.DBus"; + * TQString path = "/org/freedesktop/DBus"; + * TQString interface = "org.freedesktop.DBus"; + * + * TQT_DBusMessage msg = TQBusMessage::methodCall(service, path, interface, "ListNames"); + * + * TQT_DBusMessage reply = con.sendWithReply(msg); + * + * // awaiting for a message list + * + * if (reply.type() != TQT_DBusMessage::ReplyMessage || reply.count() != 2 || + * reply[0].type() != TQT_DBusData::List) + * { + * // error handling here + * } + * else + * { + * TQStringList list = reply[0].toTQStringList(); + * + * // reply handling here + * } + * @endcode + * + * A service returning such a reply would do something like this + * @code + * bool Service::handleMethodCall(const TQT_DBusMessage& call) + * { + * // checks for correctness, i.e. correct interface, member, + * // would usually haven been placed here + * + * TQStringList result; + * result << "Foo" << "Bar"; + * + * TQT_DBusMessage reply = TQT_DBusMessage::methodReply(call); + * reply << TQT_DBusData::fromList(result); + * + * connection.send(reply); + * + * return true; + * } + * @endcode + */ +class TQDBUS_EXPORT TQT_DBusMessage: public TQValueList +{ + friend class TQT_DBusConnection; +public: + /** + * @brief Anonymous enum for timeout constants + * + * @see timeout() + * @see setTimeout() + */ + enum + { + /** + * Use whatever D-Bus has as default timeout + */ + DefaultTimeout = -1, + + /** + * Use no timeout at all, i.e. wait as long as necessary + */ + NoTimeout = INT_MAX + }; + + /** + * @brief D-Bus message types + * + * A message of a specific type can be created using the respective factory + * method. A message created by the default constructor becomes an + * InvalidMessage + * + * @see type() + * @see signal() + * @see methodCall() + * @see methodReply() + * @see methodError() + */ + enum MessageType + { + /** + * An invalid message cannot be sent over D-Bus. This type serves for + * initializing message variables without requiring a "real" message + */ + InvalidMessage, + + /** + * A message for doing method calls on remote service objects + * + * @see methodCall() + */ + MethodCallMessage, + + /** + * A message for replying to a method call in case of success + * + * @see methodReply() + */ + ReplyMessage, + + /** + * A message for replying to a method call in case of failure + * + * @see methodError() + */ + ErrorMessage, + + /** + * A message for emitting D-Bus signals + * + * @see signal() + */ + SignalMessage + }; + + /** + * @brief Creates an empty and invalid message + * + * To create a message suitable for sending through D-Bus see the factory + * methods signal(), methodCall(), methodReply() and methodError() + * + * @see #InvalidMessage + */ + TQT_DBusMessage(); + + + /** + * @brief Creates a shallow copy of the given message + * + * This instance will become a handle to the same message data the other + * message is using, including #MessageType + * + * @param other the message to copy + */ + TQT_DBusMessage(const TQT_DBusMessage &other); + + /** + * @brief Destroys a message + * + * If this message handle is the last one using this respective message + * content, the message content will be deleted as well + */ + ~TQT_DBusMessage(); + + /** + * @brief Creates a shallow copy of the given message + * + * This instance will become a handle to the same message data the other + * message is usingm including #MessageType + * + * Any content used in this instance will be deleted if this instance was + * the last handle using that content + * + * @param other the message to copy + * + * @return a reference to this instance as required by assignment operator + * semantics + */ + TQT_DBusMessage &operator=(const TQT_DBusMessage &other); + + /** + * @brief Creates a message for sending a D-Bus signal + * + * Sending/emitting a signal over D-Bus requires a message of type + * #SignalMessage as well as the information where it is coming from, i.e. + * which interface of which object is sending it. + * See @ref dbusconventions for recommendations on those parameters. + * + * @param path the object path of the service object + * @param interface the object's interface to which the signal belongs + * @param member the signal's name + * + * @return a message suitable for appending arguments and for sending + * + * @see TQT_DBusConnection::send() + */ + static TQT_DBusMessage signal(const TQString &path, const TQString &interface, + const TQString &member); + + /** + * @brief Creates a message for sending a D-Bus method call + * + * Invoking a method over D-Bus requires a message of type + * #MethodCallMessage as well as the information where it should be sent + * to, e.g which interface of which object in which service. + * See @ref dbusconventions for recommendations on those parameters. + * + * @param service the D-Bus name of the application hosting the service + * object + * @param path the object path of the service object + * @param interface the object's interface to which the method belongs + * @param method the method's name + * + * @return a message suitable for appending arguments and for sending + * + * @see methodReply() + * @see methodError() + * @see TQT_DBusConnection::send() + */ + static TQT_DBusMessage methodCall(const TQString &service, const TQString &path, + const TQString &interface, const TQString &method); + + /** + * @brief Creates a message for replying to a D-Bus method call + * + * Replying to a D-Bus method call in the case of success requires a message + * of type #ReplyMessage as well as the information to which method call it + * is replying to. + * + * @param other the method call message it is replying to + * + * @return a message suitable for appending arguments and for sending + * + * @see methodCall() + * @see methodError() + * @see TQT_DBusConnection::send() + */ + static TQT_DBusMessage methodReply(const TQT_DBusMessage &other); + + /** + * @brief Creates a message for replying to a D-Bus method call + * + * Replying to a D-Bus method call in the case of failure requires a message + * of type #ErrorMessage as well as the information to which method call it + * is replying to and which error occured. + * + * @param other the method call message it is replying to + * @param error the error which occured during during the method call + * + * @return a message suitable for appending arguments and for sending + * + * @see methodCall() + * @see methodReply() + * @see TQT_DBusConnection::send() + */ + static TQT_DBusMessage methodError(const TQT_DBusMessage &other, const TQT_DBusError& error); + + /** + * @brief Returns the message's object path + * + * See section @ref dbusconventions-objectpath for details. + * + * The context of the object path depends on the message type: + * - #SignalMessage: the path of the service object which emits the signal + * - #MethodCallMessage: the path of the service object the call is sent to + * - #ReplyMessage: the path of the object which is replying + * - #ErrorMessage: the path of the object which is replying + * + * @return a non-empty object path or @c TQString() + * + * @see interface() + * @see member() + * @see sender() + */ + TQString path() const; + + /** + * @brief Returns the message's interface name + * + * See section @ref dbusconventions-interfacename for details. + * + * The context of the interface name depends on the message type: + * - #SignalMessage: the name of the interface which emits the signal + * - #MethodCallMessage: the name of the interface the call is sent to + * - #ReplyMessage: the name of the interface to which the method belonged + * - #ErrorMessage: the name of the interface to which the method belonged + * + * @return a non-empty interface name or @c TQString() + * + * @see path() + * @see member() + * @see sender() + */ + TQString interface() const; + + /** + * @brief Returns the message's member name + * + * See section @ref dbusconventions-membername for details. + * + * The context of the member name depends on the message type: + * - #SignalMessage: the name of the emitted signal + * - #MethodCallMessage: the name of the method to call + * - #ReplyMessage: the name of the method which replies + * - #ErrorMessage: the name of the method which replies + * + * @return a non-empty member name or @c TQString() + * + * @see path() + * @see interface() + * @see sender() + */ + TQString member() const; + + /** + * @brief Returns the name of the message sender + * + * The message sender name or address used on the D-Bus message bus + * to refer to the application which sent this message. + * + * See section @ref dbusconventions-servicename for details. + * + * This can either be a unique name as handed out by the bus, see + * TQT_DBusConnection::uniqueName() or a name registered with + * TQT_DBusConnection::requestName() + * + * @return a non-empty D-Bus sender name or @c TQString() + * + * @see path() + * @see interface() + * @see member() + */ + TQString sender() const; + + /** + * @brief Returns the error of an error message + * + * If this message is of type #ErrorMessage, this method can be used + * to retrieve the respective error object + * + * @return the transported error object. Will be empty if this is not an + * error message + * + * @see type() + */ + TQT_DBusError error() const; + + /** + * @brief Returns which kind of message this is + * + * @return the message's type + */ + MessageType type() const; + + /** + * @brief Returns the message's timeout + * + * @return the asynchronous wait timeout in milliseconds + * + * @see setTimeout() + */ + int timeout() const; + + /** + * @brief Sets the message's timeout + * + * The timeout is the number of milliseconds the D-Bus connection will + * wait for the reply of an asynchronous call. + * + * If no reply is received in time, an error message will be delivered to + * the asynchronous reply receiver. + * + * If no timeout is set explicitly, #DefaultTimeout is assumed, which is + * usually the best option + * + * @return the asynchronous wait timeout in milliseconds + * + * @param ms timeout in milliseconds + * + * @see timeout() + * @see #DefaultTimeout + * @see #NoTimeout + */ + void setTimeout(int ms); + + /** + * @brief Returns the message's serial number + * + * The serial number is some kind of short term identifier for messages + * travelling the same connection. + * + * It can be used to associate a reply or error message with a method + * call message. + * + * @return the message's serial number or @c 0 if the message hasn't been + * send yets + * + * @see replySerialNumber() + */ + int serialNumber() const; + + /** + * @brief Returns the message's reply serial number + * + * The reply serial number is the serial number of the method call message + * this message is a reply to. + * + * If this is neither a message of type #ReplyMessage or #ErrorMessage, the + * returned value will be @c 0 + * + * It can be used to associate a reply or error message with a method + * call message. + * + * @return the serial number of the associated method call message or @c 0 + * if this message is not a reply message + * + * @see serialNumber() + * @see methodReply() + * @see methodError() + * @see TQT_DBusConnection::sendWithAsyncReply() + * @see TQT_DBusProxy::sendWithAsyncReply() + */ + int replySerialNumber() const; + +//protected: + /** + * @brief Creates a raw D-Bus message from this TQt3-bindings message + * + * Marshalls data contained in the message's value list into D-Bus data + * format and creates a low level API D-Bus message for it. + * + * @note ownership of the returned message is transferred to the caller, + * i.e. it has to be deleted using dbus_message_unref() + * + * @return a C API D-Bus message or @c 0 if this is an #InvalidMessage + * or marshalling failed + */ + DBusMessage *toDBusMessage() const; + + /** + * @brief Creates a TQt3-bindings message from the given raw D-Bus message + * + * De-marshalls data contained in the message to a list of TQT_DBusData. + * + * @note ownership of the given message is shared between the caller and + * the returned message, i.e. the message as increased the reference + * counter and will still have access to the raw message even if the + * caller "deleted" it using dbus_message_unref() + * + * @param dmsg a C API D-Bus message + * + * @return a TQt3 bindings message. Can be an #InvalidMessage if the given + * message was @c 0 or if de-marshalling failed + */ + static TQT_DBusMessage fromDBusMessage(DBusMessage *dmsg); + +private: + TQT_DBusMessagePrivate *d; +}; + +#endif + diff --git a/src/tqdbusmessage_p.h b/src/tqdbusmessage_p.h new file mode 100644 index 0000000..657460f --- /dev/null +++ b/src/tqdbusmessage_p.h @@ -0,0 +1,52 @@ +/* qdbusmessage.h TQT_DBusMessage private object + * + * Copyright (C) 2005 Harald Fernengel + * Copyright (C) 2005 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSMESSAGE_P_H +#define TQDBUSMESSAGE_P_H + +#include + +#include "tqdbusatomic.h" +#include "tqdbuserror.h" + +struct DBusMessage; + +class TQT_DBusMessagePrivate +{ +public: + TQT_DBusMessagePrivate(TQT_DBusMessage *qq); + ~TQT_DBusMessagePrivate(); + + TQString path, interface, member, service, sender; + TQT_DBusError error; + DBusMessage *msg; + DBusMessage *reply; + TQT_DBusMessage *q; + int type; + int timeout; + // FIXME-QT4 TQAtomic ref; + Atomic ref; +}; + +#endif diff --git a/src/tqdbusobject.h b/src/tqdbusobject.h new file mode 100644 index 0000000..aa16750 --- /dev/null +++ b/src/tqdbusobject.h @@ -0,0 +1,372 @@ +/* qdbusobject.h DBUS service object interface + * + * Copyright (C) 2005-2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSOBJECT_H +#define TQDBUSOBJECT_H + +/** + * @page dbusservice Providing services over D-Bus + * + * Contents: + * - @ref dbusservice-introduction + * - @ref dbusservice-example + * - @ref dbusservice-requestname + * - @ref dbusservice-registerobjects + * - @ref dbusservice-interfaces + * + * @section dbusservice-introduction Introduction + * + * The TQt3 bindings do not support autogeneration of service objects yet. In + * order to provide interfaces over D-Bus, an application has to implement the + * TQT_DBusObjectBase interface and register an instance of the resulting class + * with the TQT_DBusConnection. + * + * @section dbusservice-example A simple D-Bus client example + * + * @code + * #include ; + * #include ; + * + * class TQStringList; + * + * class TestService : public TQT_DBusObjectBase + * { + * public: + * TestService(const TQT_DBusConnection& connection); + * virtual ~TestService(); + * + * protected: + * virtual bool handleMethodCall(const TQT_DBusMessage& message); + * + * private: + * TQT_DBusConnection m_connection; + * + * private: + * TQStringList sortStrings(const TQStringList& list); + * }; + * @endcode + * @code + * + * #include ; + * + * #include ; + * #include ; + * + * TestService::TestService(const TQT_DBusConnection& connection) : m_connection(connection) + * { + * m_connection.registerObject("/ListSorter", this); + * } + * + * TestService::~TestService() + * { + * m_connection.unregisterObject("/ListSorter"); + * } + * + * // return false to let D-Bus send a standard error message that the method is unknown + * + * bool TestService::handleMethod(const TQT_DBusMessage& message) + * { + * if (message.interface() != "org.example.Sort") return false; + * + * if (message.member() == "Strings") + * { + * // check parameters + * + * if (message.count() != 1 || message[0].type() != TQT_DBusData::List) + * { + * // method signature not what we expected + * + * TQT_DBusError error = TQT_DBusError::stdInvalidArgs( + * "Expected one argument of type array of string"); + * + * TQT_DBusMessage reply = TQT_DBusMessage::methodError(message, error); + * + * // send error + * + * m_connection.send(reply); + * + * // tell D-Bus we did handle the call + * + * return true; + * } + * + * // call implementation + * + * TQStringList result = sortStrings(message[0].toTQStringList()); + * + * // prepare reply + * + * TQT_DBusMessage reply = TQT_DBusMessage::methodReply(message); + * + * reply << TQT_DBusData::fromList(result); + * + * // send reply + * + * m_connection.send(reply); + * + * // tell D-Bus we did handle the call + * + * return true; + * } + * + * return false; + * } + * + * TQStringList TestService::sortStrings(const TQStringList& list) + * { + * TQStringList result = list; + * + * result.sort(); + * + * return result; + * } + * @endcode + * @code + * int main(int argc, char** argv) + * { + * TQApplication app(argc, argv, false); + * + * TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); + * if (!connection.isConnected()) + * tqFatal("Cannot connect to session bus"); + * + * // try to get a specific service name + * if (!connection.requestName("org.example.SortService")) + * { + * tqWarning("Requesting name 'org.example.SortService' failed. " + * "Will only be addressable through unique name '%s'", + * connection.uniqueName().local8Bit().data()); + * } + * else + * { + * tqDebug("Requesting name 'org.example.SortService' successfull"); + * } + * + * TestService service(connection); + * + * return app.exec(); + * } + * @endcode + * + * @section dbusservice-requestname Requesting service name + * + * When an application connects to D-Bus it gets a unique name generated by + * the bus daemon. + * + * However, an application providing service will often want to be reachable + * under a fixed name, like a webserver being reachable through a domain name + * independent from its actual IP address. + * See section @ref dbusconventions-servicename for details on service names. + * + * In order to get such a specific name an application has to request it + * using TQT_DBusConnection::requestName() + * + * The example above request @c "org.example.SortService" but continues with + * the default unique name in the case some other application is currently + * owning that name. + * + * @section dbusservice-registerobjects Registering objects + * + * To make service objects available to other applications on the same + * bus the application has to register the objects instances with the + * connection to the bus using TQT_DBusConnection::registerObject() + * + * Registering means to specify an object path where the object will be + * located, i.e. how it can be unambiguously be addressed in method calls. + * See section @ref dbusconventions-objectpath for details on object paths. + * + * If the applications has introspectable objects it is recommended to + * register an introspectable root object, i.e. using @c "/" as the path, so + * other applications have a common place to start asking for introspection + * data. + * + * In the example above a service object providing sorting services on lists is + * registered on the path @c "/ListSorter" + * + * @section dbusservice-interfaces Service interfaces + * + * D-Bus methods and signals of a service object a grouped into interfaces. + * + * See section @ref dbusconventions-interfacename for details on interface + * naming. + * + * An object can implement any number of interfaces, for example the interface + * for the functionality it wants to provide and a D-Bus standard interface like + * @c "org.freedesktop.DBus.Introspectable" for providing an XML description of + * all its interfaces. + * + * + * The service object of the example above implements just one interface + * @c "org.example.Sort" and its handleMethodCall() explicitly checks all + * received messages and rejects any messsage not sent to this particular + * interface by returning @c false and thus telling the D-Bus layer to + * generate a standard error response. + * + * Multiple interfaces can of course be directly implemented in one C++ class, + * however it might sometimes be wise to delegate calls for different + * interfaces to different implementations: + * @code + * class Interface1 : public TQT_DBusObjectBase + * { + * public: + * Interface1(const TQT_DBusConnection&); + * + * protected: + * virtual bool handleMethodCall(const TQT_DBusMessage&); + * }; + * + * class Interface2 : public TQT_DBusObjectBase + * { + * public: + * Interface2(const TQT_DBusConnection&); + * + * protected: + * virtual bool handleMethodCall(const TQT_DBusMessage&); + * }; + * + * class MultiInterfaceService : public TQT_DBusObjectBase + * { + * public: + * MultiInterfaceService(const TQT_DBusConnection&); + * + * protected: + * virtual bool handleMethodCall(const TQT_DBusMessage&); + * + * private: + * TQMap m_interfaces; + * }; + * + * MultiInterfaceService::MultiInterfaceService(const TQT_DBusConnection& connection) + * { + * m_interfaces.insert("org.example.Interface1", new Interface1(connection)); + * m_interfaces.insert("org.example.Interface2", new Interface2(connection)); + * } + * + * bool MultiInterfaceService::handleMethodCall(const TQT_DBusMessage& message) + * { + * // delegate call to its interface handler + * TQT_DBusObjectBase* handler = m_interfaces[message.interface()]; + * if (handler != 0) + * return delegateMethodCall->(message, handler); + * else + * return false; // no such interface + * } + * @endcode + */ + +/** + * @include example-service.h + * @example example-service.cpp + */ + +#include "tqdbusmacros.h" + +class TQT_DBusMessage; + +/** + * @brief Base interface for D-Bus service objects + * + * In order to register a service object with the TQT_DBusConnection it needs to + * implement the interface specified by this class. + * + * The connection will forward all method calls that have a path equivalent + * to the path the service object was registered with to the object's + * handleMethodCall() method. See TQT_DBusConnection::registerObject() + * + * If for some reason, e.g. the call is not meant for this interface, or the + * method is unknown, the implementation can just return @c false and the + * connection will handle the rest. + * + * See section @ref dbusservice for documentation on how to use TQT_DBusObjectBase + */ +class TQDBUS_EXPORT TQT_DBusObjectBase +{ + friend class TQT_DBusConnectionPrivate; +public: + /** + * @brief Destroys the object + */ + virtual ~TQT_DBusObjectBase() {} + +protected: + /** + * @brief Method call entry point + * + * This method has to be implemented to handle method calls sent to the + * service object. + * An object implementation can handle all its interfaces in one class or + * again forward the method call to interface implementators. + * + * If for some reason, e.g. the call is not meant for this interface, or + * the method is unknown, the implementation can just return @c false and + * the connection will handle the rest. + * + * If an error occurs during the method call, e.g. the number of parameters + * or their types are not what would be expected, the service object + * should reply with a TQT_DBusMessage of type TQT_DBusMessage::ErrorMessage + * which in turn should include the D-Bus error describing the problem. + * See TQT_DBusConnection::send() for sending reply messages. + * + * See TQT_DBusMessage::methodError() and TQT_DBusMessage::methodReply() on + * how to create suitable reply messages for the given method call. + * + * @param message the method call to handle + * + * @return @c true if the message can be handled independent if handling + * resulted in an error. In this case implementations should an + * error reply. Returns @c false only if interface or method are + * unknown + */ + virtual bool handleMethodCall(const TQT_DBusMessage& message) = 0; + + /** + * @brief Delegate a method call to another object + * + * When a service object is built as a collection of separated interface + * class instances, i.e. each interface of the object is implemented in + * its own TQT_DBusObjectBase subclass and the main object just wanst to pass + * on the method calls to the respective interface implementations, it + * can do so by calling this base class method. + * + * Since it is a method of the base class, it can call the otherwise + * protected handleMethodCall() of the interface implementor. + * + * See @ref dbusservice-interfaces for an example. + * + * @param message the method call to delegate + * @param delegate the object which should handle the call instead + * + * @return @c true if the message can be handled independent if handling + * resulted in an error. In this case implementations should an + * error reply. Returns @c false only if interface or method are + * unknown + * + */ + bool delegateMethodCall(const TQT_DBusMessage& message, TQT_DBusObjectBase* delegate) + { + return delegate->handleMethodCall(message); + } +}; + +#endif + diff --git a/src/tqdbusobjectpath.cpp b/src/tqdbusobjectpath.cpp new file mode 100644 index 0000000..0f42860 --- /dev/null +++ b/src/tqdbusobjectpath.cpp @@ -0,0 +1,79 @@ +/* qdbusobjectpath.cpp DBUS object path data type + * + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include "tqdbusobjectpath.h" + +TQT_DBusObjectPath::TQT_DBusObjectPath() : TQCString() +{ +} + +TQT_DBusObjectPath::TQT_DBusObjectPath(const TQT_DBusObjectPath& other) : TQCString(static_cast(other)) +{ +} + +TQT_DBusObjectPath::TQT_DBusObjectPath(const TQCString& other) : TQCString(static_cast(other)) +{ +} + +TQT_DBusObjectPath::TQT_DBusObjectPath(const TQT_DBusObjectPath& parentNode, + const TQCString& nodeName) + : TQCString(static_cast(parentNode)) +{ + if (parentNode.length() != 1) append("/"); + + append(nodeName); +} + +bool TQT_DBusObjectPath::isValid() const +{ + return (validate(*this) == -1); +} + +TQT_DBusObjectPath TQT_DBusObjectPath::parentNode() const +{ + if (length() == 1) return TQT_DBusObjectPath(); + + int index = findRev('/'); + + if (index == -1) return TQT_DBusObjectPath(); + + if (index == 0) return left(1); + + return left(index); +} + +int TQT_DBusObjectPath::validate(const TQCString& path) +{ + if (path.isEmpty()) return 0; + + if (path[0] != '/') return 0; + + // TODO add additional checks + + uint len = path.length(); + + // only root node allowed to end in slash + if (path[len - 1] == '/' && len > 1) return (len - 1); + + return -1; +} diff --git a/src/tqdbusobjectpath.h b/src/tqdbusobjectpath.h new file mode 100644 index 0000000..7a166c6 --- /dev/null +++ b/src/tqdbusobjectpath.h @@ -0,0 +1,119 @@ +/* qdbusobjectpath.h DBUS object path data type + * + * Copyright (C) 2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSOBJECTPATH_H +#define TQDBUSOBJECTPATH_H + +#include +#include "tqdbusmacros.h" + +/** + * @brief Class for representing D-Bus object paths + * + * This data type is necessary to correctly represent object paths in the + * context of D-Bus messages, since normal strings have a different D-Bus + * signature than object paths. + * + * @see @ref dbusconventions-objectpath + */ +class TQDBUS_EXPORT TQT_DBusObjectPath : public TQCString +{ +public: + /** + * @brief Creates an empty and invalid object path + */ + TQT_DBusObjectPath(); + + /** + * @brief Creates copy of the given @p other object path + * + * @param other the object path to copy + */ + TQT_DBusObjectPath(const TQT_DBusObjectPath& other); + + /** + * @brief Creates copy of the given @p other object path + * + * @param other the object path to copy + */ + TQT_DBusObjectPath(const TQCString& other); + + /** + * @brief Creates an object path for an object as a child of the parent node + * + * This is basically like specifying a directory and a file name to create + * the file's full path. + * + * Example: + * @code + * TQT_DBusObjectPath rootNode("/"); // => "/" + * + * TQT_DBusObjectPath childNod(rootNode, "child"); // => "/child" + * + * TQT_DBusObjectPath grandChildNode(childNode, "grandchild"); // => "/child/grandchild" + * @endcode + * + * @param parentNode the object path to create the child on + * @param nodeName the name of the child node + */ + TQT_DBusObjectPath(const TQT_DBusObjectPath& parentNode, const TQCString& nodeName); + + /** + * @brief Returns whether the current content is considered a valid object path + * + * @note Calls validate() to perform a check on the current content + * + * @return \c true if the object's content describe a valid object path, + * otherwise @c false + * + * @see @ref dbusconventions-objectpath + */ + bool isValid() const; + + /** + * @brief Returns the object path of this path's parent node + * + * This is basically like getting the directory of an file path + * + * @return the parent node's object path or an empty and invalid object + * if this is already the root node + */ + TQT_DBusObjectPath parentNode() const; + + /** + * @brief Checks the given string for validity as a D-Bus object path + * + * See section @ref dbusconventions-objectpath for information on object + * path formatting. + * + * @param path the string to check + * + * @return @c -1 if the object path is valid, otherwise the index of the + * first violating character + * + * @see isValid() + */ + static int validate(const TQCString& path); +}; + +#endif diff --git a/src/tqdbusproxy.cpp b/src/tqdbusproxy.cpp new file mode 100644 index 0000000..7ca6118 --- /dev/null +++ b/src/tqdbusproxy.cpp @@ -0,0 +1,209 @@ +/* qdbusproxy.cpp DBUS Object proxy + * + * Copyright (C) 2005 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include "tqdbuserror.h" +#include "tqdbusconnection.h" +#include "tqdbusmessage.h" +#include "tqdbusproxy.h" + +class TQT_DBusProxy::Private +{ +public: + Private() : canSend(false) {} + ~Private() {} + + void checkCanSend() + { + canSend = !path.isEmpty() && !service.isEmpty() && !interface.isEmpty(); + } + +public: + TQT_DBusConnection connection; + + TQString service; + TQString path; + TQString interface; + bool canSend; + + TQT_DBusError error; +}; + +TQT_DBusProxy::TQT_DBusProxy(TQObject* parent, const char* name) + : TQObject(parent, (name ? name : "TQT_DBusProxy")), + d(new Private()) +{ +} + +TQT_DBusProxy::TQT_DBusProxy(const TQT_DBusConnection& connection, + TQObject* parent, const char* name) + : TQObject(parent, (name ? name : "TQT_DBusProxy")), + d(new Private()) +{ + setConnection(connection); +} + +TQT_DBusProxy::TQT_DBusProxy(const TQString& service, const TQString& path, + const TQString& interface, const TQT_DBusConnection& connection, + TQObject* parent, const char* name) + : TQObject(parent, (name ? name : "TQT_DBusProxy")), + d(new Private()) +{ + setConnection(connection); + + d->service = service; + d->path = path; + d->interface = interface; + d->checkCanSend(); +} + +TQT_DBusProxy::~TQT_DBusProxy() +{ + delete d; +} + +bool TQT_DBusProxy::setConnection(const TQT_DBusConnection& connection) +{ + d->connection.disconnect(this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); + + d->connection = connection; + + return d->connection.connect(this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); +} + +const TQT_DBusConnection& TQT_DBusProxy::connection() const +{ + return d->connection; +} + +void TQT_DBusProxy::setService(const TQString& service) +{ + d->service = service; + d->checkCanSend(); +} + +TQString TQT_DBusProxy::service() const +{ + return d->service; +} + +void TQT_DBusProxy::setPath(const TQString& path) +{ + d->path = path; + d->checkCanSend(); +} + +TQString TQT_DBusProxy::path() const +{ + return d->path; +} + +void TQT_DBusProxy::setInterface(const TQString& interface) +{ + d->interface = interface; + d->checkCanSend(); +} + +TQString TQT_DBusProxy::interface() const +{ + return d->interface; +} + +bool TQT_DBusProxy::canSend() const +{ + return d->canSend && d->connection.isConnected(); +} + +bool TQT_DBusProxy::send(const TQString& method, const TQValueList& params) const +{ + if (!d->canSend || method.isEmpty() || !d->connection.isConnected()) + return false; + + TQT_DBusMessage message = TQT_DBusMessage::methodCall(d->service, d->path, + d->interface, method); + message += params; + + return d->connection.send(message); +} + +TQT_DBusMessage TQT_DBusProxy::sendWithReply(const TQString& method, + const TQValueList& params, + TQT_DBusError* error) const +{ + if (!d->canSend || method.isEmpty() || !d->connection.isConnected()) + return TQT_DBusMessage(); + + TQT_DBusMessage message = TQT_DBusMessage::methodCall(d->service, d->path, + d->interface, method); + message += params; + + TQT_DBusMessage reply = d->connection.sendWithReply(message, &d->error); + + if (error) + *error = d->error; + + return reply; +} + +int TQT_DBusProxy::sendWithAsyncReply(const TQString& method, const TQValueList& params) +{ + if (!d->canSend || method.isEmpty() || !d->connection.isConnected()) + return 0; + + TQT_DBusMessage message = TQT_DBusMessage::methodCall(d->service, d->path, + d->interface, method); + message += params; + + return d->connection.sendWithAsyncReply(message, this, + TQT_SLOT(handleAsyncReply(const TQT_DBusMessage&))); +} + +TQT_DBusError TQT_DBusProxy::lastError() const +{ + return d->error; +} + +void TQT_DBusProxy::handleDBusSignal(const TQT_DBusMessage& message) +{ + if (!d->path.isEmpty() && d->path != message.path()) + return; + + // only filter by service name if the name is a unique name + // because signals are always coming from a connection's unique name + // and filtering by a generic name would reject all signals + if (d->service.startsWith(":") && d->service != message.sender()) + return; + + if (!d->interface.isEmpty() && d->interface != message.interface()) + return; + + emit dbusSignal(message); +} + +void TQT_DBusProxy::handleAsyncReply(const TQT_DBusMessage& message) +{ + d->error = message.error(); + + emit asyncReply(message.replySerialNumber(), message); +} + +#include "tqdbusproxy.moc" diff --git a/src/tqdbusproxy.h b/src/tqdbusproxy.h new file mode 100644 index 0000000..8d594cd --- /dev/null +++ b/src/tqdbusproxy.h @@ -0,0 +1,585 @@ +/* qdbusproxy.h DBUS Object proxy + * + * Copyright (C) 2005-2007 Kevin Krammer + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSPROXY_H +#define TQDBUSPROXY_H + +/** + * @page dbusclient Using D-Bus as a client + * + * Contents: + * - @ref dbusclient-introduction + * + * - @ref dbusclient-example + * + * - @ref dbusclient-initialization + * + * - @ref dbusclient-methodcall + * - @ref dbusclient-synccall + * - @ref dbusclient-asynccall + * + * - @ref dbusclient-signals + * - @ref dbusclient-signals-example + * + * @section dbusclient-introduction Introduction + * + * While it is of course possible to just exchange D-Bus messages with a + * D-Bus service, it is a lot more comfortable to use TQT_DBusProxy. + * + * With TQT_DBusProxy you only need to specify the service object once, i.e. + * its D-Bus name, path and interface, and just provide the method and its + * parameters when initiating an invokation. + * + * Additionally the proxy transforms D-Bus signals from the proxy's peer + * (the D-Bus service object's interface it is associated with) to TQObject + * signal carrying the original signal's content. + * + * @section dbusclient-example A simple D-Bus client example + * + * @code + * #include + * #include + * #include + * + * int main() + * { + * // establish a connection to the session bus + * + * TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); + * if (!connection.isConnected()) + * tqFatal("Failed to connect to session bus"); + * + * // create a proxy object for method calls + * + * TQT_DBusProxy proxy(connection); + * proxy.setService("org.freedesktop.DBus"); // who we work with + * proxy.setPath("/org/freedesktop/DBus"); // which object inside the peer work with + * proxy.setInterface("org.freedesktop.DBus"); // which of its interfaces we will use + * + * // call the "ListNames" method. It returns an array of string, in TQt3 terms + * // a TQStringList, it expects no parameters + * + * TQValueList params; + * TQT_DBusMessage reply = proxy.sendWithReply("ListNames", params); + * + * if (reply.type() != TQT_DBusMessage::ReplyMessage) + * tqFatal("Call failed"); + * + * if (reply.count() != 1 || reply[0].type() != TQT_DBusData::List) + * tqFatal("Unexpected reply"); + * + * bool ok = false; + * TQStringList names = reply[0].toTQStringList(&ok); + * + * if (!ok) tqFatal("Unexpected reply"); + * + * for (TQStringList::iterator it = names.begin(); it != names.end(); ++it) + * { + * tqDebug("%s", (*it).local8Bit().data()); + * } + * + * return 0; + * } + * @endcode + * + * @section dbusclient-initialization Program initialization + * + * A connection to the bus is acquired using TQT_DBusConnection::sessionBus() + * + * Next, a proxy is created for the object @c "/org/freedesktop/DBus" with + * interface @c "org.freedesktop.DBus" on the service @c "org.freedesktop.DBus" + * + * This is a proxy for the message bus itself. + * + * @section dbusclient-methodcall Method invocation + * + * There are two choices for method invocation: + * - sychronous (blocking) calls + * - asynchronous (non-blocking) calls + * + * @subsection dbusclient-synccall Synchronous method calls + * + * As seen in the example code above, a synchronous method call can be achieved + * by TQT_DBusProxy::sendWithReply(). It sends a method call to the remote object, + * and blocks until reply is received. The outgoing arguments are specified as + * a list of TQT_DBusData. + * + * @subsection dbusclient-asynccall Asynchronous method calls + * + * To invoke a method asynchronously, connect the proxy's signal + * TQT_DBusProxy::asyncReply(int, const TQT_DBusMessage&) to a suitable slot like + * with any other TQt Signal-Slot connection. + * + * Then call TQT_DBusProxy::sendWithAsyncReply() + * It returns a numerical identifier of the call, so it can be related in the + * slot once the result is available. + * + * The slot's first argument is the reveived reply's call identifier as + * returned by the method call. The second parameter is the reply message + * similar to the one in the synchronous call. + * + * @note For asynchronous calls you'll need a running event loop, i.e. a + * TQApplication object and its exec() having been invoked. + * + * @section dbusclient-signals Connecting to D-Bus signals + * + * To receive D-BUS signals just connect to the TQT_DBusProxy's signal + * TQT_DBusProxy::dbusSignal(const TQT_DBusMessage&) + * + * It will be emitted whenever a D-Bus signal message is received from the peer + * object. + * Filtering of signals is based on the value set for @c service, @c path and + * @c interface + * + * @note Filtering for @c service will only happen if @c service is a unique + * D-Bus name, i.e. if it starts with a colon @c ":" since D-Bus signals + * carry the sender's unique name and filtering by a requested name + * would reject all signals + * + * Usually a proxy will be also be used to send to the peer object, thus having + * them all set. However if a proxy is only needed for signals, any of the + * three properties can be omitted (e.g. set to @c TQString() ), in which + * case only the available properties will be checked against the respective + * message field when deciding about dropping or emitting the message. + * See TQT_DBusProxy::handleDBusSignal() + * + * If you want all signal travelling on the bus, or apply filtering for + * different criteria, e.g. get all signals coming from interfaces starting + * with @c "org.", use @c TQT_DBusConnection::connect() instead. + * The signature of the slot stays the same. + * + * @subsection dbusclient-signals-example Signal example + * + * First declare a receiver class: + * @code + * class MyReceiver : public TQObject + * { + * Q_OBJECT + * + * public slots: + * void handleDBusSignal(const TQT_DBusMessage&); + * }; + * @endcode + * Then somewhere else in a source file: + * @code + * TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); + * + * MyReceiver* receiver1 = new MyReceiver(); + * + * connection.connect(receiver1, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); + * @endcode + * @c receiver1 will get all signals on this connection + * + * @code + * TQT_DBusProxy* proxy = new TQT_DBusProxy(connection); + * proxy->setService("org.freedesktop.DBus"); // who we work with + * proxy->setPath("/org/freedesktop/DBus"); // which object inside the peer work with + * proxy->setInterface("org.freedesktop.DBus"); // which of its interfaces we will use + * + * MyReceiver* receiver2 = new MyReceiver(); + * + * TQObject::connect(proxy, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), + * receiver2, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); + * @endcode + * @c receiver2 will only get signals coming from the proxy's peer interface + */ + +/** + * @include example-client.h + * @example example-client.cpp + */ + +#include + +#include "tqdbusmacros.h" + +class TQT_DBusConnection; +class TQT_DBusData; +class TQT_DBusError; +class TQT_DBusMessage; + +template class TQValueList; + +/** + * @brief Client interface to a remote service object + * + * TQT_DBusProxy provides a convenience interface for working with D-Bus services, + * or more precisely, interfaces of D-Bus service objects. + * + * A D-Bus service object is identified through the name of its host application + * on the bus and its path (logical location) within the host application. + * Such a service object can implement any number of interfaces, i.e. groups + * methods and signals, and can create a TQT_DBusProxy instance for every one + * your application needs to work with. + * + * See section @ref dbusclient for documentation on how to use TQT_DBusProxy + */ +class TQDBUS_EXPORT TQT_DBusProxy : public TQObject +{ + Q_OBJECT + +public: + /** + * @brief Creates a proxy without binding it to a service or connection + * + * This basic constructor allows to create a proxy and specify the peer + * object and interface later on. + * + * @param parent TQObject parent + * @param name TQObject name + */ + TQT_DBusProxy(TQObject* parent = 0, const char* name = 0); + + /** + * @brief Creates a proxy on a given connection without binding it to a + * service + * + * Similar to the above constructor, it does not yet specify and details + * about the proxy's peer, but already specifies which connection to work + * on. + * + * This can be useful to monitor all signal on a connection without + * filtering for a specific peer. + * + * @param connection the D-Bus connection to work on + * @param parent TQObject parent + * @param name TQObject name + */ + TQT_DBusProxy(const TQT_DBusConnection& connection, TQObject* parent = 0, + const char* name = 0); + + /** + * @brief Creates a proxy for a given peer on a given connection + * + * This creates a proxy for a specific peer object-interface combination + * It is equvalent to creating an "empty" proxy and calling setConnection(), + * setService(), setPath() and setInterface() manually. + * + * @param service the name the peer's host application uses on the bus + * @param path the peer object's path within its host application + * @param interface the interface to work with + * @param connection the D-Bus connection to work on + * @param parent TQObject parent + * @param name TQObject name + */ + TQT_DBusProxy(const TQString& service, const TQString& path, + const TQString& interface, const TQT_DBusConnection& connection, + TQObject* parent = 0, const char* name = 0); + + /** + * @brief Destroys the proxy instance + */ + virtual ~TQT_DBusProxy(); + + /** + * @brief Sets the D-Bus connection to work on + * + * Disconnects from any previously used connection and connects + * to the new connection's signal distribution. + * If no peer information has been provided at creation time or through + * the other set methods, the instance's signal dbusSignal() will emit + * all signals received on the given connection. + * + * @param connection the D-Bus connection to work on + * + * @return @c true if connecting to the new connection's signal succeeded, + * @c false if it failed, e.g. if the connection is a "null" + * connection + * + * @see connection() + * @see setService() + * @see setPath() + * @see setInterface() + */ + bool setConnection(const TQT_DBusConnection& connection); + + /** + * @brief Returns the currently used D-Bus connection + * + * @see setConnection() + */ + const TQT_DBusConnection& connection() const; + + /** + * @brief Sets the peer's service name + * + * A non-empty service name is required if the proxy is to be used for + * method calls. See section @ref dbusconventions-servicename for details. + * + * If a string other than @c TQString() is set, it will be used to + * filter signals, i.e. a signal received by the proxy will only be emitted + * if the service name matches. + * + * @param service the peer's name on the bus + * + * @see service() + * @see setPath() + * @see setInterface() + */ + void setService(const TQString& service); + + /** + * @brief Returns the peer's service name + * + * @return the peer object's service name + * + * @see setService() + */ + TQString service() const; + + /** + * @brief Sets the peer's object path + * + * A non-empty object path is required if the proxy is to be used for + * method calls. See section @ref dbusconventions-objectpath for details. + * + * If a string other than @c TQString() is set, it will be used to + * filter signals, i.e. a signal received by the proxy will only be emitted + * if the object path matches. + * + * @param path the peer's object path inside its host application + * (logical address) + * + * @see path() + * @see setService() + * @see setInterface() + */ + void setPath(const TQString& path); + + /** + * @brief Returns the peer's object path + * + * @return the peer object's path + * + * @see setPath() + */ + TQString path() const; + + /** + * @brief Sets the name of the peer interface + * + * A non-empty interface name is required if the proxy is to be used for + * method calls. See section @ref dbusconventions-interfacename for + * details. + * + * If a string other than @c TQString() is set, it will be used to + * filter signals, i.e. a signal received by the proxy will only be emitted + * if the interface name matches. + * + * @param interface the peer's interface to work with + * + * @see interface() + * @see setService() + * @see setPath() + */ + void setInterface(const TQString& interface); + + /** + * @brief Returns the name of the peer interface + * + * @return the peer object's interface + * + * @see setInterface() + */ + TQString interface() const; + + /** + * @brief Returns whether the proxy can be used to send method calls + * + * The capabilitly to send method calls depends on having all necessary + * base information: + * - Service name, see setService() + * - Object path, see setPath() + * - Interface, see setInterface() + * + * and a working connection, see setConnection() + * + * @return @c true if method calls can be sent, @c false if any of the three + * base information is missing or if the connection is not connected + * + * @see send() + * @see sendWithReply() + * @see sendWithAsyncReply() + */ + bool canSend() const; + + /** + * @brief Sends a method call to the peer object + * + * This is roughly equivalent to calling a C++ method with no return value + * or like ignoring the it. + * + * @param method the name of the method to invoke + * @param params the method parameters. Use an empty list if the method + * does not require parameters + * + * @return @c true if sending succeeded, @c false if sending failed, + * the method name was empty or any of the conditions for + * successfull sending as described for canSend() are not met + * + * @see lastError() + * @see sendWithReply() + * @see sendWithAsyncReply() + * @see @ref dbusconventions-membername + */ + bool send(const TQString& method, const TQValueList& params) const; + + /** + * @brief Sends a method call to the peer object and waits for the reply + * + * This is roughly equivalent to calling a C++ method on a local object. + * + * @param method the name of the method to invoke + * @param params the method parameters. Use an empty list if the method + * does not require parameters + * @param error optional parameter to get any error directly + * + * @return a TQT_DBusMessage containing any return values of the invoked method. + * Will be an invalid message if an error occurs. The error can be + * accessed through the optional paramater @p error or through + * lastError() + * + * @see canSend() + * @see send() + * @see sendWithAsyncReply() + * @see @ref dbusconventions-membername + */ + TQT_DBusMessage sendWithReply(const TQString& method, + const TQValueList& params, TQT_DBusError* error = 0) const; + + /** + * @brief Sends a method call to the peer object but does not wait for an + * answer + * + * This is roughly equivalent to calling a C++ method on a local TQt + * event loop driven object, where the result of the method call is + * delivered later through a signal. + * + * @note as with TQt's asychronous classes this needs a running event loop + * + * @param method the name of the method to invoke + * @param params the method parameters. Use an empty list if the method + * does not require parameters + * + * @return a serial number to easily identify the reply once it is received + * or 0 if the call is not possible, i.e. the method name is empty + * or any of the conditions for canSend() are not met + * + * @warning if a asynchronous call is followed by a synchronous call, e.g. + * using sendWithReply(), without returning to the event loop, + * is recommended to call TQT_DBusConnection::scheduleDispatch() + * after the synchronous call to make sure any reply received + * during the blocking call is delivered + * + * @see asyncReply() + * @see send() + * @see sendWithReply() + * @see @ref dbusconventions-membername + */ + int sendWithAsyncReply(const TQString& method, const TQValueList& params); + + /** + * @brief Returns the last error seen by the proxy + * + * The last error can a connection error, e.g. sending a message failed due + * connection being lost, or the error of the last call to sendWithReply or + * the error of the last received asyncReply() + * + * @return the last dbus error seen by this proxy + */ + TQT_DBusError lastError() const; + +signals: + /** + * @brief Signal emitted for D-Bus signals from the peer + * + * Signals received on the proxy's connection are filtered by + * handleDBusSignal() for all proxy properties that are not empty. + * + * @param message the signal's content + * + * @see TQT_DBusMessage::SignalMessage + */ + void dbusSignal(const TQT_DBusMessage& message); + + /** + * @brief Signal emitted for received replies to asynchronous method calls + * + * If a method invoked by using sendWithAsyncReply() send a response, e.g. + * method return value or errors, this signal is emitted to notify the + * proxy's user. + * + * @param callID the method call's serial number as returned by + * sendWithAsyncReply() + * @param message the reply's content + * + * @see handleAsyncReply() + * @see TQT_DBusMessage::replySerialNumber() + */ + void asyncReply(int callID, const TQT_DBusMessage& message); + +protected slots: + /** + * @brief Handles D-Bus signals received on the proxy's connection + * + * The base implementation checks each non-empty property, i.e. service + * name, object path and interface, with the respective field of the + * signal's D-Bus message. + * + * If all available matches succeed, the message is emitted by + * dbusSignal(), otherwise it is discarded. + * + * @note Filtering for @c service will only happen if @c service is a + * unique D-Bus name, i.e. if it starts with a colon @c ":" since + * D-Bus signals carry the sender's unique name and filtering by a + * requested name would reject all signals. + * + * @param message the D-Bus signal message as received + * + * @see TQT_DBusMessage::SignalMessage + */ + virtual void handleDBusSignal(const TQT_DBusMessage& message); + + /** + * @brief Handles replies to asynchronous method calls + * + * The base implementation simply extracts the reply's error and makes + * it available for lastError(). It then emits asyncReply() + * + * @param message the D-Bus reply message as received + * + * @see TQT_DBusMessage::replySerialNumber() + */ + virtual void handleAsyncReply(const TQT_DBusMessage& message); + +private: + class Private; + Private* d; + +private: + TQT_DBusProxy(const TQT_DBusProxy&); + TQT_DBusProxy& operator=(const TQT_DBusProxy&); +}; + +#endif + diff --git a/src/tqdbusserver.cpp b/src/tqdbusserver.cpp new file mode 100644 index 0000000..6bad746 --- /dev/null +++ b/src/tqdbusserver.cpp @@ -0,0 +1,60 @@ +/* qdbusserver.cpp + * + * Copyright (C) 2005 Harald Fernengel + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include "tqdbusserver.h" +#include "tqdbusconnection_p.h" + +TQT_DBusServer::TQT_DBusServer(const TQString &addr, TQObject *parent) + : TQObject(parent) +{ + d = new TQT_DBusConnectionPrivate(this); + + if (addr.isEmpty()) + return; + + d->setServer(dbus_server_listen(addr.utf8().data(), &d->error)); +} + +bool TQT_DBusServer::isConnected() const +{ + return d->server && dbus_server_get_is_connected(d->server); +} + +TQT_DBusError TQT_DBusServer::lastError() const +{ + return d->lastError; +} + +TQString TQT_DBusServer::address() const +{ + TQString addr; + if (d->server) { + char *c = dbus_server_get_address(d->server); + addr = TQString::fromUtf8(c); + dbus_free(c); + } + + return addr; +} + +#include "tqdbusserver.moc" diff --git a/src/tqdbusserver.h b/src/tqdbusserver.h new file mode 100644 index 0000000..0660a87 --- /dev/null +++ b/src/tqdbusserver.h @@ -0,0 +1,53 @@ +/* qdbusserver.h TQT_DBusServer object + * + * Copyright (C) 2005 Harald Fernengel + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSSERVER_H +#define TQDBUSSERVER_H + +#include "tqdbusmacros.h" +#include + +class TQString; + +class TQT_DBusConnectionPrivate; +class TQT_DBusError; + + +class TQDBUS_EXPORT TQT_DBusServer: public TQObject +{ + Q_OBJECT + +public: + TQT_DBusServer(const TQString &address, TQObject *parent = 0); + + bool isConnected() const; + TQT_DBusError lastError() const; + TQString address() const; + +private: + TQT_DBusServer(const TQT_DBusServer&); + TQT_DBusServer& operator=(const TQT_DBusServer&); + TQT_DBusConnectionPrivate *d; +}; + +#endif diff --git a/src/tqdbusunixfd.cpp b/src/tqdbusunixfd.cpp new file mode 100644 index 0000000..3aa4ba2 --- /dev/null +++ b/src/tqdbusunixfd.cpp @@ -0,0 +1,95 @@ +/* tqdbusunixfd.cpp DBUS unix file handle data type + * + * Copyright (C) 2013 Slávek Banko + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#include +#include "tqdbusunixfd.h" + +TQT_DBusUnixFd::TQT_DBusUnixFd() : d(new TQT_DBusUnixFdPrivate()) +{ + d->ref(); + d->fd = -1; +}; + +TQT_DBusUnixFd::TQT_DBusUnixFd(const TQT_DBusUnixFd& other) : d(other.d) +{ + d->ref(); +} + +TQT_DBusUnixFd::TQT_DBusUnixFd(int other) : d(0) +{ + setFileDescriptor(other); +} + +TQT_DBusUnixFd::~TQT_DBusUnixFd() +{ + if (d && d->deref() ) { + if ( isValid() ) { + close(d->fd); + } + delete d; + } +} + +bool TQT_DBusUnixFd::isValid() const +{ + return d ? d->fd != -1 : false; +} + +int TQT_DBusUnixFd::fileDescriptor() const +{ + return d ? d->fd : -1; +} + +void TQT_DBusUnixFd::setFileDescriptor(int fileDescriptor) +{ + giveFileDescriptor(fileDescriptor != -1 ? dup(fileDescriptor) : -1); +} + +void TQT_DBusUnixFd::giveFileDescriptor(int fileDescriptor) +{ + if ( d && d->deref() ) { + if ( isValid() ) { + close(d->fd); + } + } + else { + d = new TQT_DBusUnixFdPrivate; + } + d->ref(); + d->fd = fileDescriptor; +} + +TQT_DBusUnixFd &TQT_DBusUnixFd::operator=( const TQT_DBusUnixFd &other ) +{ + if (other.d) { + other.d->ref(); + } + if ( d && d->deref() ) { + if ( isValid() ) { + close(d->fd); + } + delete d; + } + d = other.d; + return *this; +} diff --git a/src/tqdbusunixfd.h b/src/tqdbusunixfd.h new file mode 100644 index 0000000..9f48a37 --- /dev/null +++ b/src/tqdbusunixfd.h @@ -0,0 +1,150 @@ +/* tqdbusunixfd.h DBUS unix file handle data type + * + * Copyright (C) 2013 Slávek Banko + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSUNIXFD_H +#define TQDBUSUNIXFD_H + +#include "dbus/dbus.h" +#ifndef QT_H +#include "ntqshared.h" +#endif // QT_H +#include "tqdbusmacros.h" + + +#ifndef DBUS_TYPE_UNIX_FD +#define DBUS_TYPE_UNIX_FD ((int) 'h') +#endif + +#ifndef DBUS_TYPE_UNIX_FD_AS_STRING +#define DBUS_TYPE_UNIX_FD_AS_STRING "h" +#endif + +/** + * @brief Class for representing D-Bus unix file handles + * + * This data type is necessary to correctly represent unix file handles in the + * context of D-Bus messages, since normal strings have a different D-Bus + * signature than unix file handles. + * + * @see @ref dbusconventions-unixfd + */ +class TQDBUS_EXPORT TQT_DBusUnixFd +{ +public: + /** + * @brief Creates an empty and invalid unix file handle + */ + TQT_DBusUnixFd(); + + /** + * @brief Creates copy of the given @p other unix file handle + * + * @param other the unix file handle to copy + */ + TQT_DBusUnixFd(const TQT_DBusUnixFd& other); + + /** + * @brief Creates copy of the given @p other unix file handle + * + * @param other the unix file handle to copy + */ + TQT_DBusUnixFd(int other); + + /** + * @brief Destroys the unix file handle + */ + virtual ~TQT_DBusUnixFd(); + + /** + * @brief Returns whether the current content is considered a valid unix file handle + * + * @return \c true if the object's content describe a valid unix file handle, + * otherwise @c false + * + * @see @ref dbusconventions-unixfd + */ + bool isValid() const; + + /** + * @brief Get unix file handle + * + * @see @ref dbusconventions-unixfd + */ + int fileDescriptor() const; + + /** + * @brief Set new unix file handle + * + * @see @ref dbusconventions-unixfd + */ + void setFileDescriptor(int fileDescriptor); + + /** + * @brief Give unix file handle + * + * @see @ref dbusconventions-unixfd + */ + void giveFileDescriptor(int fileDescriptor); + + /** + * @brief Copy unix file handle from TQT_DBusUnixFd + * + * @see @ref dbusconventions-unixfd + */ + TQT_DBusUnixFd &operator=( const TQT_DBusUnixFd &other ); + + /** + * @brief Checks if the given @p other variant is equal to this one + * + * @param other unix file handle to compare with + * + * @return @c true if both use same file handle, otherwise + * @c false + */ + inline bool operator==(const TQT_DBusUnixFd& other) const + { + return (&other == this) || (other.d == d); + } + + /** + * @brief Checks if the given @p other variant is not equal to this one + * + * @param other unix file handle to compare with + * + * @return @c true if both use different file handle, otherwise + * @c false + */ + inline bool operator!=(const TQT_DBusUnixFd& other) const + { + return (&other != this) && (other.d != d); + } + + +protected: + struct TQT_DBusUnixFdPrivate : public TQShared { + int fd; + } *d; + +}; + +#endif diff --git a/src/tqdbusvariant.h b/src/tqdbusvariant.h new file mode 100644 index 0000000..11c0ec5 --- /dev/null +++ b/src/tqdbusvariant.h @@ -0,0 +1,120 @@ +/* qdbusvariant.h DBUS variant struct + * + * Copyright (C) 2005 Harald Fernengel + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + */ + +#ifndef TQDBUSVARIANT_H +#define TQDBUSVARIANT_H + +#include "tqdbusmacros.h" +#include "tqdbusdata.h" + +#include + +/** + * @brief Data type for representing a D-Bus variant + * + * When D-Bus methods or signal require that a paramater can have any of the + * D-Bus data types, a D-Bus variant can be used. + * + * Basically a D-Bus variant includes the actual data and a D-Bus data signature + * to allow a receiver to determine the contents. + * + * Since the TQT_DBusVariant's #value member will already be fully de-marshalled, + * a receiver using this bindings can savely ignore the signature if it doesn't + * need it for a different purpose (e.g. logging). + * + * However, when creating a TQT_DBusVariant object for sending, make sure the + * #signature member is correctly setup, for example by using the #value + * member's buildDBusSignature() method. + * + * @code + * TQT_DBusVariant variant; + * + * variant.value = TQT_DBusData::fromInt32(131719); + * variant.signature = variant.value.buildDBusSignature(); + * @endcode + */ +class TQDBUS_EXPORT TQT_DBusVariant +{ +public: + /** + * @brief Creates an empty variant object + */ + TQT_DBusVariant() {} + + /** + * @brief Copies the given @p other variant object + * + * @param other the variant object to copy from + */ + TQT_DBusVariant(const TQT_DBusVariant& other) + { + signature = other.signature; + value = other.value; + } + + /** + * @brief Checks if the given @p other variant is equal to this one + * + * @param other the variant object to compare with + * + * @return @c true if both #signature and #value are equal, otherwise + * @c false + */ + inline bool operator==(const TQT_DBusVariant& other) const + { + if (&other == this) return true; + + return signature == other.signature && value == other.value; + } + + /** + * @brief Checks if the given @p other variant is not equal to this one + * + * @param other the variant object to compare with + * + * @return @c true if either #signature or #value is different, otherwise + * @c false + */ + inline bool operator!=(const TQT_DBusVariant& other) const + { + if (&other == this) return false; + + return signature != other.signature || value != other.value; + } + +public: + /** + * @brief The D-Bus data signature of the data contained in #value + * + * @see TQT_DBusData::buildDBusSignature() + */ + TQString signature; + + /** + * @brief The D-Bus data type to transport as a variant + */ + TQT_DBusData value; +}; + +#endif + diff --git a/tools/dbusxml2qt3/LICENSE b/tools/dbusxml2qt3/LICENSE deleted file mode 100644 index 1edf08c..0000000 --- a/tools/dbusxml2qt3/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/dbusxml2qt3/classgen.cpp b/tools/dbusxml2qt3/classgen.cpp deleted file mode 100644 index 12051c0..0000000 --- a/tools/dbusxml2qt3/classgen.cpp +++ /dev/null @@ -1,1091 +0,0 @@ -/* -* Copyright (C) 2007 Kevin Krammer -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and associated documentation files (the "Software"), -* to deal in the Software without restriction, including without limitation -* the rights to use, copy, modify, merge, publish, distribute, sublicense, -* and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -* OTHER DEALINGS IN THE SOFTWARE. -*/ - -// TQt includes -#include -#include -#include -#include - -// local includes -#include "classgen.h" -#include "methodgen.h" - -class Set : public TQMap -{ -public: - void insertString(const TQString& key) - { - insert(key, true); - } - - void removeString(const TQString& key) - { - erase(key); - } - - void insertStringList(const TQStringList& list) - { - TQStringList::const_iterator it = list.begin(); - TQStringList::const_iterator endIt = list.end(); - for (; it != endIt; ++it) - { - insert(*it, true); - } - } -}; - -static void writeFileHeader(TQTextStream& stream) -{ - stream << "// File autogenerated" << endl; - stream << endl; -} - -static void writeFileFooter(TQTextStream& stream) -{ - stream << "// End of File" << endl; - stream << endl; -} - -static void openIncludeGuard(const TQString& className, TQTextStream& stream) -{ - stream << "#if !defined(" << className.upper() << "_H_INCLUDED)" << endl; - stream << "#define " << className.upper() << "_H_INCLUDED" << endl; - stream << endl; -} - -static void closeIncludeGuard(const TQString& className, TQTextStream& stream) -{ - stream << "#endif //" << className.upper() << "_H_INCLUDED" << endl; - stream << endl; -} - -static void openNamespaces(const TQStringList& namespaces, TQTextStream& stream) -{ - TQStringList::const_iterator it = namespaces.begin(); - TQStringList::const_iterator endIt = namespaces.end(); - for (; it != endIt; ++it) - { - stream << "namespace " << *it << endl; - stream << "{" << endl; - } - stream << endl; -} - -static void closeNamespaces(const TQStringList& namespaces, TQTextStream& stream) -{ - TQStringList::const_iterator it = namespaces.end(); - TQStringList::const_iterator endIt = namespaces.end(); - for (--it; it != endIt; --it) - { - stream << "}; // namespace " << *it << endl; - stream << endl; - } -} - -static void writeIncludes(const TQString& description, const TQStringList& includes, - TQTextStream& stream) -{ - if (includes.isEmpty()) return; - - stream << "// " << description << " includes" << endl; - - TQStringList::const_iterator it = includes.begin(); - TQStringList::const_iterator endIt = includes.end(); - for (;it != endIt; ++it) - { - stream << "#include " << *it << endl; - } - - stream << endl; -} - -static void extractHeaderIncludes(const Method& method, - TQMap& includes) -{ - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - for (; it != endIt; ++it) - { - if ((*it).headerIncludes.isEmpty()) continue; - - TQMap::const_iterator mapIt = - (*it).headerIncludes.begin(); - TQMap::const_iterator mapEndIt = - (*it).headerIncludes.end(); - - for (; mapIt != mapEndIt; ++mapIt) - { - includes[mapIt.key()].insertStringList(mapIt.data()); - } - } -} - -static void extractForwardDeclarations(const Method& method, Set& forwards) -{ - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - for (; it != endIt; ++it) - { - if ((*it).forwardDeclarations.isEmpty()) continue; - - forwards.insertStringList((*it).forwardDeclarations); - } -} - -static void writeHeaderIncludes(const Class& classData, Class::Role role, - TQTextStream& stream) -{ - TQMap includes; - Set forwards; - - TQValueList::const_iterator it = classData.methods.begin(); - TQValueList::const_iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - if ((*it).arguments.isEmpty()) continue; - - extractHeaderIncludes(*it, includes); - extractForwardDeclarations(*it, forwards); - } - - it = classData.msignals.begin(); - endIt = classData.msignals.end(); - for (; it != endIt; ++it) - { - if ((*it).arguments.isEmpty()) continue; - - extractHeaderIncludes(*it, includes); - extractForwardDeclarations(*it, forwards); - } - - - TQValueList::const_iterator propertyIt = classData.properties.begin(); - TQValueList::const_iterator propertyEndIt = classData.properties.end(); - for (; propertyIt != propertyEndIt; ++propertyIt) - { - if (!(*propertyIt).headerIncludes.isEmpty()) - { - TQMap::const_iterator mapIt = - (*propertyIt).headerIncludes.begin(); - TQMap::const_iterator mapEndIt = - (*propertyIt).headerIncludes.end(); - - for (; mapIt != mapEndIt; ++mapIt) - { - includes[mapIt.key()].insertStringList(mapIt.data()); - } - } - - if (!(*propertyIt).forwardDeclarations.isEmpty()) - { - forwards.insertStringList((*propertyIt).forwardDeclarations); - } - } - - switch (role) - { - case Class::Interface: - includes["tqdbus"].insertString(""); - forwards.insertString("class TQT_DBusError"); - forwards.insertString("class TQDomElement"); - if (!classData.msignals.isEmpty()) - forwards.insertString("class TQString"); - if (!classData.asyncMethods.isEmpty()) - { - includes["TQt"].insertString(""); - forwards.erase("template class TQMap"); - - includes["tqdbus"].insertString(""); - forwards.erase("class TQT_DBusMessage"); - } - break; - - case Class::Proxy: - includes["TQt"].insertString(""); - forwards.insertString("class TQT_DBusConnection"); - forwards.insertString("class TQT_DBusError"); - forwards.insertString("class TQT_DBusMessage"); - forwards.insertString("class TQT_DBusProxy"); - forwards.insertString("class TQString"); - if (!classData.properties.isEmpty()) - forwards.insertString("class TQT_DBusVariant"); - if (!classData.asyncMethods.isEmpty()) - { - includes["TQt"].insertString(""); - forwards.erase("template class TQMap"); - } - break; - - case Class::Node: - includes["tqdbus"].insertString(""); - forwards.insertString("class TQT_DBusConnection"); - forwards.insertString("class TQString"); - break; - } - - includes["tqdbus"].insertString(""); - - if (!includes["TQt"].isEmpty()) - writeIncludes("TQt", includes["TQt"].keys(), stream); - - if (!includes["tqdbus"].isEmpty()) - writeIncludes("TQt D-Bus", includes["tqdbus"].keys(), stream); - - if (!includes["local"].isEmpty()) - writeIncludes("local", includes["local"].keys(), stream); - - stream << "// forward declarations" << endl; - Set::const_iterator setIt = forwards.begin(); - Set::const_iterator setEndIt = forwards.end(); - for (; setIt != setEndIt; ++setIt) - { - stream << setIt.key() << ";" << endl; - } - stream << endl; -} - -static void extractSourceIncludes(const Method& method, - TQMap& includes) -{ - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - for (; it != endIt; ++it) - { - if ((*it).sourceIncludes.isEmpty()) continue; - - TQMap::const_iterator mapIt = - (*it).sourceIncludes.begin(); - TQMap::const_iterator mapEndIt = - (*it).sourceIncludes.end(); - - for (; mapIt != mapEndIt; ++mapIt) - { - includes[mapIt.key()].insertStringList(mapIt.data()); - } - } -} - -static void writeSourceIncludes(const Class& classData, Class::Role role, - TQTextStream& stream) -{ - TQMap includes; - - TQValueList::const_iterator it = classData.methods.begin(); - TQValueList::const_iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - if ((*it).arguments.isEmpty()) continue; - - extractSourceIncludes(*it, includes); - } - - it = classData.msignals.begin(); - endIt = classData.msignals.end(); - for (; it != endIt; ++it) - { - if ((*it).arguments.isEmpty()) continue; - - extractSourceIncludes(*it, includes); - } - - TQValueList::const_iterator propertyIt = classData.properties.begin(); - TQValueList::const_iterator propertyEndIt = classData.properties.end(); - for (; propertyIt != propertyEndIt; ++propertyIt) - { - if ((*propertyIt).sourceIncludes.isEmpty()) continue; - - TQMap::const_iterator mapIt = - (*propertyIt).sourceIncludes.begin(); - TQMap::const_iterator mapEndIt = - (*propertyIt).sourceIncludes.end(); - - for (; mapIt != mapEndIt; ++mapIt) - { - includes[mapIt.key()].insertStringList(mapIt.data()); - } - } - - switch (role) - { - case Class::Interface: - includes["TQt"].insertString(""); - includes["tqdbus"].insertString(""); - includes["tqdbus"].insertString(""); - break; - - case Class::Proxy: - includes["tqdbus"].insertString(""); - includes["tqdbus"].insertString(""); - includes["tqdbus"].insertString(""); - if (!classData.properties.isEmpty()) - { - includes["tqdbus"].insertString(""); - includes["tqdbus"].insertString(""); - } - break; - - case Class::Node: - includes["TQt"].insertString(""); - includes["TQt"].insertString(""); - includes["tqdbus"].insertString(""); - includes["tqdbus"].insertString(""); - break; - } - - if (!includes["TQt"].isEmpty()) - writeIncludes("TQt", includes["TQt"].keys(), stream); - - if (!includes["tqdbus"].isEmpty()) - writeIncludes("TQt D-Bus", includes["tqdbus"].keys(), stream); - - if (!includes["local"].isEmpty()) - writeIncludes("local", includes["local"].keys(), stream); - - stream << endl; -} - -static void writeInterfaceIncludes(const TQValueList interfaces, - TQTextStream& stream) -{ - stream << "// interface classes includes" << endl; - - TQValueList::const_iterator it = interfaces.begin(); - TQValueList::const_iterator endIt = interfaces.end(); - for (; it != endIt; ++it) - { - stream << "#include \"" << (*it).name.lower() << ".h\"" << endl; - } - - stream << "#include \"introspectableinterface.h\"" << endl; - - stream << endl; -} - -static void openClassDeclaration(const Class& classData, - Class::Role role, TQTextStream& stream) -{ - switch (role) - { - case Class::Interface: - stream << "class " << classData.name << " : public TQT_DBusObjectBase" - << endl; - stream << "{" << endl; - stream << "public:" << endl; - stream << " virtual ~" << classData.name << "() {}" << endl; - stream << endl; - stream << " static void buildIntrospectionData(TQDomElement& interfaceElement);" << endl; - break; - - case Class::Proxy: - stream << "class " << classData.name << " : public TQObject" << endl; - stream << "{" << endl; - stream << " Q_OBJECT" << endl; - stream << " " << endl; - stream << "public:" << endl; - stream << " " << classData.name - << "(const TQString& service, const TQString& path, TQObject* parent = 0, const char* name = 0);" << endl; - stream << endl; - - stream << " virtual ~" << classData.name << "();" << endl; - stream << endl; - - stream << " void setConnection(const TQT_DBusConnection& connection);" - << endl; - break; - - case Class::Node: - stream << "class " << classData.name << " : public TQT_DBusObjectBase" - << endl; - stream << "{" << endl; - stream << "public:" << endl; - stream << " " << classData.name << "();" << endl; - stream << endl; - stream << " virtual ~" << classData.name << "();" << endl; - stream << endl; - stream << " bool registerObject(const TQT_DBusConnection& connection, " - << "const TQString& path);" << endl; - stream << endl; - stream << " void unregisterObject();" << endl; - stream << endl; - stream << "protected:" << endl; - stream << " virtual TQT_DBusObjectBase* createInterface(" - << "const TQString& interfaceName) = 0;" << endl; - stream << endl; - stream << "protected: // usually no need to reimplement" << endl; - stream << " virtual bool handleMethodCall(const TQT_DBusMessage& message);" << endl; - stream << endl; - stream << "private:" << endl; - stream << " class Private;" << endl; - stream << " Private* m_private;" << endl; - break; - } - - stream << endl; -} - -static void closeClassDeclaration(const Class& classData, Class::Role role, - TQTextStream& stream) -{ - switch (role) - { - case Class::Interface: - break; - - case Class::Proxy: - stream << "private: // Hiding copy constructor and assignment operator" << endl; - stream << " " << classData.name << "(const " - << classData.name << "&);" << endl; - stream << " " << classData.name << "& operator=(const " - << classData.name << "&);" << endl; - break; - - case Class::Node: - stream << "private: // Hiding copy constructor and assignment operator" << endl; - stream << " " << classData.name << "(const " - << classData.name << "&);" << endl; - stream << " " << classData.name << "& operator=(const " - << classData.name << "&);" << endl; - break; - } - stream << "}; // class " << classData.name << endl; - stream << endl; -} - -static void writeMethodDeclarations(const Class& classData, Class::Role role, - TQTextStream& stream) -{ - if (role == Class::Interface && !classData.asyncReplyMethods.isEmpty()) - { - stream << "public:" << endl; - - TQValueList::const_iterator it = - classData.asyncReplyMethods.begin(); - TQValueList::const_iterator endIt = - classData.asyncReplyMethods.end(); - for (; it != endIt; ++it) - { - Method method = *it; - method.name += "AsyncReply"; - - stream << " virtual void "; - MethodGenerator::writeMethodDeclaration(method, false, false, stream); - - stream << " virtual void " << (*it).name - << "AsyncError(int asyncCallId, const TQT_DBusError& error);" - << endl; - stream << endl; - } - } - - if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty()) - { - bool pureVirtual = true; - switch (role) - { - case Class::Interface: - pureVirtual = true; - stream << "protected:" << endl; - break; - - case Class::Proxy: - pureVirtual = false; - stream << "public:" << endl; - break; - - case Class::Node: // no variable methods - break; - } - - TQValueList::const_iterator it = classData.methods.begin(); - TQValueList::const_iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - if ((*it).async) continue; - - stream << " virtual bool "; - MethodGenerator::writeMethodDeclaration(*it, pureVirtual, true, stream); - } - - it = classData.asyncMethods.begin(); - endIt = classData.asyncMethods.end(); - for (; it != endIt; ++it) - { - Method method = *it; - method.name += "Async"; - - switch (role) - { - case Class::Interface: - stream << " virtual void "; - MethodGenerator::writeMethodDeclaration(method, pureVirtual, false, stream); - break; - - case Class::Proxy: - stream << " virtual bool "; - MethodGenerator::writeMethodDeclaration(method, pureVirtual, true, stream); - break; - - case Class::Node: // no async methods - break; - } - } - } - - if (!classData.properties.isEmpty()) - { - bool pureVirtual = true; - bool skip = false; - switch (role) - { - case Class::Interface: - tqWarning("Properties not yet supported for interfaces"); - skip = true; - pureVirtual = true; - break; - - case Class::Proxy: - pureVirtual = false; - stream << "public:" << endl; - stream << " virtual void setDBusProperty(const TQString& name," - << " const TQT_DBusVariant& variant, TQT_DBusError& error);" - << endl; - stream << " virtual TQT_DBusVariant getDBusProperty(const TQString& name, TQT_DBusError& error) const;" << endl; - stream << endl; - break; - - case Class::Node: // no node properties - skip = true; - break; - } - - if (!skip) - { - TQValueList::const_iterator it = classData.properties.begin(); - TQValueList::const_iterator endIt = classData.properties.end(); - for (; it != endIt; ++it) - { - MethodGenerator::writePropertyDeclaration(*it, pureVirtual, stream); - } - } - } - - switch (role) - { - case Class::Interface: - if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty()) - { - stream << "protected: // implement sending replies" << endl; - stream << " virtual void handleMethodReply(const TQT_DBusMessage& reply) = 0;" << endl; - stream << endl; - stream << "protected: // usually no need to reimplement" << endl; - stream << " virtual bool handleMethodCall(const TQT_DBusMessage& message);" << endl; - } - else - { - stream << "protected: // no methods to handle" << endl; - stream << " virtual bool handleMethodCall(const TQT_DBusMessage&) { return false; }" << endl; - } - break; - - case Class::Proxy: - { - if (!classData.msignals.isEmpty()) - { - stream << "protected slots: // usually no need to reimplement" << endl; - stream << " virtual void slotHandleDBusSignal(const TQT_DBusMessage& message);" << endl; - stream << endl; - } - - if (!classData.asyncReplySignals.isEmpty()) - { - if (classData.msignals.isEmpty()) - { - stream << "protected slots: // usually no need to reimplement" << endl; - } - stream << " virtual void slotHandleAsyncReply(int id, const TQT_DBusMessage& message);" << endl; - stream << endl; - } - - stream << "protected:" << endl; - stream << " TQT_DBusProxy* m_baseProxy;" << endl; - - if (!classData.asyncMethods.isEmpty()) - { - stream << endl; - stream << " TQMap m_asyncCalls;" << endl; - } - - break; - } - - case Class::Node: // not variable methods - break; - } - - stream << endl; -} - -static void writeSignalDeclarations(const Class& classData, Class::Role role, - TQTextStream& stream) -{ - if (classData.msignals.isEmpty() && classData.asyncReplySignals.isEmpty()) - return; - - TQString prefix; - switch (role) - { - case Class::Interface: - stream << "protected: // implement sending signals" << endl; - stream << " virtual bool handleSignalSend(const TQT_DBusMessage& reply) = 0;" << endl; - stream << " virtual TQString objectPath() const = 0;" << endl; - stream << endl; - stream << "protected: // for sending D-Bus signals" << endl; - prefix = " virtual bool emit"; - break; - - case Class::Proxy: - stream << "signals:" << endl; - stream << " void AsyncErrorResponseDetected(int asyncCallId, const TQT_DBusError error);" << endl << endl; - prefix = " void "; - break; - - case Class::Node: // no signals - break; - } - - TQValueList::const_iterator it = classData.msignals.begin(); - TQValueList::const_iterator endIt = classData.msignals.end(); - for (; it != endIt; ++it) - { - stream << prefix; - MethodGenerator::writeMethodDeclaration(*it, false, false, stream); - } - - it = classData.asyncReplySignals.begin(); - endIt = classData.asyncReplySignals.end(); - for (; it != endIt; ++it) - { - stream << prefix; - - Method signal = *it; - signal.name += "AsyncReply"; - - MethodGenerator::writeMethodDeclaration(signal, false, false, stream); - } - - stream << endl; -} - -static void writeSignalEmitters(const Class& classData, TQTextStream& stream) -{ - if (classData.msignals.isEmpty()) return; - - TQValueList::const_iterator it = classData.msignals.begin(); - TQValueList::const_iterator endIt = classData.msignals.end(); - for (; it != endIt; ++it) - { - MethodGenerator::writeSignalEmitter(classData, *it, stream); - } - - stream << endl; -} - -static void writeMethodCallDeclarations(const Class& classData, - TQTextStream& stream) -{ - TQValueList::const_iterator it = classData.methods.begin(); - TQValueList::const_iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - stream << " "; - MethodGenerator::writeMethodCallDeclaration(*it, stream); - } - - if (!classData.asyncReplyMethods.isEmpty()) - { - stream << "protected:" << endl; - stream << " TQMap m_asyncCalls;" << endl; - stream << endl; - } -} - -static void writeInterfaceAsyncReplyHandlers(const Class& classData, - TQTextStream& stream) -{ - if (classData.asyncReplyMethods.isEmpty()) return; - - TQValueList::const_iterator it = classData.asyncReplyMethods.begin(); - TQValueList::const_iterator endIt = classData.asyncReplyMethods.end(); - for (; it != endIt; ++it) - { - MethodGenerator::writeInterfaceAsyncReplyHandler(classData, *it, stream); - } -} - -static void writeMethodCalls(const Class& classData, TQTextStream& stream) -{ - TQValueList::const_iterator it = classData.methods.begin(); - TQValueList::const_iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - if ((*it).async) continue; - - MethodGenerator::writeMethodCall(classData, *it, stream); - } - - it = classData.asyncMethods.begin(); - endIt = classData.asyncMethods.end(); - for (; it != endIt; ++it) - { - MethodGenerator::writeMethodCall(classData, *it, stream); - } -} - -static void writeProxyMethods(const Class& classData, TQTextStream& stream) -{ - TQValueList::const_iterator it = classData.methods.begin(); - TQValueList::const_iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - if ((*it).async) continue; - - MethodGenerator::writeProxyMethod(classData.name, *it, stream); - } - - it = classData.asyncMethods.begin(); - endIt = classData.asyncMethods.end(); - for (; it != endIt; ++it) - { - MethodGenerator::writeProxyMethod(classData.name, *it, stream); - } -} - -static void writeProxyProperties(const Class& classData, TQTextStream& stream) -{ - if (classData.properties.isEmpty()) return; - - MethodGenerator::writeProxyGenericProperty(classData, stream); - - TQValueList::const_iterator it = classData.properties.begin(); - TQValueList::const_iterator endIt = classData.properties.end(); - for (; it != endIt; ++it) - { - MethodGenerator::writeProxyProperty(classData, *it, stream); - } -} - -static void splitAsyncProxyMethods(Class& classData) -{ - // create the async identifier - Argument idArgMethod; - idArgMethod.name = "asyncCallId"; - idArgMethod.signature = "int"; - idArgMethod.isPrimitive = true; - idArgMethod.direction = Argument::Out; - - Argument idArgSignal = idArgMethod; - idArgSignal.direction = Argument::In; - - TQValueList::iterator it = classData.methods.begin(); - TQValueList::iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - if (!(*it).async) continue; - - Method method = *it; - - TQValueList methodArgs; - TQValueList signalArgs; - - // add id argument - methodArgs << idArgMethod; - signalArgs << idArgSignal; - - // split in/out arguments: "in" belong to the method, "out" to the new signal - TQValueList::const_iterator argIt = method.arguments.begin(); - TQValueList::const_iterator argEndIt = method.arguments.end(); - for (; argIt != argEndIt; ++argIt) - { - if ((*argIt).direction == Argument::Out) - { - // signal parameters are "out" but have "in" signature, - // e.g. "const T&" - Argument arg = *argIt; - arg.direction = Argument::In; - - signalArgs << arg; - } - else - methodArgs << *argIt; - } - - // change method - method.arguments = methodArgs; - - classData.asyncMethods << method; - - // create "callback" signal - Method signal = method; - signal.arguments = signalArgs; - - classData.asyncReplySignals << signal; - } -} - -static void splitAsyncInterfaceMethods(Class& classData) -{ - // create the async identifier - Argument idArgMethod; - idArgMethod.name = "asyncCallId"; - idArgMethod.signature = "int"; - idArgMethod.isPrimitive = true; - idArgMethod.direction = Argument::In; - - Argument idArgReply = idArgMethod; - - TQValueList::iterator it = classData.methods.begin(); - TQValueList::iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - if (!(*it).async) continue; - - Method method = *it; - - TQValueList methodArgs; - TQValueList replyArgs; - - // add id argument - methodArgs << idArgMethod; - replyArgs << idArgReply; - - // split in/out arguments: "in" belong to the call, "out" to the reply - TQValueList::const_iterator argIt = method.arguments.begin(); - TQValueList::const_iterator argEndIt = method.arguments.end(); - for (; argIt != argEndIt; ++argIt) - { - if ((*argIt).direction == Argument::Out) - { - // reply parameters are "out" for the service but "in" for - // the reply handler - Argument arg = *argIt; - arg.direction = Argument::In; - - replyArgs << arg; - } - else - methodArgs << *argIt; - } - - // change method - method.arguments = methodArgs; - - classData.asyncMethods << method; - - // create reply handler - Method reply = method; - reply.arguments = replyArgs; - - classData.asyncReplyMethods << reply; - } -} - -bool ClassGenerator::initStreams(const TQString& baseName, - TQTextStream& headerStream, - TQTextStream& sourceStream) -{ - TQFile* headerFile = new TQFile(baseName + ".h"); - TQFile* sourceFile = new TQFile(baseName + ".cpp"); - - if (!headerFile->open(IO_WriteOnly) || !sourceFile->open(IO_WriteOnly)) - { - delete headerFile; - delete sourceFile; - - return false; - } - - headerStream.setDevice(TQT_TQIODEVICE(headerFile)); - sourceStream.setDevice(TQT_TQIODEVICE(sourceFile)); - - // create header - writeFileHeader(headerStream); - openIncludeGuard(baseName, headerStream); - - // create source - writeFileHeader(sourceStream); - sourceStream << "// declaration include" << endl; - sourceStream << "#include \"" << baseName << ".h\"" << endl; - sourceStream << endl; - - return true; -} - -bool ClassGenerator::finishStreams(const TQString& baseName, - TQTextStream& headerStream, - TQTextStream& sourceStream) -{ - closeIncludeGuard(baseName, headerStream); - writeFileFooter(headerStream); - writeFileFooter(sourceStream); - - TQIODevice* device = headerStream.device(); - headerStream.unsetDevice(); - delete device; - - device = sourceStream.device(); - sourceStream.unsetDevice(); - delete device; - - return true; -} - -bool ClassGenerator::extractClass(const TQDomElement& interfaceElement, - Class& classData) -{ - tqDebug("ClassGenerator: processing interface '%s'", - interfaceElement.attribute("name").latin1()); - - classData.dbusName = interfaceElement.attribute("name"); - - TQStringList nameParts = TQStringList::split('.', classData.dbusName); - - if (nameParts.count() < 2) return false; - - classData.name = nameParts.back(); - nameParts.pop_back(); - classData.namespaces = nameParts; - - return MethodGenerator::extractMethods(interfaceElement, classData); -} - -bool ClassGenerator::generateInterface(const Class& classData, - TQTextStream& headerStream, - TQTextStream& sourceStream) -{ - Class classDataCopy = classData; - splitAsyncInterfaceMethods(classDataCopy); - - // create header - writeHeaderIncludes(classDataCopy, Class::Interface, headerStream); - - openNamespaces(classDataCopy.namespaces, headerStream); - openClassDeclaration(classDataCopy, Class::Interface, headerStream); - - writeSignalDeclarations(classDataCopy, Class::Interface, headerStream); - writeMethodDeclarations(classDataCopy, Class::Interface, headerStream); - writeMethodCallDeclarations(classDataCopy, headerStream); - - closeClassDeclaration(classDataCopy, Class::Interface, headerStream); - closeNamespaces(classDataCopy.namespaces, headerStream); - - // create source - writeSourceIncludes(classDataCopy, Class::Interface, sourceStream); - - openNamespaces(classDataCopy.namespaces, sourceStream); - - MethodGenerator::writeIntrospectionDataMethod(classDataCopy, sourceStream); - - writeSignalEmitters(classDataCopy, sourceStream); - writeInterfaceAsyncReplyHandlers(classDataCopy, sourceStream); - writeMethodCalls(classDataCopy, sourceStream); - - MethodGenerator::writeInterfaceMainMethod(classDataCopy, sourceStream); - - closeNamespaces(classDataCopy.namespaces, sourceStream); - - return true; -} - -bool ClassGenerator::generateProxy(const Class& classData, - TQTextStream& headerStream, - TQTextStream& sourceStream) -{ - Class classDataCopy = classData; - splitAsyncProxyMethods(classDataCopy); - - // create header - writeHeaderIncludes(classDataCopy, Class::Proxy, headerStream); - - openNamespaces(classDataCopy.namespaces, headerStream); - openClassDeclaration(classDataCopy, Class::Proxy, headerStream); - - writeSignalDeclarations(classDataCopy, Class::Proxy, headerStream); - writeMethodDeclarations(classDataCopy, Class::Proxy, headerStream); - - closeClassDeclaration(classDataCopy, Class::Proxy, headerStream); - closeNamespaces(classDataCopy.namespaces, headerStream); - - // create source - writeSourceIncludes(classDataCopy, Class::Proxy, sourceStream); - - openNamespaces(classDataCopy.namespaces, sourceStream); - - MethodGenerator::writeProxyBegin(classDataCopy, sourceStream); - - writeProxyMethods(classDataCopy, sourceStream); - - writeProxyProperties(classDataCopy, sourceStream); - - if (!classDataCopy.msignals.isEmpty()) - MethodGenerator::writeSignalHandler(classDataCopy, sourceStream); - - if (!classDataCopy.asyncReplySignals.isEmpty()) - MethodGenerator::writeProxyAsyncReplyHandler(classDataCopy, sourceStream); - - closeNamespaces(classDataCopy.namespaces, sourceStream); - - return true; -} - -bool ClassGenerator::generateNode(const Class& classData, - const TQValueList& interfaces, - TQTextStream& headerStream, - TQTextStream& sourceStream) -{ - // create header - writeHeaderIncludes(classData, Class::Node, headerStream); - - openNamespaces(classData.namespaces, headerStream); - openClassDeclaration(classData, Class::Node, headerStream); - - closeClassDeclaration(classData, Class::Node, headerStream); - closeNamespaces(classData.namespaces, headerStream); - - // create source - writeSourceIncludes(classData, Class::Node, sourceStream); - writeInterfaceIncludes(interfaces, sourceStream); - - openNamespaces(classData.namespaces, sourceStream); - - MethodGenerator::writeNodePrivate(classData, sourceStream); - - MethodGenerator::writeNodeBegin(classData, sourceStream); - - MethodGenerator::writeNodeMethods(classData, interfaces, sourceStream); - - closeNamespaces(classData.namespaces, sourceStream); - - return true; -} - -// End of File diff --git a/tools/dbusxml2qt3/classgen.h b/tools/dbusxml2qt3/classgen.h deleted file mode 100644 index 3597890..0000000 --- a/tools/dbusxml2qt3/classgen.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* Copyright (C) 2007 Kevin Krammer -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and associated documentation files (the "Software"), -* to deal in the Software without restriction, including without limitation -* the rights to use, copy, modify, merge, publish, distribute, sublicense, -* and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -* OTHER DEALINGS IN THE SOFTWARE. -*/ - -#if !defined(CLASSGEN_H_INCLUDED) -#define CLASSGEN_H_INCLUDED - -// forward declarations -class Class; -class TQDomElement; -class TQTextStream; -template class TQValueList; - -class ClassGenerator -{ -public: - static bool initStreams(const TQString& baseName, - TQTextStream& headerStream, TQTextStream& sourceStream); - - static bool finishStreams(const TQString& baseName, - TQTextStream& headerStream, TQTextStream& sourceStream); - - static bool extractClass(const TQDomElement& interfaceElement, Class& classData); - static bool generateInterface(const Class& classData, - TQTextStream& headerStream, - TQTextStream& sourceStream); - static bool generateProxy(const Class& classData, - TQTextStream& headerStream, TQTextStream& sourceStream); - static bool generateNode(const Class& classData, - const TQValueList& interfaces, - TQTextStream& headerStream, TQTextStream& sourceStream); -}; - -#endif - -// End of File diff --git a/tools/dbusxml2qt3/main.cpp b/tools/dbusxml2qt3/main.cpp deleted file mode 100644 index 0208072..0000000 --- a/tools/dbusxml2qt3/main.cpp +++ /dev/null @@ -1,637 +0,0 @@ -/* -* Copyright (C) 2007 Kevin Krammer -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and associated documentation files (the "Software"), -* to deal in the Software without restriction, including without limitation -* the rights to use, copy, modify, merge, publish, distribute, sublicense, -* and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -* OTHER DEALINGS IN THE SOFTWARE. -*/ - -// standard includes -#include -#include - -// TQt includes -#include -#include -#include -#include - -// local includes -#include "classgen.h" -#include "methodgen.h" - -typedef TQMap OptionMap; - -void usage(); - -OptionMap parseOptions(int argc, char** argv); - -bool checkForOption(const OptionMap& options, const TQString& option) -{ - return options.find(option) != options.end(); -} - -int main(int argc, char** argv) -{ - const OptionMap options = parseOptions(argc, argv); - - if (!checkForOption(options, "filename")) - { - std::cerr << "dbusxml2qt3: introspection data file missing" << std::endl; - usage(); - exit(1); - } - - TQString fileName = options["filename"]; - TQFile file(fileName); - if (!file.exists()) - { - std::cerr << "dbusxml2qt3: introspection data file '" - << fileName.local8Bit().data() - << "' does not exist" << std::endl; - exit(2); - } - - if (!file.open(IO_ReadOnly)) - { - std::cerr << "dbusxml2qt3: introspection data file '" - << fileName.local8Bit().data() - << "' cannot be read" << std::endl; - exit(2); - } - - TQDomDocument document; - - if (!document.setContent(&file)) - { - file.close(); - - std::cerr << "dbusxml2qt3: introspection data file '" - << fileName.local8Bit().data() - << "' cannot be parsed" << std::endl; - exit(2); - } - - file.close(); - - TQDomElement rootElement = document.documentElement(); - if (rootElement.isNull() || rootElement.tagName() != "node") - { - std::cerr << "dbusxml2qt3: introspection data file '" - << fileName.local8Bit().data() - << "' does not have a 'node' element as its root node" - << std::endl; - exit(2); - } - - TQValueList interfaces; - bool hasIntrospectable = false; - - TQDomNode child = rootElement.firstChild(); - for (; !child.isNull(); child = child.nextSibling()) - { - if (!child.isElement()) continue; - - TQDomElement element = child.toElement(); - - if (element.tagName() == "interface") - { - if (!element.attribute("name").isEmpty()) - { - Class classData; - if (ClassGenerator::extractClass(element, classData)) - { - if (classData.dbusName == "org.freedesktop.DBus.Introspectable") - hasIntrospectable = true; - else - interfaces << classData; - } - } - } - } - - if (interfaces.isEmpty()) - { - std::cerr << "dbusxml2qt3: introspection data file '" - << fileName.local8Bit().data() - << "' does not contain any valid interface descriptions" - << std::endl; - exit(3); - } - - bool generateProxies = checkForOption(options, "proxy"); - bool generateInterfaces = checkForOption(options, "interface"); - bool generateNode = checkForOption(options, "node"); - - // if no specific option is selected, we generate everything - bool generateAll = !(generateProxies || generateInterfaces || generateNode); - - if (checkForOption(options, "classname")) - { - // class name only useful for single interfaces or just node - if (interfaces.count() > 1 && (generateAll || generateInterfaces || generateProxies)) - { - std::cerr << "dbusxml2qt3: class name option specified but " - << "introspection data file '" - << fileName.local8Bit().data() - << "' contains more than one interface description" - << std::endl; - exit(3); - } - - // class name for node is handled differently later on - if (!generateNode) - { - TQStringList nameParts = TQStringList::split("::", options["classname"]); - - interfaces[0].name = nameParts.back(); - - nameParts.pop_back(); - interfaces[0].namespaces = nameParts; - } - } - - if (checkForOption(options, "namespace")) - { - TQStringList nameParts = TQStringList::split("::", options["namespace"]); - - TQValueList::iterator it = interfaces.begin(); - TQValueList::iterator endIt = interfaces.end(); - for (; it != endIt; ++it) - { - (*it).namespaces = nameParts; - } - } - - if (generateInterfaces || generateAll) - { - TQTextStream headerStream; - TQTextStream sourceStream; - - TQString baseName = options["interface"]; - if (!baseName.isEmpty()) - { - if (!ClassGenerator::initStreams(baseName, headerStream, sourceStream)) - { - std::cerr << "dbusxml2qt3: proxy files, using base name '" - << baseName.local8Bit().data() - << "', could not be opened for writing" - << std::endl; - exit(4); - } - } - - TQValueList::const_iterator it = interfaces.begin(); - TQValueList::const_iterator endIt = interfaces.end(); - for (; it != endIt; ++it) - { - if (baseName.isEmpty()) - { - if (!ClassGenerator::initStreams((*it).name.lower() + "interface", - headerStream, sourceStream)) - { - std::cerr << "dbusxml2qt3: interface files, using base name '" - << baseName.local8Bit().data() - << "', could not be opened for writing" - << std::endl; - exit(4); - } - } - - ClassGenerator::generateInterface(*it, headerStream, sourceStream); - - if (baseName.isEmpty()) - { - ClassGenerator::finishStreams((*it).name.lower() + "interface", - headerStream, sourceStream); - } - } - - if (!baseName.isEmpty()) - ClassGenerator::finishStreams(baseName, headerStream, sourceStream); - } - - if (generateProxies || generateAll) - { - TQTextStream headerStream; - TQTextStream sourceStream; - - TQString baseName = options["proxy"]; - if (!baseName.isEmpty()) - { - if (!ClassGenerator::initStreams(baseName, headerStream, sourceStream)) - { - std::cerr << "dbusxml2qt3: proxy files, using base name '" - << baseName.local8Bit().data() - << "', could not be opened for writing" - << std::endl; - exit(4); - } - } - - TQValueList::const_iterator it = interfaces.begin(); - TQValueList::const_iterator endIt = interfaces.end(); - for (; it != endIt; ++it) - { - if (baseName.isEmpty()) - { - if (!ClassGenerator::initStreams((*it).name.lower() + "proxy", - headerStream, sourceStream)) - { - std::cerr << "dbusxml2qt3: proxy files, using base name '" - << baseName.local8Bit().data() - << "', could not be opened for writing" - << std::endl; - exit(4); - } - } - - ClassGenerator::generateProxy(*it, headerStream, sourceStream); - - if (baseName.isEmpty()) - { - ClassGenerator::finishStreams((*it).name.lower() + "proxy", - headerStream, sourceStream); - } - } - - if (!baseName.isEmpty()) - ClassGenerator::finishStreams(baseName, headerStream, sourceStream); - } - - if (generateNode || generateAll) - { - if (!hasIntrospectable) - { - tqDebug("Generating org.freedesktop.DBus.Introspectable on demand"); - - Class classData; - classData.name = "Introspectable"; - classData.dbusName = "org.freedesktop.DBus.Introspectable"; - - classData.namespaces << "org" << "freedesktop" << "DBus"; - - Method method; - method.name = "Introspect"; - method.noReply = false; - method.async = false; - - Argument argument; - argument.name = "data"; - argument.direction = Argument::Out; - argument.signature = "TQString"; - argument.accessor = "String"; - argument.isPrimitive = false; - argument.dbusSignature = "s"; - - argument.forwardDeclarations << "class TQString"; - argument.sourceIncludes["TQt"].append(""); - - method.arguments << argument; - classData.methods << method; - - TQTextStream headerStream; - TQTextStream sourceStream; - - if (!ClassGenerator::initStreams(classData.name.lower() + "interface", - headerStream, sourceStream)) - { - std::cerr << "dbusxml2qt3: interface files, using base name '" - << classData.name.lower().local8Bit().data() << "interface" - << "', could not be opened for writing" - << std::endl; - exit(4); - } - - ClassGenerator::generateInterface(classData, - headerStream, sourceStream); - - ClassGenerator::finishStreams(classData.name.lower() + "interface", - headerStream, sourceStream); - } - - TQString nodeClassName = options["classname"]; - if (nodeClassName.isEmpty()) - { - nodeClassName = rootElement.attribute("name"); - if (nodeClassName.startsWith("/")) nodeClassName = nodeClassName.mid(1); - if (nodeClassName.isEmpty()) - { - std::cerr << "dbusxml2qt3: cannot generate node without class name." - << std::endl; - exit(3); - } - - nodeClassName.replace('/', "_"); - } - - TQStringList nameParts = TQStringList::split("::", nodeClassName); - - Class classData; - classData.name = nameParts.back(); - - nameParts.pop_back(); - classData.namespaces = nameParts; - - if (checkForOption(options, "namespace")) - { - nameParts = TQStringList::split("::", options["namespace"]); - - classData.namespaces = nameParts; - } - - TQTextStream headerStream; - TQTextStream sourceStream; - - TQString baseName = options["node"]; - if (baseName.isEmpty()) baseName = classData.name.lower() + "node"; - - if (!ClassGenerator::initStreams(baseName, headerStream, sourceStream)) - { - std::cerr << "dbusxml2qt3: interface files, using base name '" - << baseName.local8Bit().data() - << "', could not be opened for writing" - << std::endl; - exit(4); - } - - ClassGenerator::generateNode(classData, interfaces, - headerStream, sourceStream); - - ClassGenerator::finishStreams(baseName, headerStream, sourceStream); - } - - return 0; -} - -void usage() -{ - std::cout << "usage: dbusxml2qt3 [options] " << std::endl; - std::cout << std::endl; - - std::cout << "Options:" << std::endl; - std::cout << "-h, --help" << std::endl; - std::cout << "\tDisplay this help" << std::endl; - std::cout << std::endl; - - std::cout << "-c , --class " << std::endl; - std::cout << "\tUse 'classname' instead of last string in interface name" - << std::endl; - std::cout << std::endl; - - std::cout << "-N [namespace], --namespace [namespace]" << std::endl; - std::cout << "\tOverride namespaces. If provided, use 'namespace' instead, otherwise ignore namespaces" - << std::endl; - std::cout << std::endl; - - std::cout << "-i [basename], --interface [basename]" << std::endl; - std::cout << "\tGenerate interface files. If provided, use 'basename' for filenames" - << std::endl; - std::cout << std::endl; - - std::cout << "-p [basename], --proxy [basename]" << std::endl; - std::cout << "\tGenerate proxy files. If provided, use 'basename' for filenames" - << std::endl; - std::cout << std::endl; - - std::cout << "-n [basename], --node [basename]" << std::endl; - std::cout << "\tGenerate node files. If provided, use 'basename' for filenames" - << std::endl; - std::cout << std::endl; - - std::cout << "Examples:" << std::endl; - std::cout << "dbusxml2qt3 myinterface.xml" << std::endl; - std::cout << "\tGenerates as much as possible, i.e. interfaces, proxies and, " - << "if a node name is specified in 'myinterface.xml', the node files" - << std::endl; - std::cout << "\tUses lowercased interface names as plus type specific suffix " - << "for the file names" << std::endl; - std::cout << std::endl; - - std::cout << "dbusxml2qt3 myinterface.xml -N" << std::endl; - std::cout << "\tSame as first example but does not use namespaces" - << std::endl; - std::cout << std::endl; - - std::cout << "dbusxml2qt3 myinterface.xml -N org::myorg" << std::endl; - std::cout << "\tSame as first example but overrides namespaces with 'org::myorg'" - << std::endl; - std::cout << std::endl; - - std::cout << "dbusxml2qt3 myinterface.xml -n mynode -c MyNode" << std::endl; - std::cout << "\tGenerate only node files, use 'mynode' as the file basename " - << "and classname 'MyClass'" - << std::endl; - std::cout << std::endl; - - std::cout << "dbusxml2qt3 myinterface.xml -p" << std::endl; - std::cout << "\tGenerate only proxy files, use default file basename" - << std::endl; - std::cout << std::endl; - - std::cout << "dbusxml2qt3 myinterface.xml -p myproxy" << std::endl; - std::cout << "\tGenerate only proxy files, use 'myproxy' as the file basename" - << std::endl; - std::cout << std::endl; -} - -bool testAndSetOption(OptionMap& options, const TQString& option, const TQString& value) -{ - OptionMap::iterator it = options.find(option); - if (it == options.end()) - { - options.insert(option, value); - return true; - } - - return false; -} - -OptionMap parseOptions(int argc, char** argv) -{ - TQStringList args; - for (int i = 1; i < argc; ++i) - { - args << TQString::fromLocal8Bit(argv[i]); - } - - OptionMap options; - - while (!args.isEmpty()) - { - TQString arg = args.front(); - args.pop_front(); - - if (arg.startsWith("-")) - { - if (arg.endsWith("help")) - { - usage(); - exit(0); - } - else if (arg == "-p" || arg == "--proxy") - { - // test for optional argument - TQString value; - if (!args.isEmpty() > 0 && !args[0].startsWith("-")) - { - value = args.front(); - args.pop_front(); - } - - if (!testAndSetOption(options, "proxy", value)) - { - std::cerr << "Error while parsing command line argument '" - << arg.local8Bit().data() << "'"; - - if (!value.isEmpty()) - std::cerr << ", value '" << value.local8Bit().data() << "':"; - else - std::cerr << ":"; - - std::cerr << " already set to '" - << options["proxy"].local8Bit().data() << std::endl; - } - } - else if (arg == "-i" || arg == "--interface") - { - // test for optional argument - TQString value; - if (!args.isEmpty() > 0 && !args[0].startsWith("-")) - { - value = args.front(); - args.pop_front(); - } - - if (!testAndSetOption(options, "interface", value)) - { - std::cerr << "Error while parsing command line argument '" - << arg.local8Bit().data() << "'"; - - if (!value.isEmpty()) - std::cerr << ", value '" << value.local8Bit().data() << "':"; - else - std::cerr << ":"; - - std::cerr << " already set to '" - << options["interface"].local8Bit().data() << std::endl; - } - } - else if (arg == "-n" || arg == "--node") - { - // test for optional argument - TQString value; - if (!args.isEmpty() > 0 && !args[0].startsWith("-")) - { - value = args.front(); - args.pop_front(); - } - - if (!testAndSetOption(options, "node", value)) - { - std::cerr << "Error while parsing command line argument '" - << arg.local8Bit().data() << "'"; - - if (!value.isEmpty()) - std::cerr << ", value '" << value.local8Bit().data() << "':"; - else - std::cerr << ":"; - - std::cerr << " already set to '" - << options["node"].local8Bit().data() << std::endl; - } - } - else if (arg == "-N" || arg == "--namespace") - { - // test for optional argument - TQString value; - if (!args.isEmpty() > 0 && !args[0].startsWith("-")) - { - value = args.front(); - args.pop_front(); - } - - if (!testAndSetOption(options, "namespace", value)) - { - std::cerr << "Error while parsing command line argument '" - << arg.local8Bit().data() << "'"; - - if (!value.isEmpty()) - std::cerr << ", value '" << value.local8Bit().data() << "':"; - else - std::cerr << ":"; - - std::cerr << " already set to '" - << options["namespace"].local8Bit().data() << std::endl; - } - } - else if (arg == "-c" || arg == "--class") - { - // test for mandatory argument - if (args.isEmpty() || args[0].startsWith("-")) - { - std::cerr << "Error while parsing command line argument '" - << arg.local8Bit().data() - << "': mandatory parameter missing" << std::endl; - usage(); - exit(1); - } - - TQString value = args.front(); - args.pop_front(); - - if (!testAndSetOption(options, "classname", value)) - { - std::cerr << "Error while parsing command line argument '" - << arg.local8Bit().data() << "'"; - - if (!value.isEmpty()) - std::cerr << ", value '" << value.local8Bit().data() << "':"; - else - std::cerr << ":"; - - std::cerr << " already set to '" - << options["classname"].local8Bit().data() << std::endl; - } - } - else - { - std::cerr << "Error while parsing command line argument '" - << arg.local8Bit().data() - << "': unknown option" << std::endl; - usage(); - exit(1); - } - } - else - { - if (!testAndSetOption(options, "filename", arg)) - { - std::cerr << "Error while parsing command line argument '" - << arg.local8Bit().data() - << "': introspection file already given as '" - << options["filename"].local8Bit().data() << std::endl; - usage(); - exit(1); - } - } - } - - return options; -} - -// End of File diff --git a/tools/dbusxml2qt3/methodgen.cpp b/tools/dbusxml2qt3/methodgen.cpp deleted file mode 100644 index 4e407d5..0000000 --- a/tools/dbusxml2qt3/methodgen.cpp +++ /dev/null @@ -1,1793 +0,0 @@ -/* -* Copyright (C) 2007 Kevin Krammer -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and associated documentation files (the "Software"), -* to deal in the Software without restriction, including without limitation -* the rights to use, copy, modify, merge, publish, distribute, sublicense, -* and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -* OTHER DEALINGS IN THE SOFTWARE. -*/ - -// TQt includes -#include -#include - -// local includes -#include "methodgen.h" - -static bool parseDBusSignature(const TQString& signature, Argument& argument) -{ - argument.dbusSignature = signature; - - if (signature.length() == 1) - { - if (signature == "b") - { - argument.signature = "bool"; - argument.accessor = "Bool"; - argument.isPrimitive = true; - } - else if (signature == "y") - { - argument.signature = "TQ_UINT8"; - argument.accessor = "Byte"; - argument.isPrimitive = true; - } - else if (signature == "n") - { - argument.signature = "TQ_INT16"; - argument.accessor = "Int16"; - argument.isPrimitive = true; - } - else if (signature == "q") - { - argument.signature = "TQ_UINT16"; - argument.accessor = "UInt16"; - argument.isPrimitive = true; - } - else if (signature == "i") - { - argument.signature = "TQ_INT32"; - argument.accessor = "Int32"; - argument.isPrimitive = true; - } - else if (signature == "u") - { - argument.signature = "TQ_UINT32"; - argument.accessor = "UInt32"; - argument.isPrimitive = true; - } - else if (signature == "x") - { - argument.signature = "TQ_INT64"; - argument.accessor = "Int64"; - argument.isPrimitive = true; - } - else if (signature == "t") - { - argument.signature = "TQ_UINT64"; - argument.accessor = "UInt64"; - argument.isPrimitive = true; - } - else if (signature == "d") - { - argument.signature = "double"; - argument.accessor = "Double"; - argument.isPrimitive = true; - } - else if (signature == "s") - { - argument.signature = "TQString"; - argument.accessor = "String"; - argument.isPrimitive = false; - - argument.forwardDeclarations.append("class TQString"); - argument.sourceIncludes["TQt"].append(""); - } - else if (signature == "o") - { - argument.signature = "TQT_DBusObjectPath"; - argument.accessor = "ObjectPath"; - argument.isPrimitive = false; - - argument.forwardDeclarations.append("class TQT_DBusObjectPath"); - argument.sourceIncludes["tqdbus"].append(""); - } - else if (signature == "h") - { - argument.signature = "TQT_DBusUnixFd"; - argument.accessor = "UnixFd"; - argument.isPrimitive = false; - - argument.forwardDeclarations.append("class TQT_DBusUnixFd"); - argument.sourceIncludes["tqdbus"].append(""); - } - else if (signature == "v") - { - argument.signature = "TQT_DBusVariant"; - argument.accessor = "Variant"; - argument.isPrimitive = false; - - argument.forwardDeclarations.append("class TQT_DBusVariant"); - argument.sourceIncludes["tqdbus"].append(""); - } - else - return false; - } - else if (signature.startsWith("a")) - { - if (signature == "as") - { - argument.signature = "TQStringList"; - argument.accessor = "List"; - argument.subAccessor = "TQStringList"; - argument.isPrimitive = false; - - argument.forwardDeclarations.append("class TQStringList"); - - argument.sourceIncludes["tqdbus"].append(""); - argument.sourceIncludes["TQt"].append(""); - } - else if (signature.startsWith("a{")) - { - int from = signature.find("{"); - int to = signature.findRev("}"); - if (from == -1 || to == -1 || (to - from - 1) < 2) return false; - - TQString dictSignature = signature.mid(from + 1, (to - from - 1)); - - Argument key; - if (!parseDBusSignature(dictSignature.left(1), key)) return false; - - Argument value; - if (parseDBusSignature(dictSignature.mid(1), value)) - { - if (!value.subAccessor.isEmpty()) - { - argument.isPrimitive = false; - argument.containerClass = "TQT_DBusDataMap< " + key.signature + " >"; - argument.signature = "TQT_DBusDataMap< " + key.signature + " >"; - argument.accessor = key.accessor + "KeyMap"; - - argument.forwardDeclarations.append("template class TQT_DBusDataMap"); - argument.forwardDeclarations += key.forwardDeclarations; - - argument.sourceIncludes = key.sourceIncludes; - argument.sourceIncludes["tqdbus"].append(""); - argument.sourceIncludes["tqdbus"].append(""); - } - else - { - argument.isPrimitive = false; - argument.containerClass = "TQT_DBusDataMap< " + key.signature + " >"; - argument.signature = "TQMap< " + key.signature + - ", " + value.signature + " >"; - argument.accessor = key.accessor + "KeyMap"; - argument.subAccessor = value.accessor + "Map"; - - argument.forwardDeclarations.append("template class TQMap"); - argument.forwardDeclarations += key.forwardDeclarations; - argument.forwardDeclarations += value.forwardDeclarations; - - argument.sourceIncludes = key.sourceIncludes; - argument.sourceIncludes["TQt"].append(""); - argument.sourceIncludes["tqdbus"].append(""); - argument.sourceIncludes["tqdbus"].append(""); - - TQMap::const_iterator it = - value.sourceIncludes.begin(); - TQMap::const_iterator endIt = - value.sourceIncludes.end(); - for (; it != endIt; ++it) - { - argument.sourceIncludes[it.key()] += it.data(); - } - } - } - else - { - argument.isPrimitive = false; - argument.containerClass = "TQT_DBusDataMap< " + key.signature + " >"; - argument.signature = "TQT_DBusDataMap< " + key.signature + " >"; - argument.accessor = key.accessor + "KeyMap"; - - argument.forwardDeclarations.append("template class TQT_DBusDataMap"); - argument.forwardDeclarations += key.forwardDeclarations; - - argument.sourceIncludes = key.sourceIncludes; - argument.sourceIncludes["tqdbus"].append(""); - argument.sourceIncludes["tqdbus"].append(""); - } - } - else - { - TQString itemSignature = signature.mid(1); - - Argument item; - if (parseDBusSignature(itemSignature, item) && !itemSignature.startsWith("a")) - { - argument.isPrimitive = false; - argument.signature = "TQValueList< " + item.signature + " >"; - argument.accessor = "List"; - argument.subAccessor = item.accessor + "List"; - argument.containerClass = "TQT_DBusDataList"; - - argument.forwardDeclarations.append("class TQT_DBusDataList"); - argument.forwardDeclarations.append("template class TQValueList"); - argument.forwardDeclarations += item.forwardDeclarations; - - argument.sourceIncludes["TQt"].append(""); - argument.sourceIncludes["tqdbus"].append(""); - - TQMap::const_iterator it = - item.sourceIncludes.begin(); - TQMap::const_iterator endIt = - item.sourceIncludes.end(); - for (; it != endIt; ++it) - { - argument.sourceIncludes[it.key()] += it.data(); - } - } - else - { - argument.signature = "TQT_DBusDataList"; - argument.accessor = "List"; - argument.isPrimitive = false; - - argument.forwardDeclarations.append("class TQT_DBusDataList"); - - argument.sourceIncludes["tqdbus"].append(""); - } - } - } - else - return false; - - return true; -} - -static TQMap extractTypeAnnotations(const TQDomElement& element) -{ - const TQString annotationPrefix = "org.freedesktop.DBus.TQt3.Type."; - - TQMap annotations; - - TQDomNode node = element.firstChild(); - for (uint count = 1; !node.isNull(); node = node.nextSibling(), ++count) - { - if (!node.isElement()) continue; - - TQDomElement element = node.toElement(); - if (element.tagName() != "annotation") continue; - - TQString name = element.attribute("name"); - if (name.isEmpty()) continue; - - TQString value = element.attribute("value").stripWhiteSpace(); - if (value.isEmpty()) continue; - - if (!name.startsWith(annotationPrefix)) continue; - - TQString arg = name.mid(annotationPrefix.length()); - - annotations.insert(arg, value); - } - - return annotations; -} - -static bool hasAnnotation(const TQDomElement& element, const TQString& annotation, TQString* value = 0) -{ - for (TQDomNode node = element.firstChild(); !node.isNull(); - node = node.nextSibling()) - { - if (!node.isElement()) continue; - - TQDomElement childElement = node.toElement(); - if (childElement.tagName() != "annotation") continue; - if (childElement.attribute("name") != annotation) continue; - - if (value != 0) *value = childElement.attribute("value"); - return true; - } - - return false; -} - -static TQValueList extractArguments(const TQDomElement& methodElement, - Class& classData) -{ - TQMap argAnnotations = extractTypeAnnotations(methodElement); - - TQValueList arguments; - - bool isSignal = methodElement.tagName() == "signal"; - - uint inCount = 0; - uint outCount = 0; - for (TQDomNode node = methodElement.firstChild(); !node.isNull(); - node = node.nextSibling()) - { - if (!node.isElement()) continue; - - TQDomElement element = node.toElement(); - if (element.tagName() != "arg") continue; - if (element.attribute("type").isEmpty()) continue; - - Argument argument; - argument.name = element.attribute("name"); - if (argument.name.isEmpty()) - argument.name = TQString("arg%1").arg(inCount + outCount); - - argument.direction = Argument::In; - if (!isSignal && element.attribute("direction", "in") == "out") - argument.direction = Argument::Out; - - TQString annotation; - if (!isSignal && argument.direction == Argument::In) - { - annotation = argAnnotations[TQString("In%1").arg(inCount)]; - ++inCount; - } - else - { - annotation = argAnnotations[TQString("Out%1").arg(outCount)]; - ++outCount; - } - - if (!annotation.isEmpty()) - { - // just assume nobody uses annotations for primitives - argument.annotatedType = annotation; - argument.signature = annotation; - argument.isPrimitive = false; - argument.dbusSignature = element.attribute("type"); - - TQString includeBase = - TQString("\"%1type%2.h\"").arg(classData.name.lower()); - - argument.headerIncludes["local"].append(includeBase.arg("declarations")); - argument.sourceIncludes["local"].append(includeBase.arg("includes")); - argument.sourceIncludes["tqdbus"].append(""); - } - else if (!parseDBusSignature(element.attribute("type"), argument)) - { - argument.signature = "TQT_DBusData"; - argument.isPrimitive = false; - - argument.forwardDeclarations.append("class TQT_DBusData"); - argument.sourceIncludes["tqdbus"].append(""); - } - - arguments.append(argument); - } - - return arguments; -} - -static void writeVariable(const Argument& argument, uint index, - const TQString& prefix, TQTextStream& stream) -{ - stream << prefix << argument.signature << " _" << argument.name; - if (argument.direction == Argument::In) - { - if (!argument.annotatedType.isEmpty()) - { - stream << ";" << endl; - - // TODO: error handling? - stream << prefix << "TQT_DBusDataConverter::convertFromTQT_DBusData<" - << argument.annotatedType - << TQString(">(message[%1], _").arg(index) - << argument.name << ")"; - } - else if (!argument.accessor.isEmpty()) - { - stream << TQString::fromUtf8(" = message[%1].to").arg(index); - stream << argument.accessor; - - if (!argument.subAccessor.isEmpty()) - { - stream << TQString("().to%1").arg(argument.subAccessor); - } - - stream << "()"; - } - else - stream << TQString::fromUtf8(" = message[%1]").arg(index); - } - - stream << ";" << endl; -} - -static void writeVariables(const TQString& prefix, const Method& method, - TQTextStream& stream) -{ - uint count = 0; - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - for (; it != endIt; ++it) - { - writeVariable(*it, count, prefix, stream); - - if ((*it).direction == Argument::In) ++count; - } -} - -static void writeSignalEmit(const Method& signal, TQTextStream& stream) -{ - stream << " emit " << signal.name << "("; - - TQValueList::const_iterator it = signal.arguments.begin(); - TQValueList::const_iterator endIt = signal.arguments.end(); - for (; it != endIt;) - { - stream << "_" << (*it).name; - - ++it; - if (it != endIt) stream << ", "; - } - - stream << ");" << endl; -} - -static void writeMethodIntrospection(const Method& method, bool& firstArgument, - TQTextStream& stream) -{ - stream << " methodElement.setAttribute(\"name\", \"" - << method.name << "\");" << endl; - - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - for (; it != endIt; ++it) - { - stream << endl; - if (firstArgument) - { - firstArgument = false; - - stream << " TQDomElement argumentElement = document.createElement(" - << "\"arg\");" << endl; - } - else - { - stream << " argumentElement = document.createElement(" - << "\"arg\");" << endl; - } - - stream << " argumentElement.setAttribute(\"name\", \"" - << (*it).name << "\");" << endl; - - stream << " argumentElement.setAttribute(\"type\", \"" - << (*it).dbusSignature << "\");" << endl; - - stream << " argumentElement.setAttribute(\"direction\", \"" - << ((*it).direction == Argument::In ? "in" : "out") << "\");" - << endl; - - stream << " methodElement.appendChild(argumentElement);" << endl; - } - stream << endl; -} - -static void writeNodeInitialization(const Class& classData, - const TQValueList& interfaces, TQTextStream& stream) -{ - stream << "bool " << classData.name - << "::registerObject(const TQT_DBusConnection& connection, " - << "const TQString& path)" << endl; - stream << "{" << endl; - stream << " if (path.isEmpty()) return false;" << endl; - stream << endl; - - stream << " if (!m_private->objectPath.isEmpty()) unregisterObject();" - << endl; - stream << endl; - - stream << " m_private->connection = connection;" << endl; - stream << " m_private->objectPath = path;" << endl; - stream << endl; - stream << " if (!m_private->connection.registerObject(path, this))" << endl; - stream << " {" << endl; - stream << " m_private->connection = TQT_DBusConnection();" << endl; - stream << " m_private->objectPath = TQString();" << endl; - stream << endl; - stream << " return false;" << endl; - stream << " }" << endl; - stream << endl; - - stream << " if (m_private->interfaces.isEmpty())" << endl; - stream << " {" << endl; - stream << " TQString name = \"org.freedesktop.DBus.Introspectable\";" - << endl; - stream << " TQT_DBusObjectBase* interface = m_private;" << endl; - stream << " m_private->interfaces.insert(name, interface);" << endl; - - TQValueList::const_iterator it = interfaces.begin(); - TQValueList::const_iterator endIt = interfaces.end(); - for (; it != endIt; ++it) - { - stream << endl; - stream << " name = \"" << (*it).dbusName << "\";" << endl; - stream << " interface = createInterface(name);" << endl; - stream << " Q_ASSERT(interface != 0);" << endl; - stream << " m_private->interfaces.insert(name, interface);" << endl; - } - - stream << " }" << endl; - stream << endl; - stream << " return true;" << endl; - stream << "}" << endl; - stream << endl; -} -static void writeNodeIntrospection(const Class& classData, - const TQValueList& interfaces, TQTextStream& stream) -{ - stream << "void " << classData.name << "::Private" - << "::cacheIntrospectionData()" << endl; - stream << "{" << endl; - - stream << " TQDomDocument doc;" << endl; - stream << " TQDomElement nodeElement = doc.createElement(\"node\");" << endl; - stream << " TQDomElement interfaceElement = doc.createElement(\"interface\");" - << endl; - stream << " org::freedesktop::DBus::Introspectable" - << "::buildIntrospectionData(interfaceElement);" << endl; - stream << " nodeElement.appendChild(interfaceElement);" << endl; - - TQValueList::const_iterator it = interfaces.begin(); - TQValueList::const_iterator endIt = interfaces.end(); - for (; it != endIt; ++it) - { - if ((*it).dbusName == "org.freedesktop.DBus.Introspectable") continue; - - stream << endl; - stream << " interfaceElement = doc.createElement(\"interface\");" - << endl; - stream << " " << (*it).namespaces.join("::") + "::" + (*it).name - << "::buildIntrospectionData(interfaceElement);" << endl; - stream << " nodeElement.appendChild(interfaceElement);" << endl; - } - - stream << endl; - stream << " doc.appendChild(nodeElement);" << endl; - stream << endl; - - stream << " introspectionData = \"\\n\";" << endl; - stream << " introspectionData += doc.toString();" << endl; - stream << "}" << endl; - stream << endl; -} - -bool MethodGenerator::extractMethods(const TQDomElement& interfaceElement, - Class& classData) -{ - TQMap propertyAnnotations = - extractTypeAnnotations(interfaceElement); - - uint propertyCount = 0; - for (TQDomNode node = interfaceElement.firstChild(); !node.isNull(); - node = node.nextSibling()) - { - if (!node.isElement()) continue; - - TQDomElement element = node.toElement(); - if (element.attribute("name").isEmpty()) continue; - - if (element.tagName() == "method" || element.tagName() == "signal") - { - Method method; - method.name = element.attribute("name"); - method.arguments = extractArguments(element, classData); - method.noReply = false; - method.async = false; - - if (element.tagName() == "method") - { - method.async = hasAnnotation(element, "org.freedesktop.DBus.GLib.Async"); - classData.methods.append(method); - if (method.async) { - method.async = false; - classData.methods.append(method); - } - } - else - classData.msignals.append(method); - } - else if (element.tagName() == "property") - { - Property property; - property.name = element.attribute("name"); - property.read = element.attribute("access").find("read") != -1; - property.write = element.attribute("access").find("write") != -1; - - TQString annotation = - propertyAnnotations[TQString("Property%1").arg(propertyCount)]; - - if (!annotation.isEmpty()) - { - property.annotatedType = annotation; - property.signature = annotation; - property.dbusSignature = element.attribute("type"); - property.isPrimitive = false; - - TQString includeBase = - TQString("\"%1type%2.h\"").arg(classData.name.lower()); - - property.headerIncludes["local"].append(includeBase.arg("declarations")); - property.sourceIncludes["local"].append(includeBase.arg("includes")); - property.sourceIncludes["tqdbus"].append(""); - } - else if (!parseDBusSignature(element.attribute("type"), property)) - { - property.signature = "TQT_DBusData"; - property.isPrimitive = false; - - property.forwardDeclarations.append("class TQT_DBusData"); - property.sourceIncludes["tqdbus"].append(""); - } - - classData.properties.append(property); - ++propertyCount; - } - } - - return !classData.methods.isEmpty() || !classData.msignals.isEmpty() || - !classData.properties.isEmpty(); -} - -void MethodGenerator::writeMethodDeclaration(const Method& method, bool pureVirtual, - bool withError, TQTextStream& stream) -{ - stream << method.name << "("; - - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - for (; it != endIt;) - { - if (!(*it).isPrimitive && (*it).direction == Argument::In) - stream << "const "; - - stream << (*it).signature; - - if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&"; - - stream << " " << (*it).name; - - ++it; - if (it != endIt || withError) stream << ", "; - } - - if (withError) - stream << "TQT_DBusError& error)"; - else - stream << ")"; - - if (pureVirtual) - stream << " = 0;" << endl; - else - stream << ";" << endl; - - stream << endl; -} - -void MethodGenerator::writePropertyDeclaration(const Property& property, - bool pureVirtual, TQTextStream& stream) -{ - if (property.write) - { - stream << " virtual void set" << property.name << "("; - - if (!property.isPrimitive) stream << "const "; - - stream << property.signature; - - if (!property.isPrimitive) stream << "&"; - - stream << " value, TQT_DBusError& error)"; - - if (pureVirtual) - stream << " = 0;" << endl; - else - stream << ";" << endl; - } - - if (property.read) - { - stream << " virtual " << property.signature << " get" - << property.name << "(TQT_DBusError& error) const"; - - if (pureVirtual) - stream << " = 0;" << endl; - else - stream << ";" << endl; - } - - if (property.read || property.write) stream << endl; -} - -void MethodGenerator::writeMethodCallDeclaration(const Method& method, - TQTextStream& stream) -{ - if (method.async) - stream << "void call" << method.name << "Async"; - else - stream << "TQT_DBusMessage call" << method.name; - - stream << "(const TQT_DBusMessage& message);" << endl; - stream << endl; -} - -void MethodGenerator::writeMethodCall(const Class& classData, - const Method& method, TQTextStream& stream) -{ - if (method.async) - stream << "void " << classData.name << "::call" << method.name << "Async"; - else - stream << "TQT_DBusMessage " << classData.name << "::call" << method.name; - - stream << "(const TQT_DBusMessage& message)" << endl; - - stream << "{" << endl; - - if (method.async) - { - // FIXME: using writeVariables by removing asyncCallId argument - Method reducedMethod = method; - reducedMethod.arguments.pop_front(); - - writeVariables(" ", reducedMethod, stream); - } - else - { - stream << " TQT_DBusError error;" << endl; - stream << " TQT_DBusMessage reply;" << endl; - stream << endl; - - writeVariables(" ", method, stream); - } - - stream << endl; - - if (method.async) - { - stream << " int _asyncCallId = 0;" << endl; - stream << " while (m_asyncCalls.find(_asyncCallId) != m_asyncCalls.end())" - << endl; - stream << " {" << endl; - stream << " ++_asyncCallId;" << endl; - stream << " }" << endl; - stream << " m_asyncCalls.insert(_asyncCallId, message);" << endl; - stream << endl; - - stream << " " << method.name << "Async("; - } - else - stream << " if (" << method.name << "("; - - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - while (it != endIt) - { - stream << "_" << (*it).name; - - ++it; - if (it != endIt) stream << ", "; - } - - if (method.async) - { - stream << ");" << endl; - stream << endl; - - stream << " return;" << endl; - stream << "}" << endl; - stream << endl; - return; - } - - if (method.arguments.count() > 0) stream << ", "; - stream << "error))" << endl; - - stream << " {" << endl; - stream << " reply = TQT_DBusMessage::methodReply(message);" << endl; - - it = method.arguments.begin(); - for (; it != endIt; ++it) - { - if ((*it).direction == Argument::Out) - { - if (!(*it).annotatedType.isEmpty()) - { - stream << " TQT_DBusData " << (*it).name << "Data;" << endl; - stream << " TQT_DBusDataConverter::convertToTQT_DBusData<" - << (*it).annotatedType << ">(_" - << (*it).name << ", " << (*it).name << "Data);" - << endl; - stream << " reply << " << (*it).name << "Data"; - } - else if (!(*it).accessor.isEmpty()) - { - stream << " reply << TQT_DBusData::from" << (*it).accessor; - if (!(*it).subAccessor.isEmpty()) - { - stream << "(" << (*it).containerClass; - } - - stream << "(_" << (*it).name << ")"; - - if (!(*it).subAccessor.isEmpty()) - { - stream << ")"; - } - } - else - stream << " reply << _" << (*it).name; - - stream << ";" << endl; - } - } - stream << " }" << endl; - stream << " else" << endl; - stream << " {" << endl; - - stream << " if (!error.isValid())" << endl; - stream << " {" << endl; - stream << " tqWarning(\"Call to implementation of "; - - TQStringList::const_iterator nsIt = classData.namespaces.begin(); - TQStringList::const_iterator nsEndIt = classData.namespaces.end(); - for (; nsIt != nsEndIt; ++nsIt) - { - stream << *nsIt << "::"; - } - - stream << classData.name << "::" << method.name; - stream << " returned 'false' but error object is not valid!\");" << endl; - stream << endl; - stream << " error = TQT_DBusError::stdFailed(\""; - - nsIt = classData.namespaces.begin(); - for (; nsIt != nsEndIt; ++nsIt) - { - stream << *nsIt << "."; - } - - stream << classData.name << "." << method.name << " execution failed\");" - << endl; - stream << " }" << endl; - stream << endl; - - stream << " reply = TQT_DBusMessage::methodError(message, error);" << endl; - - stream << " }" << endl; - stream << endl; - stream << " return reply;" << endl; - stream << "}" << endl; - stream << endl; -} - -void MethodGenerator::writeSignalEmitter(const Class& classData, - const Method& method, TQTextStream& stream) -{ - stream << "bool " << classData.name << "::emit" << method.name << "("; - - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - for (; it != endIt;) - { - if (!(*it).isPrimitive && (*it).direction == Argument::In) - stream << "const "; - - stream << (*it).signature; - - if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&"; - - stream << " " << (*it).name; - - ++it; - if (it != endIt) stream << ", "; - } - - stream << ")" << endl; - - stream << "{" << endl; - - // TODO: create error or use enum for return - stream << " TQString path = objectPath();" << endl; - stream << " Q_ASSERT(!path.isEmpty());" << endl; - stream << endl; - - stream << " TQT_DBusMessage message = TQT_DBusMessage::signal(path, \""; - stream << classData.dbusName << "\", \"" << method.name << "\");" << endl; - stream << endl; - - it = method.arguments.begin(); - for (; it != endIt; ++it) - { - if ((*it).direction == Argument::In) - { - if (!(*it).annotatedType.isEmpty()) - { - // TODO: error handling - stream << " TQT_DBusData " << (*it).name << "Data;" << endl; - stream << " if (TQT_DBusDataConverter:convertToTQT_DBusData<" - << (*it).annotatedType << ">(" - << (*it).name << ", " << (*it).name << "Data" - << ") != TQT_DBusDataConverter::Success) return false;" - << endl; - stream << " message << " << (*it).name << "Data"; - } - else if (!(*it).accessor.isEmpty()) - { - stream << " message << TQT_DBusData::from" << (*it).accessor; - if (!(*it).subAccessor.isEmpty()) - { - stream << "(" << (*it).containerClass; - } - - stream << "(" << (*it).name << ")"; - - if (!(*it).subAccessor.isEmpty()) - { - stream << ")"; - } - } - else - stream << " message << " << (*it).name; - - stream << ";" << endl; - } - } - stream << endl; - - stream << " return handleSignalSend(message);" << endl; - - stream << "}" << endl; - stream << endl; -} - - -void MethodGenerator::writeInterfaceAsyncReplyHandler(const Class& classData, - const Method& method, TQTextStream& stream) -{ - stream << "void " << classData.name << "::" << method.name - << "AsyncReply("; - - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - while (it != endIt) - { - if (!(*it).isPrimitive && (*it).direction == Argument::In) - stream << "const "; - - stream << (*it).signature; - - if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&"; - - stream << " " << (*it).name; - - ++it; - if (it != endIt) stream << ", "; - } - stream << ")" << endl; - stream << endl; - stream << "{" << endl; - - stream << " TQMap::iterator findIt = m_asyncCalls.find(asyncCallId);" << endl; - stream << " if (findIt == m_asyncCalls.end()) return;" << endl; - stream << endl; - - stream << " TQT_DBusMessage call = findIt.data();" << endl; - stream << " m_asyncCalls.erase(findIt);" << endl; - stream << endl; - - stream << " TQT_DBusMessage reply = TQT_DBusMessage::methodReply(call);" - << endl; - - it = method.arguments.begin(); - for (++it; it != endIt; ++it) // skip asyncCallId at beginning - { - if (!(*it).annotatedType.isEmpty()) - { - stream << " TQT_DBusData " << (*it).name << "Data;" << endl; - - // TODO error handling - stream << " if (TQT_DBusDataConverter::convertToTQT_DBusData<" - << (*it).annotatedType << ">(" << (*it).name << ", " - << (*it).name << "Data" - << ") != TQT_DBusDataConverter::Success) return false;" - << endl; - stream << " reply << " << (*it).name << "Data;" << endl; - } - else if (!(*it).accessor.isEmpty()) - { - stream << " reply << TQT_DBusData::from" << (*it).accessor << "("; - - if ((*it).subAccessor.isEmpty()) - stream << (*it).name; - else - stream << (*it).containerClass << "(" << (*it).name << ")"; - - stream << ");" << endl; - } - else - stream << " reply << " << (*it).name << ";" << endl; - } - stream << endl; - - stream << " handleMethodReply(reply);" << endl; - - stream << "}" << endl; - stream << endl; - - stream << "void " << classData.name << "::" << method.name - << "AsyncError(int asyncCallId, const TQT_DBusError& error)"; - stream << endl; - - stream << "{" << endl; - - stream << " TQMap::iterator findIt = m_asyncCalls.find(asyncCallId);" << endl; - stream << " if (findIt == m_asyncCalls.end()) return;" << endl; - stream << endl; - - stream << " TQT_DBusMessage call = findIt.data();" << endl; - stream << " m_asyncCalls.erase(findIt);" << endl; - stream << endl; - - stream << " TQT_DBusMessage reply = TQT_DBusMessage::methodError(call, error);" - << endl; - stream << " handleMethodReply(reply);" << endl; - - stream << "}" << endl; - stream << endl; -} - -void MethodGenerator::writeInterfaceMainMethod(const Class& classData, - TQTextStream& stream) -{ - if (classData.methods.isEmpty()) return; - - stream << "bool " << classData.name - << "::handleMethodCall(const TQT_DBusMessage& message)" << endl; - stream << "{" << endl; - - stream << " if (message.interface() != \"" << classData.dbusName - << "\") return false;" << endl; - stream << endl; - - TQValueList::const_iterator it = classData.methods.begin(); - TQValueList::const_iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - stream << " if (message.member() == \"" << (*it).name << "\")" << endl; - stream << " {" << endl; - - if ((*it).async) - { - stream << " call" << (*it).name << "Async(message);" << endl; - stream << endl; - } - else - { - stream << " TQT_DBusMessage reply = call" << (*it).name - << "(message);" << endl; - stream << " handleMethodReply(reply);" << endl; - stream << endl; - } - stream << " return true;" << endl; - stream << " }" << endl; - stream << endl; - } - - stream << " return false; " << endl; - stream << "}" << endl; - stream << endl; -} - -void MethodGenerator::writeSignalHandler(const Class& classData, - TQTextStream& stream) -{ - stream << "void " << classData.name - << "::slotHandleDBusSignal(const TQT_DBusMessage& message)" << endl; - stream << "{" << endl; - - TQValueList::const_iterator it = classData.msignals.begin(); - TQValueList::const_iterator endIt = classData.msignals.end(); - bool first = true; - for (; it != endIt; ++it) - { - stream << " "; - - if (!first) - stream << "else "; - else - first = false; - - stream << "if (message.member() == \"" << (*it).name << "\")" << endl; - stream << " {" << endl; - - writeVariables(" ", *it, stream); - stream << endl; - - writeSignalEmit(*it, stream); - - stream << " }" << endl; - } - - stream << "}" << endl; - stream << endl; -} - -void MethodGenerator::writeProxyBegin(const Class& classData, TQTextStream& stream) -{ - stream << classData.name << "::" << classData.name - << "(const TQString& service, const TQString& path, TQObject* parent, const char* name)" << endl; - stream << " : TQObject(parent, name)," << endl; - stream << " m_baseProxy(new TQT_DBusProxy())" << endl; - stream << "{" << endl; - stream << " m_baseProxy->setInterface(\"" - << classData.dbusName << "\");" << endl; - stream << " m_baseProxy->setPath(path);" << endl; - stream << " m_baseProxy->setService(service);" << endl; - stream << endl; - - if (!classData.msignals.isEmpty()) - { - stream << " TQObject::connect(m_baseProxy, " - << "TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&))," << endl; - stream << " this, " - << " TQT_SLOT(slotHandleDBusSignal(const TQT_DBusMessage&)));" - << endl; - } - - if (!classData.asyncReplySignals.isEmpty()) - { - stream << " TQObject::connect(m_baseProxy, " - << "TQT_SIGNAL(asyncReply(int, const TQT_DBusMessage&))," << endl; - stream << " this, " - << " TQT_SLOT(slotHandleAsyncReply(int, const TQT_DBusMessage&)));" - << endl; - } - - stream << "}" << endl; - - stream << endl; - - stream << classData.name << "::~" << classData.name << "()" << endl; - stream << "{" << endl; - stream << " delete m_baseProxy;" << endl; - stream << "}" << endl; - stream << endl; - - stream << "void " << classData.name - << "::setConnection(const TQT_DBusConnection& connection)" << endl; - stream << "{" << endl; - stream << " m_baseProxy->setConnection(connection);" << endl; - stream << "}" << endl; - stream << endl; -} - -void MethodGenerator::writeProxyMethod(const TQString& className, - const Method& method, TQTextStream& stream) -{ - stream << "bool " << className << "::" << method.name - << (method.async ? "Async(" : "("); - - TQValueList::const_iterator it = method.arguments.begin(); - TQValueList::const_iterator endIt = method.arguments.end(); - for (; it != endIt; ++it) - { - if (!(*it).isPrimitive && (*it).direction == Argument::In) - stream << "const "; - - stream << (*it).signature; - - if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&"; - - stream << " " << (*it).name << ", "; - } - - stream << "TQT_DBusError& error)" << endl; - - stream << "{" << endl; - stream << " TQValueList parameters;" << endl; - stream << endl; - - uint outCount = 0; - - it = method.arguments.begin(); - for (; it != endIt; ++it) - { - if ((*it).direction == Argument::Out) - { - ++outCount; - continue; - } - - if (!(*it).annotatedType.isEmpty()) - { - stream << " TQT_DBusData " << (*it).name << "Data;" << endl; - - // TODO error handling - stream << " if (TQT_DBusDataConverter::convertToTQT_DBusData<" - << (*it).annotatedType << ">(" << (*it).name << ", " - << (*it).name << "Data" - << ") != TQT_DBusDataConverter::Success) return false;" - << endl; - stream << " parameters << " << (*it).name << "Data;" << endl; - } - else if (!(*it).accessor.isEmpty()) - { - stream << " parameters << TQT_DBusData::from" << (*it).accessor << "("; - - if ((*it).subAccessor.isEmpty()) - stream << (*it).name; - else - stream << (*it).containerClass << "(" << (*it).name << ")"; - - stream << ");" << endl; - } - else - stream << " parameters << " << (*it).name << ";" << endl; - } - - stream << endl; - - if (outCount == 0 && method.noReply) - { - stream << " if (!m_baseProxy->send(\"" << method.name - << "\", parameters))" << endl; - stream << " {" << endl; - stream << " error = m_baseProxy->lastError();" << endl; - stream << " return false;" << endl; - stream << " }" << endl; - stream << " return true;" << endl; - stream << "}" << endl; - stream << endl; - return; - } - - if (method.async) - { - stream << " asyncCallId = m_baseProxy->sendWithAsyncReply(\""; - stream << method.name << "\", parameters);" << endl; - stream << endl; - - stream << " if (asyncCallId != 0) m_asyncCalls[asyncCallId] = \"" - << method.name << "\";" << endl; - stream << endl; - - stream << " error = TQT_DBusError();"; - stream << endl; - - stream << " return (asyncCallId != 0);" << endl; - stream << "}" << endl; - stream << endl; - return; - } - - stream << " TQT_DBusMessage reply = m_baseProxy->sendWithReply(\""; - stream << method.name << "\", parameters, &error);" << endl; - stream << endl; - - stream << " if (reply.type() != TQT_DBusMessage::ReplyMessage) return false;" - << endl; - - if (outCount == 0) - { - stream << " return true;" << endl; - stream << "}" << endl; - stream << endl; - return; - } - - stream << endl; - - // TODO: create error or use enum for return - stream << " if (reply.count() != " << outCount << ") return false;" << endl; - stream << endl; - - bool firstAccessor = true; - bool firstSubAccessor = true; - - it = method.arguments.begin(); - for (; it != endIt; ++it) - { - if ((*it).direction == Argument::In) continue; - - --outCount; - - if (!(*it).annotatedType.isEmpty()) - { - // TODO error handling - stream << " if (TQT_DBusDataConverter::convertFromTQT_DBusData<" - << (*it).annotatedType << ">(reply.front(), " - << (*it).name - << ") != TQT_DBusDataConverter::Success) return false;" - << endl; - } - else if (!(*it).accessor.isEmpty()) - { - if (firstAccessor) - { - stream << " bool ok = false;" << endl; - stream << endl; - firstAccessor = false; - } - - if ((*it).subAccessor.isEmpty()) - { - stream << " " << (*it).name << " = reply.front().to" - << (*it).accessor << "(&ok);" << endl; - } - else - { - if (firstSubAccessor) - { - stream << " bool subOK = false;" << endl; - stream << endl; - firstSubAccessor = false; - } - - stream << " " << (*it).name << " = reply.front().to" - << (*it).accessor << "(&ok).to" << (*it).subAccessor - << "(&subOK);" << endl; - - // TODO: create error or use enum for return - stream << " if (!subOK) return false;" << endl; - } - - // TODO: create error or use enum for return - stream << " if (!ok) return false;" << endl; - } - else - stream << " " << (*it).name << " = reply.front();" << endl; - stream << endl; - - if (outCount > 0) - { - stream << " reply.pop_front();" << endl; - stream << endl; - } - } - - stream << " return true;" << endl; - - stream << "}" << endl; - stream << endl; -} - -void MethodGenerator::writeProxyGenericProperty(const Class& classData, - TQTextStream& stream) -{ - stream << "void " << classData.name - << "::setDBusProperty(const TQString& name, " - << "const TQT_DBusVariant& value, TQT_DBusError& error)" - << endl; - stream << "{" << endl; - - stream << " TQT_DBusConnection connection = m_baseProxy->connection();" << endl; - stream << endl; - stream << " TQT_DBusMessage message = TQT_DBusMessage::methodCall(" - << "m_baseProxy->service(), m_baseProxy->path(), " - << "\"org.freedesktop.DBus.Properties\", \"Set\");" << endl; - stream << endl; - - stream << " message << TQT_DBusData::fromString(m_baseProxy->interface());" - << endl; - stream << " message << TQT_DBusData::fromString(name);" << endl; - stream << " message << TQT_DBusData::fromVariant(value);" << endl; - stream << endl; - - stream << " connection.sendWithReply(message, &error);" << endl; - - stream << "}" << endl; - - stream << endl; - - stream << "TQT_DBusVariant " << classData.name - << "::getDBusProperty(const TQString& name, TQT_DBusError& error) const" - << endl; - stream << "{" << endl; - - stream << " TQT_DBusConnection connection = m_baseProxy->connection();" << endl; - stream << endl; - - stream << " TQT_DBusMessage message = TQT_DBusMessage::methodCall(" - << "m_baseProxy->service(), m_baseProxy->path(), " - << "\"org.freedesktop.DBus.Properties\", \"Get\");" << endl; - stream << endl; - - stream << " message << TQT_DBusData::fromString(m_baseProxy->interface());" - << endl; - stream << " message << TQT_DBusData::fromString(name);" << endl; - stream << endl; - - stream << " TQT_DBusMessage reply = connection.sendWithReply(message, &error);" - << endl; - stream << endl; - - stream << " if (reply.type() != TQT_DBusMessage::ReplyMessage)" - << " return TQT_DBusVariant();" << endl; - stream << " if (reply.count() != 1) return TQT_DBusVariant();" << endl; - - stream << endl; - - stream << " bool ok = false;" << endl; - stream << " TQT_DBusVariant value = reply.front().toVariant(&ok);" << endl; - - // TODO generate error - stream << " if (!ok) return TQT_DBusVariant();" << endl; - stream << endl; - - stream << " return value;" << endl; - - stream << "}" << endl; - - stream << endl; -} - -void MethodGenerator::writeProxyProperty(const Class& classData, - const Property& property, TQTextStream& stream) -{ - if (property.write) - { - stream << "void " << classData.name << "::set" << property.name << "("; - - if (!property.isPrimitive) stream << "const "; - - stream << property.signature; - - if (!property.isPrimitive) stream << "&"; - - stream << " value, TQT_DBusError& error)" << endl; - stream << "{" << endl; - stream << " TQT_DBusVariant variant;" << endl; - - if (!property.annotatedType.isEmpty()) - { - // TODO: error handling - stream << " TQT_DBusDataConverter::convertToTQT_DBusData<" - << property.annotatedType << ">(value, variant.value);" - << endl; - } - else if (!property.accessor.isEmpty()) - { - stream << " variant.value = TQT_DBusData::from" - << property.accessor << "("; - - if (property.subAccessor.isEmpty()) - stream << "value"; - else - stream << property.containerClass << "(value)"; - - stream << ");" << endl; - } - else - stream << " variant.value = TQT_DBusData(value);" << endl; - - stream << " variant.signature = \"" << property.dbusSignature << "\";" - << endl; - - stream << endl; - stream << " setDBusProperty(\"" << property.name - << "\", variant, error);" << endl; - - stream << "}" << endl; - stream << endl; - } - - if (property.read) - { - stream << property.signature << " " << classData.name - << "::get" << property.name << "(TQT_DBusError& error) const" << endl; - stream << "{" << endl; - - stream << " TQT_DBusVariant variant = getDBusProperty(\"" - << property.name << "\", error);" << endl; - stream << endl; - stream << " if (error.isValid()) return " - << property.signature << "();" << endl; - stream << endl; - - if (!property.annotatedType.isEmpty()) - { - stream << " " << property.signature << " result;" << endl; - - // TODO error handling - stream << " TQT_DBusDataConverter::convertFromTQT_DBusData<" - << property.annotatedType << ">(variant.value, result);" - << endl; - } - else if (!property.accessor.isEmpty()) - { - stream << " bool ok = false;" << endl; - stream << endl; - - if (property.subAccessor.isEmpty()) - { - stream << " " << property.signature << " result = "; - stream << " variant.value.to" << property.accessor - << "(&ok);" << endl; - } - else - { - stream << " bool subOK = false;" << endl; - stream << endl; - - stream << " " << property.signature << " result = "; - stream << " variant.value.to" - << property.accessor << "(&ok).to" << property.subAccessor - << "(&subOK);" << endl; - - // TODO: create error - stream << " if (!subOK) {}" << endl; - } - - // TODO: create error - stream << " if (!ok) {}" << endl; - } - else - stream << " " << property.signature << " result = variant.value;"; - stream << endl; - - stream << " return result;" << endl; - stream << "}" << endl; - stream << endl; - } -} - -void MethodGenerator::writeProxyAsyncReplyHandler(const Class& classData, - TQTextStream& stream) -{ - stream << "void " << classData.name - << "::slotHandleAsyncReply(int asyncCallId, const TQT_DBusMessage& message)" << endl; - stream << "{" << endl; - - stream << " TQMap::iterator findIt = " - << "m_asyncCalls.find(asyncCallId);" << endl; - stream << " if (findIt == m_asyncCalls.end()) return;" << endl; - stream << endl; - stream << " const TQString signalName = findIt.data();" << endl; - stream << " m_asyncCalls.erase(findIt);" << endl; - stream << endl; - - TQValueList::const_iterator it = classData.asyncReplySignals.begin(); - TQValueList::const_iterator endIt = classData.asyncReplySignals.end(); - bool first = true; - for (; it != endIt; ++it) - { - stream << " "; - - if (!first) - stream << "else "; - else - first = false; - - stream << "if (signalName == \"" << (*it).name << "\")" << endl; - stream << " {" << endl; - - // FIXME tricking writeVariables and writeSignalEmit into writing - // the reply emit code by manipulating arguments and name - stream << " int _asyncCallId = asyncCallId;" << endl << endl; - - stream << " if (message.type() == TQT_DBusMessage::ErrorMessage) {" << endl; - stream << " emit AsyncErrorResponseDetected(_asyncCallId, message.error());" << endl; - stream << " }" << endl << endl; - - Method signal = *it; - signal.arguments.pop_front(); - - writeVariables(" ", signal, stream); - stream << endl; - - signal = *it; - signal.name += "AsyncReply"; - - writeSignalEmit(signal, stream); - - stream << " }" << endl; - } - - stream << "}" << endl; - stream << endl; -} - -void MethodGenerator::writeIntrospectionDataMethod(const Class& classData, - TQTextStream& stream) -{ - stream << "void " << classData.name - << "::buildIntrospectionData(TQDomElement& interfaceElement)" << endl; - stream << "{" << endl; - - stream << " interfaceElement.setAttribute(\"name\", \"" - << classData.dbusName << "\");" << endl; - stream << endl; - - bool firstMethod = true; - bool firstArgument = true; - - TQValueList::const_iterator it = classData.methods.begin(); - TQValueList::const_iterator endIt = classData.methods.end(); - for (; it != endIt; ++it) - { - if (firstMethod) - { - firstMethod = false; - stream << " TQDomDocument document = interfaceElement.ownerDocument();" << endl; - stream << " TQDomElement methodElement = document.createElement(" - << "\"method\");" << endl; - } - else - { - stream << endl; - stream << " methodElement = document.createElement(" - << "\"method\");" << endl; - } - - writeMethodIntrospection(*it, firstArgument, stream); - - stream << " interfaceElement.appendChild(methodElement);" << endl; - } - - it = classData.msignals.begin(); - endIt = classData.msignals.end(); - for (; it != endIt; ++it) - { - if (firstMethod) - { - firstMethod = false; - stream << " TQDomDocument document = interfaceElement.ownerDocument();" << endl; - stream << endl; - stream << " TQDomElement methodElement = document.createElement(" - << "\"signal\");" << endl; - } - else - { - stream << endl; - stream << " methodElement = document.createElement(" - << "\"signal\");" << endl; - } - - writeMethodIntrospection(*it, firstArgument, stream); - - stream << " interfaceElement.appendChild(methodElement);" << endl; - } - - stream << "}" << endl; - stream << endl; -} - -void MethodGenerator::writeNodePrivate(const Class& classData, TQTextStream& stream) -{ - stream << "class " << classData.name - << "::Private : public org::freedesktop::DBus::Introspectable" << endl; - stream << "{" << endl; - stream << "public:" << endl; - stream << " virtual ~Private();" << endl; - stream << endl; - - stream << "public:" << endl; - stream << " TQMap interfaces;" << endl; - stream << " TQString introspectionData;" << endl; - stream << endl; - stream << " TQT_DBusConnection connection;" << endl; - stream << " TQString objectPath;" << endl; - stream << endl; - - stream << "protected:" << endl; - stream << " virtual bool Introspect(TQString& data, TQT_DBusError& error);" - << endl; - stream << endl; - stream << " virtual void handleMethodReply(const TQT_DBusMessage& reply);" - << endl; - - stream << "private:" << endl; - stream << " void cacheIntrospectionData();" << endl; - - stream << "};" << endl; - stream << endl; -} - -void MethodGenerator::writeNodeBegin(const Class& classData, TQTextStream& stream) -{ - stream << classData.name << "::" << classData.name - << "() : TQT_DBusObjectBase()," << endl; - stream << " m_private(new Private())" << endl; - stream << "{" << endl; - stream << "}" << endl; - stream << endl; - - stream << classData.name << "::~" << classData.name << "()" << endl; - stream << "{" << endl; - stream << " unregisterObject();" << endl; - stream << endl; - stream << " delete m_private;" << endl; - stream << "}" << endl; - stream << endl; -} - -void MethodGenerator::writeNodeMethods(const Class& classData, - const TQValueList& interfaces, TQTextStream& stream) -{ - writeNodeInitialization(classData, interfaces, stream); - - stream << "void " << classData.name << "::unregisterObject()" << endl; - stream << "{" << endl; - stream << " if (m_private->objectPath.isEmpty()) return;" << endl; - stream << endl; - stream << " m_private->connection.unregisterObject(m_private->objectPath);" << endl; - stream << endl; - stream << " m_private->connection = TQT_DBusConnection();" << endl; - stream << " m_private->objectPath = TQString();" << endl; - stream << "}" << endl; - stream << endl; - - stream << "bool " << classData.name - << "::handleMethodCall(const TQT_DBusMessage& message)" << endl; - stream << "{" << endl; - stream << " TQMap::iterator findIt = " - << "m_private->interfaces.find(message.interface());" << endl; - stream << " if (findIt == m_private->interfaces.end()) return false;" - << endl; - stream << endl; - stream << " return delegateMethodCall(message, findIt.data());" << endl; - stream << "}" << endl; - stream << endl; - - stream << classData.name << "::Private::~Private()" << endl; - stream << "{" << endl; - stream << " TQMap::const_iterator it = " - << "interfaces.begin();" << endl; - stream << " TQMap::const_iterator endIt = " - << "interfaces.end();" << endl; - stream << " for (; it != endIt; ++it)" << endl; - stream << " {" << endl; - stream << " TQT_DBusObjectBase* interface = it.data();" << endl; - stream << " if (interface != this)" << endl; - stream << " delete interface;" << endl; - stream << " }" << endl; - stream << " interfaces.clear();" << endl; - stream << "}" << endl; - stream << endl; - - stream << "bool " << classData.name << "::Private" - << "::Introspect(TQString& data, TQT_DBusError& error)" << endl; - stream << "{" << endl; - stream << " Q_UNUSED(error);" << endl; - stream << " if (introspectionData.isEmpty()) cacheIntrospectionData();" - << endl; - stream << endl; - stream << " data = introspectionData;" << endl; - stream << endl; - stream << " return true;" << endl; - stream << "}" << endl; - stream << endl; - - stream << "void " << classData.name << "::Private" - << "::handleMethodReply(const TQT_DBusMessage& reply)" << endl; - stream << "{" << endl; - stream << " connection.send(reply);" << endl; - stream << "}" << endl; - stream << endl; - - writeNodeIntrospection(classData, interfaces, stream); -} - -// End of File diff --git a/tools/dbusxml2qt3/methodgen.h b/tools/dbusxml2qt3/methodgen.h deleted file mode 100644 index 9954fb2..0000000 --- a/tools/dbusxml2qt3/methodgen.h +++ /dev/null @@ -1,153 +0,0 @@ -/* -* Copyright (C) 2007 Kevin Krammer -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and associated documentation files (the "Software"), -* to deal in the Software without restriction, including without limitation -* the rights to use, copy, modify, merge, publish, distribute, sublicense, -* and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -* OTHER DEALINGS IN THE SOFTWARE. -*/ - -#if !defined(METHODGEN_H_INCLUDED) -#define METHODGEN_H_INCLUDED - -// TQt includes -#include -#include - -// forward declarations -class TQTextStream; - -class Argument -{ -public: - enum Direction - { - In, - Out - }; - - TQString name; - TQString annotatedType; - TQString signature; - TQString accessor; - TQString subAccessor; - TQString containerClass; - Direction direction; - bool isPrimitive; - - TQStringList forwardDeclarations; - TQMap headerIncludes; - TQMap sourceIncludes; - - TQString dbusSignature; -}; - -class Method -{ -public: - TQString name; - TQValueList arguments; - bool noReply; - bool async; -}; - -class Property : public Argument -{ -public: - bool read; - bool write; -}; - -class Class -{ -public: - enum Role - { - Interface, - Proxy, - Node - }; - - TQString name; - TQString dbusName; - TQStringList namespaces; - TQValueList methods; - TQValueList msignals; - TQValueList properties; - - TQValueList asyncMethods; - TQValueList asyncReplySignals; - TQValueList asyncReplyMethods; -}; - -class MethodGenerator -{ -public: - static bool extractMethods(const TQDomElement& interfaceElement, - Class& classData); - - static void writeMethodDeclaration(const Method& method, bool pureVirtual, - bool withError, TQTextStream& stream); - - static void writePropertyDeclaration(const Property& property, bool pureVirtual, - TQTextStream& stream); - - static void writeMethodCallDeclaration(const Method& method, - TQTextStream& stream); - - static void writeMethodCall(const Class& classData, const Method& method, - TQTextStream& stream); - - static void writeSignalEmitter(const Class& classData, const Method& method, - TQTextStream& stream); - - static void writeInterfaceAsyncReplyHandler(const Class& classData, - const Method& method, - TQTextStream& stream); - - static void writeInterfaceMainMethod(const Class& classData, - TQTextStream& stream); - - static void writeSignalHandler(const Class& classData, TQTextStream& stream); - - static void writeProxyBegin(const Class& classData, TQTextStream& stream); - - static void writeProxyMethod(const TQString& className, const Method& method, - TQTextStream& stream); - - static void writeProxyGenericProperty(const Class& classData, - TQTextStream& stream); - - static void writeProxyProperty(const Class& classData, const Property& property, - TQTextStream& stream); - - static void writeProxyAsyncReplyHandler(const Class& classData, - TQTextStream& stream); - - static void writeIntrospectionDataMethod(const Class& classData, - TQTextStream& stream); - - static void writeNodePrivate(const Class& classData, TQTextStream& stream); - - static void writeNodeBegin(const Class& classData, TQTextStream& stream); - - static void writeNodeMethods(const Class& classData, - const TQValueList& interfaces, TQTextStream& stream); -}; - -#endif - -// End of File diff --git a/tqdbusatomic.h b/tqdbusatomic.h deleted file mode 100644 index 50ceec3..0000000 --- a/tqdbusatomic.h +++ /dev/null @@ -1,40 +0,0 @@ -/* qdbusatomic.h Dummy reference counter - * - * Copyright (C) 2005 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef ATOMIC_H -#define ATOMIC_H - -class Atomic -{ -public: - Atomic(int value); - - void ref(); - - bool deref(); - -private: - int m_value; -}; - -#endif diff --git a/tqdbusconnection.cpp b/tqdbusconnection.cpp deleted file mode 100644 index 0360456..0000000 --- a/tqdbusconnection.cpp +++ /dev/null @@ -1,408 +0,0 @@ -/* qdbusconnection.cpp - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2005-2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include - -#include "tqdbusconnection.h" -#include "tqdbuserror.h" -#include "tqdbusmessage.h" -#include "tqdbusconnection_p.h" - -#include "tqdbusmessage_p.h" - -QT_STATIC_CONST_IMPL char *TQT_DBusConnection::default_connection_name = "qt_dbus_default_connection"; - -class TQT_DBusConnectionManager -{ -public: - TQT_DBusConnectionManager(): default_connection(0) {} - ~TQT_DBusConnectionManager(); - void bindToApplication(); - TQT_DBusConnectionPrivate *connection(const TQString &name) const; - void removeConnection(const TQString &name); - void setConnection(const TQString &name, TQT_DBusConnectionPrivate *c); - - static TQT_DBusConnectionManager* instance() { - if (managerInstance == 0) managerInstance = new TQT_DBusConnectionManager(); - return managerInstance; - } - -private: - TQT_DBusConnectionPrivate *default_connection; - // FIXME-QT4 TQHash connectionHash; - typedef TQMap ConnectionHash; - ConnectionHash connectionHash; - - static TQT_DBusConnectionManager* managerInstance; -}; - -// FIXME-QT4 TQ_GLOBAL_STATIC(TQT_DBusConnectionManager, manager); -TQT_DBusConnectionManager* TQT_DBusConnectionManager::managerInstance = 0; -TQT_DBusConnectionManager* manager() { - return TQT_DBusConnectionManager::instance(); -} - -TQT_DBusConnectionPrivate *TQT_DBusConnectionManager::connection(const TQString &name) const -{ - if (name == TQString::fromLatin1(TQT_DBusConnection::default_connection_name)) - return default_connection; - - ConnectionHash::const_iterator it = connectionHash.find(name); - - return (it != connectionHash.end() ? it.data() : 0); -} - -void TQT_DBusConnectionManager::removeConnection(const TQString &name) -{ - TQT_DBusConnectionPrivate *d = 0; - if (name == TQString::fromLatin1(TQT_DBusConnection::default_connection_name)) { - d = default_connection; - default_connection = 0; - } else { - ConnectionHash::iterator it = connectionHash.find(name); - if (it == connectionHash.end()) - return; - - d = it.data(); - connectionHash.erase(it); - } - if (!d->ref.deref()) - delete d; -} - -TQT_DBusConnectionManager::~TQT_DBusConnectionManager() -{ - if (default_connection) { - delete default_connection; - default_connection = 0; - } -/* FIXME-QT4 - for (TQHash::const_iterator it = connectionHash.constBegin(); - it != connectionHash.constEnd(); ++it) { - delete it.value(); - }*/ - for (ConnectionHash::const_iterator it = connectionHash.constBegin(); - it != connectionHash.constEnd(); ++it) - { - delete it.data(); - } - connectionHash.clear(); -} - -void TQT_DBusConnectionManager::bindToApplication() -{ - if (default_connection) { - default_connection->bindToApplication(); - } -/* FIXME-QT4 - for (TQHash::const_iterator it = connectionHash.constBegin(); - it != connectionHash.constEnd(); ++it) { - (*it)->bindToApplication(); - }*/ - for (ConnectionHash::const_iterator it = connectionHash.constBegin(); - it != connectionHash.constEnd(); ++it) - { - it.data()->bindToApplication(); - } -} - -void qDBusBindToApplication() -{ - manager()->bindToApplication(); -} - -void TQT_DBusConnectionManager::setConnection(const TQString &name, TQT_DBusConnectionPrivate *c) -{ - if (name == TQString::fromLatin1(TQT_DBusConnection::default_connection_name)) - default_connection = c; - else - connectionHash[name] = c; -} - - -TQT_DBusConnection::TQT_DBusConnection() : d(0) -{ -} - -TQT_DBusConnection::TQT_DBusConnection(const TQString &name) -{ - d = manager()->connection(name); - if (d) - d->ref.ref(); -} - -TQT_DBusConnection::TQT_DBusConnection(const TQT_DBusConnection &other) -{ - d = other.d; - if (d) - d->ref.ref(); -} - -TQT_DBusConnection::~TQT_DBusConnection() -{ - if (d && !d->ref.deref()) - delete d; -} - -TQT_DBusConnection &TQT_DBusConnection::operator=(const TQT_DBusConnection &other) -{ - if (other.d) - other.d->ref.ref(); -/* FIXME-QT4 - TQT_DBusConnectionPrivate *old = static_cast( - q_atomic_set_ptr(&d, other.d));*/ - TQT_DBusConnectionPrivate* old = d; - d = other.d; - if (old && !old->ref.deref()) - delete old; - - return *this; -} - -TQT_DBusConnection TQT_DBusConnection::sessionBus() -{ - return addConnection(TQT_DBusConnection::SessionBus); -} - -TQT_DBusConnection TQT_DBusConnection::systemBus() -{ - return addConnection(TQT_DBusConnection::SystemBus); -} - -TQT_DBusConnection TQT_DBusConnection::addConnection(BusType type, const TQString &name) -{ -// Q_ASSERT_X(TQCoreApplication::instance(), "TQT_DBusConnection::addConnection", -// "Cannot create connection without a Q[Core]Application instance"); - - TQT_DBusConnectionPrivate *d = manager()->connection(name); - if (d) - return TQT_DBusConnection(name); - - d = new TQT_DBusConnectionPrivate; - DBusConnection *c = 0; - switch (type) { - case SystemBus: - c = dbus_bus_get(DBUS_BUS_SYSTEM, &d->error); - break; - case SessionBus: - c = dbus_bus_get(DBUS_BUS_SESSION, &d->error); - break; - case ActivationBus: - c = dbus_bus_get(DBUS_BUS_STARTER, &d->error); - break; - } - d->setConnection(c); //setConnection does the error handling for us - - manager()->setConnection(name, d); - - return TQT_DBusConnection(name); -} - -TQT_DBusConnection TQT_DBusConnection::addConnection(const TQString &address, - const TQString &name) -{ -// Q_ASSERT_X(TQCoreApplication::instance(), "TQT_DBusConnection::addConnection", -// "Cannot create connection without a Q[Core]Application instance"); - - TQT_DBusConnectionPrivate *d = manager()->connection(name); - if (d) - return TQT_DBusConnection(name); - - d = new TQT_DBusConnectionPrivate; - // setConnection does the error handling for us - d->setConnection(dbus_connection_open(address.utf8().data(), &d->error)); - - manager()->setConnection(name, d); - - return TQT_DBusConnection(name); -} - -void TQT_DBusConnection::closeConnection(const TQString &name) -{ - manager()->removeConnection(name); -} - -void TQT_DBusConnectionPrivate::timerEvent(TQTimerEvent *e) -{ - DBusTimeout *timeout = timeouts[e->timerId()]; - dbus_timeout_handle(timeout); -} - -bool TQT_DBusConnection::send(const TQT_DBusMessage &message) const -{ - if (!d || !d->connection) - return false; - - DBusMessage *msg = message.toDBusMessage(); - if (!msg) - return false; - - bool isOk = dbus_connection_send(d->connection, msg, 0); - dbus_message_unref(msg); - return isOk; -} - -int TQT_DBusConnection::sendWithAsyncReply(const TQT_DBusMessage &message, TQObject *receiver, - const char *method) const -{ - if (!d || !d->connection) - return 0; - - return d->sendWithReplyAsync(message, receiver, method); -} - -TQT_DBusMessage TQT_DBusConnection::sendWithReply(const TQT_DBusMessage &message, TQT_DBusError *error) const -{ - if (!d || !d->connection) - return TQT_DBusMessage::fromDBusMessage(0); - - DBusMessage *msg = message.toDBusMessage(); - if (!msg) - return TQT_DBusMessage::fromDBusMessage(0); - - DBusMessage *reply = dbus_connection_send_with_reply_and_block(d->connection, msg, -1, &d->error); - - if (d->handleError() && error) - *error = d->lastError; - - dbus_message_unref(msg); - - TQT_DBusMessage ret = TQT_DBusMessage::fromDBusMessage(reply); - if (reply) { - dbus_message_unref(reply); - } - - bool dbus_error_set = dbus_error_is_set(&d->error); - ret.d->error.setDBUSError(dbus_error_set); - if (error) error->setDBUSError(dbus_error_set); - - return ret; -} - -void TQT_DBusConnection::flush() const -{ - if (!d || !d->connection) return; - - d->flush(); -} - -void TQT_DBusConnection::dispatch() const -{ - if (!d || !d->connection) return; - - d->dispatch(); -} - -void TQT_DBusConnection::scheduleDispatch() const -{ - if (!d || !d->connection) return; - - d->scheduleDispatch(); -} - -bool TQT_DBusConnection::connect(TQObject* object, const char* slot) -{ - if (!d || !d->connection || !object || !slot) - return false; - - bool ok = object->connect(d, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), slot); - - return ok; -} - -bool TQT_DBusConnection::disconnect(TQObject* object, const char* slot) -{ - if (!d || !d->connection || !object || !slot) - return false; - - bool ok = d->disconnect(object, slot); - - return ok; -} - -bool TQT_DBusConnection::registerObject(const TQString& path, TQT_DBusObjectBase* object) -{ - if (!d || !d->connection || !object || path.isEmpty()) - return false; - - TQT_DBusConnectionPrivate::ObjectMap::const_iterator it = d->registeredObjects.find(path); - if (it != d->registeredObjects.end()) - return false; - - d->registeredObjects.insert(path, object); - - return true; -} - -void TQT_DBusConnection::unregisterObject(const TQString &path) -{ - if (!d || !d->connection || path.isEmpty()) - return; - - TQT_DBusConnectionPrivate::ObjectMap::iterator it = d->registeredObjects.find(path); - if (it == d->registeredObjects.end()) - return ; - - d->registeredObjects.erase(it); -} - -bool TQT_DBusConnection::isConnected( ) const -{ - return d && d->connection && dbus_connection_get_is_connected(d->connection); -} - -TQT_DBusError TQT_DBusConnection::lastError() const -{ - return d ? d->lastError : TQT_DBusError(); -} - -TQString TQT_DBusConnection::uniqueName() const -{ - return d && d->connection ? - TQString::fromUtf8(dbus_bus_get_unique_name(d->connection)) - : TQString(); -} - -bool TQT_DBusConnection::requestName(const TQString &name, int modeFlags) -{ - Q_ASSERT(modeFlags >= 0); - - if (!d || !d->connection) - return false; - - if (modeFlags < 0) - return false; - - int dbusFlags = 0; - if (modeFlags & AllowReplace) - dbusFlags |= DBUS_NAME_FLAG_ALLOW_REPLACEMENT; - if (modeFlags & ReplaceExisting) - dbusFlags |= DBUS_NAME_FLAG_REPLACE_EXISTING; - - dbus_bus_request_name(d->connection, name.utf8(), dbusFlags, &d->error); - - return !d->handleError(); -} - -#include "tqdbusconnection.moc" diff --git a/tqdbusconnection.h b/tqdbusconnection.h deleted file mode 100644 index 9fde84b..0000000 --- a/tqdbusconnection.h +++ /dev/null @@ -1,663 +0,0 @@ -/* qdbusconnection.h TQT_DBusConnection object - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2005-2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSCONNECTION_H -#define TQDBUSCONNECTION_H - -/** - * @mainpage TQt3 Bindings for D-Bus - * - * D-Bus is an IPC (inter process communication) technology designed to allow - * applications to interoperate without requiring tight coupling. - * - * For more information about D-Bus itself see its website: - * http://www.freedesktop.org/wiki/Software_2fdbus - * - * The TQt3 D-Bus bindings described here are a TQt3 style API around the base - * implementation to enable TQt3 developers to use D-Bus in their applications - * without requiring them to know about the details of the C based D-Bus API. - * - * The two main use cases are: - * - using the API to access service implemented in other applications. - * See section @ref dbusclient for an introduction on this - * - * - using the API to provide access to services implemented in your application - * See section @ref dbusservice for an introduction on this - * - * Of course an application can do both at the same time. - */ - -/** - * @page dbusconventions Naming and syntax conventions in D-Bus - * - * @section dbusconventions-servicename Service names - * - * The service name is D-Bus application identifier, i.e. either - * the unique name handed out to the peer application by the bus on connect - * (see TQT_DBusConnection::uniqueName()) or, more likely, a well known name the - * peer application has requested, see TQT_DBusConnection::requestName() - * - * Such well known names have the form of word separated by dots, like - * Internet domain names but in reverse order. - * - * For example the name for the bus itself (the D-Bus daemon) would be - * @code - * "org.freedesktop.DBus" - * @endcode - * - * @section dbusconventions-objectpath Object paths - * - * The object path is like an address within the peer host application. - * The path format looks like a Unix file path, i.e. words separated by - * slash @c '/' characters. - * - * For example the path for the bus itself (the D-Bus daemon's main object) - * would be - * @code - * "/org/freedesktop/DBus" - * @endcode - * - * @section dbusconventions-interfacename Interface names - * - * The interface name specifies which group of methods and signals - * implemented by the peer service object is used in proxy operations. - * - * Interface names have the form of word separated by dots, like Internet - * domain names but in reverse order or like a fully qualified Java class name. - * - * For example the interface for the bus itself (the D-Bus daemon's main - * interface) would be - * @code - * "org.freedesktop.DBus" - * @endcode - * - * @section dbusconventions-errorname Error names - * - * A D-Bus error name is a sequence of words separated by dots, similar - * to D-Bus service names or interface names, or like a fully qualified - * Java class name. - * - * For example if a D-Bus service does not handle a method invocation sent - * to it because it doesn't know about the method it will return a D-Bus - * error named - * @code - * "org.freedesktop.DBus.Error.UnknownMethod" - * @endcode - * TQT_DBusError can create some of the more common errors based on a type value - * and decode their names into the type respectively. See TQT_DBusError#ErrorType - * - * @section dbusconventions-membername Method and signal names - * - * There is no mandatory convention for member names, neither for methods nor - * for signals. - * - * However, using the standard interfaces of D-Bus as a hint, it is recommended - * to use "camel case" names starting with an uppercase letter, for example - * @code - * "GetConnectionUnixUser" - * @endcode - */ - -#include "tqdbusmacros.h" -#include - -class TQT_DBusConnectionPrivate; -class TQT_DBusError; -class TQT_DBusMessage; -class TQT_DBusObjectBase; -class TQObject; - -/** - * @brief Provides access to a specific D-Bus bus - * - * In order to access a D-Bus message bus an application has to connect to it. - * This is very similar to connecting to an FTP server using TQFtp, where any - * number of commands can be sent in sequence over the same connection. - * - * Additionally to the asynchronous command execution provided by TQFtp a - * TQT_DBusConnection can also execute synchronous (blocking) calls so the - * code around those calls stays closer to in-process method incovations. - * - * However it is recommended to only perform blocking calls on D-Bus service - * methods that are likely to be processed fast. - * - * TQT_DBusConnection implements a shared resource, i.e. if you create a - * connection with a specific name in one part of your code and then - * create one with the same name somewhere else, the second creation will - * actually return the same shared connection object the first caller created. - * - * The application can be connected to more than one message bus simultaniously - * using one or more connections per bus, however the most common case is to - * have one connection per bus. - * - * The two main bus types are: - * - System bus: a bus connecting applications on one system across user - * or session boundaries, for example allowing to communicate - * with system services like printer spoolers, etc - * - * - Session bus: a bus connecting applications within one user session, for - * example started at login or by a session manager. Use cases - * or this kind of bus would be accessing user specific - * resources like addressbooks, retrieving user settings or - * controlling session services (e.g. disabling screensaver - * in a video player application during playback) - * - * While TQT_DBusConnection provides the basic API to access D-Bus services - * it is more convenient to use TQT_DBusProxy on top of the connection. - * - * See sections @ref dbusclient and @ref dbusservice for examples - */ -class TQDBUS_EXPORT TQT_DBusConnection -{ -public: - /** - * DBus bus types - */ - enum BusType - { - /** - * The session bus is a user and user session specific message - * channel. It will usually be started by a login script or a - * session manager. - */ - SessionBus, - - /** - * The system bus is a message channel bridging user level and - * system level process boundaries, e.g. it can allow a user process - * with normal user access restrictions to perform a limited subset - * of operations on a process running with elevated rights. - * - * @warning if an applications exposed services on the system bus, i.e. - * registers objects using registerObject(), it should be - * carefully examined on potential security issues - */ - SystemBus, - - // TODO find out about ActivationBus purpose - ActivationBus - }; - - /** - * @brief Creates an empty/disconnected connection handle - * - * This is mainly used for initializing variables of this type, i.e. like - * the default TQString constructor. - * - * A variable set to such an empty connection can be assigned a working - * connection at any time. - */ - TQT_DBusConnection(); - - /** - * @brief Creates a connection handle to a named connection - * - * This will result in an disconnected connection handle if no - * connection with that name has been created by addConnection before. - * - * Therefore it is recommended to use addConnection() instead to get a - * connection handle. - * - * @param name identifier of the shared connection object - */ - TQT_DBusConnection(const TQString &name); - - /** - * @brief Creates a shallow copy of the given connection - * - * Allows to pass connection handles around by value, similar to TQString - * thus avoiding problems like dangling pointers in application code - * - * @param other the connection to copy from - */ - TQT_DBusConnection(const TQT_DBusConnection &other); - - /** - * @brief Destroys the connection handle - * - * If this handle is the last one referencing the shared connection object - * it will delete it, disconnecting it from any objects it was - * collaborating with - */ - ~TQT_DBusConnection(); - - /** - * @brief Creates a shallow copy of the given connection - * - * Allows to pass connection handles around by value, similar to TQString - * thus avoiding problems like dangling pointers in application code - * - * @param other the connection to copy from - * - * @return a reference to this instance as required by assigment operator - * semantics - */ - TQT_DBusConnection &operator=(const TQT_DBusConnection &other); - - /** - * @brief Returns whether the connection is connected to a bus - * - * @return @c true if the connection can be used, @c false if the handle - * does not have access to a shared connection object or if the - * connection to the bus could not be established or broke - */ - bool isConnected() const; - - /** - * @brief Returns the last error seen by the connection - * - * This can be a connection error, e.g. attempt to connect failed, or a - * transmission error or an error reported by a method call - * - * @return the last error seen by the connection - */ - TQT_DBusError lastError() const; - - /** - * @brief Flags for controlling the behavior name collision handling - * - * @see requestName() - */ - enum NameRequestMode - { - /** - * Do not allow others to take over a name requested by this - * application - */ - NoReplace = 0, - - /** - * Allow other applications that request the same name to get it, - * i.e. allow the bus to transfer the name from this application - * to the one requesting it - */ - AllowReplace = 1, - - /** - * Try to get the name transferred from the current owner to this - * application. This will only work if the other application as - * requested the name using the AllowReplace flag - */ - ReplaceExisting = 2 - }; - - /** - * @brief Requests to be addressable on the bus by a given name - * - * Each connection to a bus gets a unique name once the connection is - * established. This is similar to getting an IP address when connecting - * to the Internet. - * - * If an application's purpose is to provide services to other applications - * the other applications require to know how to address the service - * provider. Similar to a domain name on the Internet D-Bus allows to - * register names on the bus and be addressed through those names instead - * of the connection identifier. - * - * @note this is not required if the application only needs to acccess - * services or only implements generic service APIs - * - * If more than one application request the same name, D-Bus will try - * to resolve this conflict as good as possible. - * The #NameRequestMode flags allow to control how an application prefers - * to be treated in such a conflict. - * - * @param name the name the connection should be addressable with. See - * section @ref dbusconventions-servicename - * @param modeFlags an OR'ed combination of #NameRequestMode flags - * - * @return @c true if the name request was successfull, @c false if - * the connection is not connected to a bus or the name is already - * taken and cannot be tranferred - * - * @see uniqueName() - */ - bool requestName(const TQString &name, int modeFlags = NoReplace); - - /** - * @brief Returns the connection identifier assigned at connect - * - * The unique name is the connection address or identifier the bus assigned - * to this connection when it got established. - * - * @return the connection's unique bus identifier - * - * @see requestName() - */ - TQString uniqueName() const; - - /** - * @brief Sends a message over the bus - * - * Sends a message composed through the TQT_DBusMessage API to the bus. - * This is the main method for service objects (see TQT_DBusObjectBase) to - * send replies and errors for method calls they accepted or for sending - * D-Bus signals. - * - * @note for doing method calls it is more convenient to use TQT_DBusProxy, - * see TQT_DBusProxy::send() - * - * @param message the message to send - * - * @return @c true if sending succeeded, @c false if the connection is not - * connected, if the message lacks information about the recepient - * or if sending fails a at a lower level in the communication - * stack - * - * @see lastError() - */ - bool send(const TQT_DBusMessage &message) const; - - /** - * @brief Sends a message over the bus and waits for the reply - * - * Sends a message composed through the TQT_DBusMessage API to the bus. - * It then blocks and waits until the associated reply is received. - * Any message received in between is stored and can be processed - * by calling dispatch() or scheduleDispatch() - * - * @note for doing method calls it is more convenient to use TQT_DBusProxy, - * see TQT_DBusProxy::sendWithReply() - * - * @param message the message to send - * @param error an optional parameter to directly get any error that might - * occur during processing of the call - * - * @return a message containing either the call's reply or an invalid - * message in case the call failed - * - * @see lastError() - */ - TQT_DBusMessage sendWithReply(const TQT_DBusMessage &message, TQT_DBusError *error = 0) const; - - /** - * @brief Sends a message over the bus, specifying a receiver object for - * replies - * - * Sends a message composed through the TQT_DBusMessage API to the bus and - * returns an identifier number to associate with the reply once it is - * received by the given receiver. - * See TQT_DBusMessage::replySerialNumber() - * - * The required slot signature is - * @code - * void slotname(const TQT_DBusMessage&); - * @endcode - * - * @note for doing method calls it is more convenient to use TQT_DBusProxy, - * see TQT_DBusProxy::sendWithAsyncReply() - * - * @param message the message to send - * @param receiver the TQObject to relay the reply to - * @param slot the slot to invoke for the reply - * - * @return a numeric identifier for association with the reply or @c 0 if - * sending failed - * - * @see lastError() - */ - int sendWithAsyncReply(const TQT_DBusMessage &message, TQObject *receiver, - const char *slot) const; - - /** - * @brief Flushes buffered outgoing message - * - * Attempts to send all enqueued outgoing messages before returning. - */ - void flush() const; - - /** - * @brief Processes buffered inbound messages - * - * Attempts to process all enqueued inbound messages, e.g. replies to - * method calls or received signals. - * - * @warning dispatching message can result in TQt signals being emitted - * before this method returns. In case you just want to make sure - * no inbound message is forgotten, call scheduleDispatch() which - * will execute the dispatch delayed through the event loop. - */ - void dispatch() const; - - /** - * @brief Request a delayed check for inbound buffer processing - * - * Similar to dispatch() but delayed by a single shot timer to ensure - * the method has returned before the processing is started. - * - * If a asynchronous method call is followed by a synchronous call without - * returning to the event loop in between, a call to scheduleDispatch() - * ensures that a pending reply to the asynchronous call is processed - * as soon as possible - */ - void scheduleDispatch() const; - - /** - * @brief Connects an object to receive D-Bus signals - * - * This provides a basic access to all D-Bus signals received on this - * connection. - * For every D-Bus signal processed by the connection object a TQt signal - * is emitted and thus delivered to all receiver objects connected - * through this method. - * - * The required slot signature is - * @code - * void slotname(const TQT_DBusMessage&); - * @endcode - * - * so a suitable receiver could look like this - * @code - * class DBusSignalReceiver : public TQObject - * { - * Q_OBJECT - * - * public slots: - * void dbusSignal(const TQT_DBusMessage&); - * }; - * @endcode - * - * and would be connected like this - * @code - * // assuming the following variables - * TQT_DBusConnection connection; - * DBusSignalReceiver* receiver; - * - * connection.connect(receiver, TQT_SLOT(dbusSignal(const TQT_DBusMessage&))); - * @endcode - * - * See TQT_DBusProxy::dbusSignal() for a more obvious way of connecting slots. - * - * @param object the receiver object - * @param slot the receiver slot (or signal for signal->signal connections) - * - * @return @c true if the connection was successfull, otherwise @c false - * - * @see disconnect() - */ - bool connect(TQObject* object, const char* slot); - - /** - * @brief Disconnects a given receiver from the D-Bus signal handling - * - * @param object the receiver object to disconnect from - * @param slot the receiver slot (or signal for signal->signal connections) - * - * @return @c true if the disconnect was successfull, otherwise @c false - * - * @see connect() - */ - bool disconnect(TQObject* object, const char* slot); - - /** - * @brief Registers a service object for a given path - * - * In order to receive method calls over the D-Bus connection the service - * objects path within its host application has to be registered with the - * connection. See section @ref dbusconventions-objectpath for details. - * - * Only one objects can be registered for a single object path, i.e. - * the path -> object mapping is unambiguous, similar to mapping of - * filesystem paths to files. - * - * If a service object offers more than one interface it is up to the - * service implementation if all are implemented in the object path to this - * method or if the passed object is just another demultiplexer which - * relays the message to the interface implementor. - * - * @param path the object path to register the object for - * @param object the service implementation object for that path - * - * @return @c true if the given object is now registered for the given path - * or @c false if path is empty, object is null or another object - * is already registered for this path - * - * @see unregisterObject() - */ - bool registerObject(const TQString& path, TQT_DBusObjectBase* object); - - /** - * @brief Unregister a service object on a given path - * - * Removes any mapping of object path to service object previously - * registered by registerObject(). - * See section @ref dbusconventions-objectpath for details. - * - * @warning always(!) unregister a service object before deleting it - * - * @param path the object path of the object to unregister - * - * @see registerObject() - */ - void unregisterObject(const TQString &path); - - /** - * @brief Gets a connection to the session bus - * - * Convenience overload for creating the default shared connection to the - * D-Bus session bus. - * - * Equivalent to calling addConnection(SessionBus); - * - * @return a connection handle. Check isConnected() to find out if the - * connection attempt has been successfull - * - * @see addConnection(BusType,const TQString&); - */ - static TQT_DBusConnection sessionBus(); - - /** - * @brief Gets a connection to the system bus - * - * Convenience overload for creating the default shared connection to the - * D-Bus system bus. - * - * Equivalent to calling addConnection(SystemBus); - * - * @return a connection handle. Check isConnected() to find out if the - * connection attempt has been successfull - * - * @see addConnection(BusType,const TQString&); - */ - static TQT_DBusConnection systemBus(); - - /** - * @brief Add a connection to a bus with a specific bus type - * - * This is a factory method as it will create a connection for the given - * name if its not available yet, but return a previously created - * connection for that name if available. - * - * Depending on the #BusType the D-Bus library will connect to the address - * configured for that type, so this is the recommended way to create - * connection to D-Bus. - * - * @code - * // Associate the default connection name with a connection to the user's - * // session bus - * TQT_DBusConnection con = TQT_DBusConnection::addConnection(TQT_DBusConnection::SessionBus); - * - * // check if we are connected and which uniqueName we got - * if (con.isConnected()) - * { - * tqDebug("Connected to session bus. We got uniqueName %s", - * con.uniqueName().local8Bit().data()); - * } - * @endcode - * For the common use cases see also sessionBus() and systemBus() - * - * @param type the #BusType of the bus to connect to - * @param name the name to use for TQT_DBusConnection's connection sharing - * - * @return a connection handle. Check isConnected() to find out if the - * connection attempt has been successfull - * - * @see closeConnection() - */ - static TQT_DBusConnection addConnection(BusType type, - const TQString &name = default_connection_name); - - /** - * @brief Add a connection to a bus at a specific address - * - * This is a factory method as it will create a connection for the given - * name if its not available yet, but return a previously created - * connection for that name if available. - * - * @note this requires to know the address of a D-Bus daemon to connect to - * - * @param address the address of the D-Bus daemon. Usually a Unix domain - * socket address - * @param name the name to use for TQT_DBusConnection's connection sharing - * - * @return a connection handle. Check isConnected() to find out if the - * connection attempt has been successfull - * - * @see closeConnection() - */ - static TQT_DBusConnection addConnection(const TQString &address, - const TQString &name = default_connection_name); - - // TODO check why this doesn't close the D-Bus connection - /** - * @brief Closes a connection with a given name - * - * Removes the name from the pool of shared connections, i.e. a call to - * addConnection() with the same name afterwards will create a new - * connection. - * - * @param name the connection name as used in addConnection() - */ - static void closeConnection(const TQString &name = default_connection_name); - - /** - * String used as the default parameter for connection names - */ - QT_STATIC_CONST char *default_connection_name; - -private: - TQT_DBusConnectionPrivate *d; -}; - -#endif diff --git a/tqdbusconnection_p.h b/tqdbusconnection_p.h deleted file mode 100644 index 6e4efd1..0000000 --- a/tqdbusconnection_p.h +++ /dev/null @@ -1,177 +0,0 @@ -/* qdbusconnection_p.h TQT_DBusConnection private object - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2005 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the public API. This header file may -// change from version to version without notice, or even be -// removed. -// -// We mean it. -// -// - -#ifndef TQDBUSCONNECTION_P_H -#define TQDBUSCONNECTION_P_H - -#include -#include -#include -#include - -#include - -#include "tqdbusatomic.h" -#include "tqdbuserror.h" -#include "tqdbusobject.h" -#include "tqdbusmessage.h" - -class TQT_DBusMessage; -class TQSocketNotifier; -class TQTimer; -class TQTimerEvent; - -struct DBusConnection; -struct DBusServer; - -class TQT_DBusResultInfo -{ - public: - TQT_DBusMessage message; - TQObject* receiver; - TQCString method; -}; -typedef TQValueList TQT_DBusResultInfoList; - -class TQT_DBusConnectionPrivate: public TQObject -{ - Q_OBJECT - - -public: - TQT_DBusConnectionPrivate(TQObject *parent = 0); - ~TQT_DBusConnectionPrivate(); - - void bindToApplication(); - - void setConnection(DBusConnection *connection); - void setServer(DBusServer *server); - void closeConnection(); - void timerEvent(TQTimerEvent *e); - - bool handleSignal(DBusMessage *msg); - bool handleObjectCall(DBusMessage *message); - bool handleError(); - - void emitPendingCallReply(const TQT_DBusMessage& message); - -signals: - void dbusSignal(const TQT_DBusMessage& message); - - void dbusPendingCallReply(const TQT_DBusMessage& message); - -public slots: - void socketRead(int); - void socketWrite(int); - - void objectDestroyed(TQObject* object); - - void purgeRemovedWatches(); - - void scheduleDispatch(); - void dispatch(); - -public: - DBusError error; - TQT_DBusError lastError; - - enum ConnectionMode { InvalidMode, ServerMode, ClientMode }; - - // FIXME TQAtomic ref; - Atomic ref; - ConnectionMode mode; - DBusConnection *connection; - DBusServer *server; - - TQTimer* dispatcher; - - static int messageMetaType; - static int registerMessageMetaType(); - int sendWithReplyAsync(const TQT_DBusMessage &message, TQObject *receiver, - const char *method); - void flush(); - - struct Watcher - { - Watcher(): watch(0), read(0), write(0) {} - DBusWatch *watch; - TQSocketNotifier *read; - TQSocketNotifier *write; - }; - // FIXME typedef TQMultiHash WatcherHash; - typedef TQValueList WatcherList; - WatcherList removedWatches; - typedef TQMap WatcherHash; - WatcherHash watchers; - - // FIXME typedef TQHash TimeoutHash; - typedef TQMap TimeoutHash; - TimeoutHash timeouts; - - typedef TQMap ObjectMap; - ObjectMap registeredObjects; - - TQValueList pendingTimeouts; - - struct TQT_DBusPendingCall - { - TQGuardedPtr receiver; - TQCString method; - DBusPendingCall *pending; - }; - typedef TQMap PendingCallMap; - PendingCallMap pendingCalls; - - typedef TQValueList PendingMessagesForEmit; - PendingMessagesForEmit pendingMessages; - - bool inDispatch; - - TQT_DBusResultInfoList m_resultEmissionQueue; - -public: - void newMethodInResultEmissionQueue(); - -private slots: - void transmitResultEmissionQueue(); - void transmitMessageEmissionQueue(); - -private: - TQTimer* m_resultEmissionQueueTimer; - TQTimer* m_messageEmissionQueueTimer; -}; - -#endif diff --git a/tqdbusdata.cpp b/tqdbusdata.cpp deleted file mode 100644 index 629df57..0000000 --- a/tqdbusdata.cpp +++ /dev/null @@ -1,1121 +0,0 @@ -/* qdbusdata.cpp DBUS data transport type - * - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include "dbus/dbus.h" - -#include "tqdbusdata.h" -#include "tqdbusdatalist.h" -#include "tqdbusdatamap.h" -#include "tqdbusobjectpath.h" -#include "tqdbusunixfd.h" -#include "tqdbusvariant.h" - -#include -#include -#include - -class TQT_DBusData::Private : public TQShared -{ -public: - Private() : TQShared(), type(TQT_DBusData::Invalid), keyType(TQT_DBusData::Invalid) {} - - ~Private() - { - switch (type) - { - case TQT_DBusData::String: - delete (TQString*)value.pointer; - break; - - case TQT_DBusData::ObjectPath: - delete (TQT_DBusObjectPath*)value.pointer; - break; - - case TQT_DBusData::UnixFd: - delete (TQT_DBusUnixFd*)value.pointer; - break; - - case TQT_DBusData::List: - delete (TQT_DBusDataList*)value.pointer; - break; - - case TQT_DBusData::Struct: - delete (TQValueList*)value.pointer; - break; - - case TQT_DBusData::Variant: - delete (TQT_DBusVariant*)value.pointer; - break; - - case TQT_DBusData::Map: - switch (keyType) - { - case TQT_DBusData::Byte: - delete (TQT_DBusDataMap*)value.pointer; - break; - - case TQT_DBusData::Int16: - delete (TQT_DBusDataMap*)value.pointer; - break; - - case TQT_DBusData::UInt16: - delete (TQT_DBusDataMap*)value.pointer; - break; - - case TQT_DBusData::Int32: - delete (TQT_DBusDataMap*)value.pointer; - break; - - case TQT_DBusData::UInt32: - delete (TQT_DBusDataMap*)value.pointer; - break; - - case TQT_DBusData::Int64: - delete (TQT_DBusDataMap*)value.pointer; - break; - - case TQT_DBusData::UInt64: - delete (TQT_DBusDataMap*)value.pointer; - break; - - case TQT_DBusData::String: - delete (TQT_DBusDataMap*)value.pointer; - break; - - case TQT_DBusData::ObjectPath: - delete (TQT_DBusDataMap*)value.pointer; - break; - - case TQT_DBusData::UnixFd: - delete (TQT_DBusDataMap*)value.pointer; - break; - - default: - tqFatal("TQT_DBusData::Private: unhandled map key type %d(%s)", - keyType, TQT_DBusData::typeName(keyType)); - break; - } - break; - - default: - break; - } - } - -public: - Type type; - Type keyType; - - union - { - bool boolValue; - TQ_UINT8 byteValue; - TQ_INT16 int16Value; - TQ_UINT16 uint16Value; - TQ_INT32 int32Value; - TQ_UINT32 uint32Value; - TQ_INT64 int64Value; - TQ_UINT64 uint64Value; - double doubleValue; - void* pointer; - } value; -}; - -// key type definitions for TQT_DBusDataMap -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::Byte; - -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::Int16; - -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::UInt16; - -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::Int32; - -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::UInt32; - -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::Int64; - -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::UInt64; - -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::String; - -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::ObjectPath; - -template <> -const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::UnixFd; - - -TQT_DBusData::TQT_DBusData() : d(new Private()) -{ -} - -TQT_DBusData::TQT_DBusData(const TQT_DBusData& other) : d(0) -{ - d = other.d; - - d->ref(); -} - -TQT_DBusData::~TQT_DBusData() -{ - if (d->deref()) delete d; -} - -TQT_DBusData& TQT_DBusData::operator=(const TQT_DBusData& other) -{ - if (&other == this) return *this; - - if (d->deref()) delete d; - - d = other.d; - - d->ref(); - - return *this; -} - -bool TQT_DBusData::operator==(const TQT_DBusData& other) const -{ - if (&other == this) return true; - - if (d == other.d) return true; - - if (d->type == other.d->type) - { - switch (d->type) - { - case TQT_DBusData::Invalid: - return true; - - case TQT_DBusData::Bool: - return d->value.boolValue == other.d->value.boolValue; - - case TQT_DBusData::Byte: - return d->value.byteValue == other.d->value.byteValue; - - case TQT_DBusData::Int16: - return d->value.int16Value == other.d->value.int16Value; - - case TQT_DBusData::UInt16: - return d->value.uint16Value == other.d->value.uint16Value; - - case TQT_DBusData::Int32: - return d->value.int32Value == other.d->value.int32Value; - - case TQT_DBusData::UInt32: - return d->value.uint32Value == other.d->value.uint64Value; - - case TQT_DBusData::Int64: - return d->value.int64Value == other.d->value.int64Value; - - case TQT_DBusData::UInt64: - return d->value.uint64Value == other.d->value.uint64Value; - - case TQT_DBusData::Double: - // FIXME: should not compare doubles for equality like this - return d->value.doubleValue == other.d->value.doubleValue; - - case TQT_DBusData::String: - return toString() == other.toString(); - - case TQT_DBusData::ObjectPath: - return toObjectPath() == other.toObjectPath(); - - case TQT_DBusData::UnixFd: - return toUnixFd() == other.toUnixFd(); - - case TQT_DBusData::List: - return toList() == other.toList(); - - case TQT_DBusData::Struct: - return toStruct() == other.toStruct(); - - case TQT_DBusData::Variant: - return toVariant() == other.toVariant(); - - case TQT_DBusData::Map: - if (d->keyType != other.d->keyType) return false; - - switch (d->keyType) - { - case TQT_DBusData::Byte: - return toByteKeyMap() == other.toByteKeyMap(); - - case TQT_DBusData::Int16: - return toInt16KeyMap() == other.toInt16KeyMap(); - - case TQT_DBusData::UInt16: - return toUInt16KeyMap() == other.toUInt16KeyMap(); - - case TQT_DBusData::Int32: - return toInt32KeyMap() == other.toInt32KeyMap(); - - case TQT_DBusData::UInt32: - return toUInt32KeyMap() == other.toUInt32KeyMap(); - - case TQT_DBusData::Int64: - return toInt64KeyMap() == other.toInt64KeyMap(); - - case TQT_DBusData::UInt64: - return toUInt64KeyMap() == other.toUInt64KeyMap(); - - case TQT_DBusData::String: - return toStringKeyMap() == other.toStringKeyMap(); - - case TQT_DBusData::ObjectPath: - return toObjectPathKeyMap() == other.toObjectPathKeyMap(); - - case TQT_DBusData::UnixFd: - return toUnixFdKeyMap() == other.toUnixFdKeyMap(); - - default: - tqFatal("TQT_DBusData operator== unhandled map key type %d(%s)", - d->keyType, TQT_DBusData::typeName(d->keyType)); - break; - } - - break; - } - } - - return false; -} - -bool TQT_DBusData::operator!=(const TQT_DBusData& other) const -{ - return !operator==(other); -} - -TQT_DBusData::Type TQT_DBusData::type() const -{ - return d->type; -} - -TQT_DBusData::Type TQT_DBusData::keyType() const -{ - if (d->type != TQT_DBusData::Map) return TQT_DBusData::Invalid; - - return d->keyType; -} - -const char* TQT_DBusData::typeName(Type type) -{ - switch (type) - { - case TQT_DBusData::Invalid: return "Invalid"; - case TQT_DBusData::Bool: return "Bool"; - case TQT_DBusData::Byte: return "Byte"; - case TQT_DBusData::Int16: return "Int16"; - case TQT_DBusData::UInt16: return "UInt16"; - case TQT_DBusData::Int32: return "Int32"; - case TQT_DBusData::UInt32: return "UInt32"; - case TQT_DBusData::Int64: return "Int64"; - case TQT_DBusData::UInt64: return "UInt64"; - case TQT_DBusData::Double: return "Double"; - case TQT_DBusData::String: return "String"; - case TQT_DBusData::ObjectPath: return "ObjectPath"; - case TQT_DBusData::UnixFd: return "UnixFd"; - case TQT_DBusData::List: return "List"; - case TQT_DBusData::Struct: return "Struct"; - case TQT_DBusData::Variant: return "Variant"; - case TQT_DBusData::Map: return "Map"; - } - - return 0; -} - -TQT_DBusData TQT_DBusData::fromBool(bool value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Bool; - data.d->value.boolValue = value; - - return data; -} - -bool TQT_DBusData::toBool(bool* ok) const -{ - if (d->type != TQT_DBusData::Bool) - { - if (ok != 0) *ok = false; - return false; - } - - if (ok != 0) *ok = true; - - return d->value.boolValue; -} - -TQT_DBusData TQT_DBusData::fromByte(TQ_UINT8 value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Byte; - data.d->value.byteValue = value; - - return data; -} - -TQ_UINT8 TQT_DBusData::toByte(bool* ok) const -{ - if (d->type != TQT_DBusData::Byte) - { - if (ok != 0) *ok = false; - return 0; - } - - if (ok != 0) *ok = true; - - return d->value.byteValue; -} - -TQT_DBusData TQT_DBusData::fromInt16(TQ_INT16 value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Int16; - data.d->value.int16Value = value; - - return data; -} - -TQ_INT16 TQT_DBusData::toInt16(bool* ok) const -{ - if (d->type != TQT_DBusData::Int16) - { - if (ok != 0) *ok = false; - return 0; - } - - if (ok != 0) *ok = true; - - return d->value.int16Value; -} - -TQT_DBusData TQT_DBusData::fromUInt16(TQ_UINT16 value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::UInt16; - data.d->value.uint16Value = value; - - return data; -} - -TQ_UINT16 TQT_DBusData::toUInt16(bool* ok) const -{ - if (d->type != TQT_DBusData::UInt16) - { - if (ok != 0) *ok = false; - return 0; - } - - if (ok != 0) *ok = true; - - return d->value.uint16Value; -} - -TQT_DBusData TQT_DBusData::fromInt32(TQ_INT32 value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Int32; - data.d->value.int32Value = value; - - return data; -} - -TQ_INT32 TQT_DBusData::toInt32(bool* ok) const -{ - if (d->type != TQT_DBusData::Int32) - { - if (ok != 0) *ok = false; - return 0; - } - - if (ok != 0) *ok = true; - - return d->value.int32Value; -} - -TQT_DBusData TQT_DBusData::fromUInt32(TQ_UINT32 value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::UInt32; - data.d->value.uint32Value = value; - - return data; -} - -TQ_UINT32 TQT_DBusData::toUInt32(bool* ok) const -{ - if (d->type != TQT_DBusData::UInt32) - { - if (ok != 0) *ok = false; - return 0; - } - - if (ok != 0) *ok = true; - - return d->value.uint32Value; -} - -TQT_DBusData TQT_DBusData::fromInt64(TQ_INT64 value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Int64; - data.d->value.int64Value = value; - - return data; -} - -TQ_INT64 TQT_DBusData::toInt64(bool* ok) const -{ - if (d->type != TQT_DBusData::Int64) - { - if (ok != 0) *ok = false; - return 0; - } - - if (ok != 0) *ok = true; - - return d->value.int64Value; -} - -TQT_DBusData TQT_DBusData::fromUInt64(TQ_UINT64 value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::UInt64; - data.d->value.uint64Value = value; - - return data; -} - -TQ_UINT64 TQT_DBusData::toUInt64(bool* ok) const -{ - if (d->type != TQT_DBusData::UInt64) - { - if (ok != 0) *ok = false; - return 0; - } - - if (ok != 0) *ok = true; - - return d->value.uint64Value; -} - -TQT_DBusData TQT_DBusData::fromDouble(double value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Double; - data.d->value.doubleValue = value; - - return data; -} - -double TQT_DBusData::toDouble(bool* ok) const -{ - if (d->type != TQT_DBusData::Double) - { - if (ok != 0) *ok = false; - return 0.0; - } - - if (ok != 0) *ok = true; - - return d->value.doubleValue; -} - -TQT_DBusData TQT_DBusData::fromString(const TQString& value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::String; - data.d->value.pointer = new TQString(value); - - return data; -} - -TQString TQT_DBusData::toString(bool* ok) const -{ - if (d->type != TQT_DBusData::String) - { - if (ok != 0) *ok = false; - return TQString(); - } - - if (ok != 0) *ok = true; - - return *((TQString*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromObjectPath(const TQT_DBusObjectPath& value) -{ - TQT_DBusData data; - - if (value.isValid()) - { - data.d->type = TQT_DBusData::ObjectPath; - data.d->value.pointer = new TQT_DBusObjectPath(value); - } - - return data; -} - -TQT_DBusObjectPath TQT_DBusData::toObjectPath(bool* ok) const -{ - if (d->type != TQT_DBusData::ObjectPath) - { - if (ok != 0) *ok = false; - return TQT_DBusObjectPath(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusObjectPath*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromUnixFd(const TQT_DBusUnixFd& value) -{ - TQT_DBusData data; - - if (value.isValid()) - { - data.d->type = TQT_DBusData::UnixFd; - data.d->value.pointer = new TQT_DBusUnixFd(value); - } - - return data; -} - -TQT_DBusUnixFd TQT_DBusData::toUnixFd(bool* ok) const -{ - if (d->type != TQT_DBusData::UnixFd) - { - if (ok != 0) *ok = false; - return TQT_DBusUnixFd(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusUnixFd*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromList(const TQT_DBusDataList& list) -{ - TQT_DBusData data; - - if (list.type() == TQT_DBusData::Invalid) return data; - - data.d->type = TQT_DBusData::List; - data.d->value.pointer = new TQT_DBusDataList(list); - - return data; -} - -TQT_DBusDataList TQT_DBusData::toList(bool* ok) const -{ - if (d->type != TQT_DBusData::List) - { - if (ok != 0) *ok = false; - return TQT_DBusDataList(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataList*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromTQValueList(const TQValueList& list) -{ - return fromList(TQT_DBusDataList(list)); -} - -TQValueList TQT_DBusData::toTQValueList(bool* ok) const -{ - bool internalOk = false; - TQT_DBusDataList list = toList(&internalOk); - - if (!internalOk) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - return list.toTQValueList(); -} - -TQT_DBusData TQT_DBusData::fromStruct(const TQValueList& memberList) -{ - TQT_DBusData data; - - TQValueList::const_iterator it = memberList.begin(); - TQValueList::const_iterator endIt = memberList.end(); - for (; it != endIt; ++it) - { - if ((*it).d->type == Invalid) return data; - } - - data.d->type = TQT_DBusData::Struct; - data.d->value.pointer = new TQValueList(memberList); - - return data; -} - -TQValueList TQT_DBusData::toStruct(bool* ok) const -{ - if (d->type != TQT_DBusData::Struct) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - if (ok != 0) *ok = true; - - return *((TQValueList*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromVariant(const TQT_DBusVariant& value) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Variant; - data.d->value.pointer = new TQT_DBusVariant(value); - - return data; -} - -TQT_DBusVariant TQT_DBusData::toVariant(bool* ok) const -{ - if (d->type != TQT_DBusData::Variant) - { - if (ok != 0) *ok = false; - return TQT_DBusVariant(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusVariant*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromByteKeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toByteKeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromInt16KeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toInt16KeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromUInt16KeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toUInt16KeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && - d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromInt32KeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toInt32KeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromUInt32KeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toUInt32KeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && - d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromInt64KeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toInt64KeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromUInt64KeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toUInt64KeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && - d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromStringKeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toStringKeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromObjectPathKeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toObjectPathKeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && - d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -TQT_DBusData TQT_DBusData::fromUnixFdKeyMap(const TQT_DBusDataMap& map) -{ - TQT_DBusData data; - - data.d->type = TQT_DBusData::Map; - data.d->keyType = map.keyType(); - data.d->value.pointer = new TQT_DBusDataMap(map); - - return data; -} - -TQT_DBusDataMap TQT_DBusData::toUnixFdKeyMap(bool* ok) const -{ - if (d->type != TQT_DBusData::Map && - d->keyType != TQT_DBusDataMap::m_keyType) - { - if (ok != 0) *ok = false; - return TQT_DBusDataMap(); - } - - if (ok != 0) *ok = true; - - return *((TQT_DBusDataMap*)d->value.pointer); -} - -static const char* qDBusTypeForTQT_DBusType(TQT_DBusData::Type type) -{ - switch (type) - { - case TQT_DBusData::Invalid: - return 0; - case TQT_DBusData::Bool: - return DBUS_TYPE_BOOLEAN_AS_STRING; - case TQT_DBusData::Byte: - return DBUS_TYPE_BYTE_AS_STRING; - case TQT_DBusData::Int16: - return DBUS_TYPE_INT16_AS_STRING; - case TQT_DBusData::UInt16: - return DBUS_TYPE_UINT16_AS_STRING; - case TQT_DBusData::Int32: - return DBUS_TYPE_INT32_AS_STRING; - case TQT_DBusData::UInt32: - return DBUS_TYPE_UINT32_AS_STRING; - case TQT_DBusData::Int64: - return DBUS_TYPE_INT64_AS_STRING; - case TQT_DBusData::UInt64: - return DBUS_TYPE_UINT64_AS_STRING; - case TQT_DBusData::Double: - return DBUS_TYPE_DOUBLE_AS_STRING; - case TQT_DBusData::String: - return DBUS_TYPE_STRING_AS_STRING; - case TQT_DBusData::ObjectPath: - return DBUS_TYPE_OBJECT_PATH_AS_STRING; - case TQT_DBusData::UnixFd: - return DBUS_TYPE_UNIX_FD_AS_STRING; - case TQT_DBusData::Variant: - return DBUS_TYPE_VARIANT_AS_STRING; - default: - break; - } - return 0; -} - -template -TQCString qDBusSignatureForMapValue(const TQT_DBusDataMap& map) -{ - if (map.hasContainerValueType()) - return map.containerValueType().buildDBusSignature(); - else - return qDBusTypeForTQT_DBusType(map.valueType()); -} - -TQCString TQT_DBusData::buildDBusSignature() const -{ - TQCString signature; - - switch (d->type) - { - case TQT_DBusData::List: - { - TQT_DBusDataList* list = (TQT_DBusDataList*) d->value.pointer; - signature = DBUS_TYPE_ARRAY_AS_STRING; - if (list->hasContainerItemType()) - signature += list->containerItemType().buildDBusSignature(); - else - signature += qDBusTypeForTQT_DBusType(list->type()); - break; - } - - case TQT_DBusData::Struct: - { - signature += DBUS_STRUCT_BEGIN_CHAR; - - TQValueList* memberList = - (TQValueList*) d->value.pointer; - - TQValueList::const_iterator it = (*memberList).begin(); - TQValueList::const_iterator endIt = (*memberList).end(); - for (; it != endIt; ++it) - { - signature += (*it).buildDBusSignature(); - } - signature += DBUS_STRUCT_END_CHAR; - break; - } - - case TQT_DBusData::Map: - signature += DBUS_TYPE_ARRAY_AS_STRING; - signature += DBUS_DICT_ENTRY_BEGIN_CHAR; - - signature += qDBusTypeForTQT_DBusType(keyType()); - - switch (keyType()) - { - case TQT_DBusData::Byte: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - case TQT_DBusData::Int16: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - case TQT_DBusData::UInt16: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - case TQT_DBusData::Int32: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - case TQT_DBusData::UInt32: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - case TQT_DBusData::Int64: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - case TQT_DBusData::UInt64: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - case TQT_DBusData::String: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - case TQT_DBusData::ObjectPath: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - case TQT_DBusData::UnixFd: - signature += qDBusSignatureForMapValue( - *((TQT_DBusDataMap*) d->value.pointer)); - break; - default: - break; - } - - signature += DBUS_DICT_ENTRY_END_CHAR; - break; - - default: - signature = qDBusTypeForTQT_DBusType(d->type); - break; - } - - return signature; -} diff --git a/tqdbusdata.h b/tqdbusdata.h deleted file mode 100644 index ae64706..0000000 --- a/tqdbusdata.h +++ /dev/null @@ -1,1223 +0,0 @@ -/* qdbusdata.h DBUS data transport type - * - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSDATA_H -#define TQDBUSDATA_H - -#include "tqdbusmacros.h" -#include - -class TQCString; -class TQT_DBusDataList; -class TQT_DBusVariant; -class TQT_DBusObjectPath; -class TQT_DBusUnixFd; -class TQString; - -template class TQValueList; -template class TQT_DBusDataMap; - -/** - * @brief Class for accurately representing D-Bus data types - * - * The TQT_DBusData class can be compared to TQt's TQVariant class, but - * specialized to contain data types used in D-Bus messages. - * - * Like TQVariant objects of TQT_DBusData use implicit sharing, i.e. copying - * a TQT_DBusData object is a cheap operation and does not require that the - * content itself is copied. - * - * Depending on the #Type of the object, the content can be a recursive - * construct of TQT_DBusData objects, e.g. a #List can contain elements that are - * containers themselves, e.g. #Map, #Struct, #Variant or even #List again. - * - * @see TQT_DBusDataList - * @see TQT_DBusDataMap - * @see TQT_DBusDataConverter - */ -class TQDBUS_EXPORT TQT_DBusData -{ -public: - /** - * @brief Enum for the data types used in D-Bus messages - * - * In order to provide correct mapping of C++ and TQt types and the data - * types used in D-Bus messages, TQT_DBusData uses explicit naming of types - * where the name is usually the one used in D-Bus, with the exception of - * #List and #Map since this is closer to the TQt container they are - * implemented with (TQValueList and TQMap respectively) - * - * @see type(), keyType() - * @see typeName() - */ - enum Type - { - /** - * Base type for TQT_DBusData objects created by the default constructor. - * - * Also used as the type of returned objects when getter type methods - * fail due to type incompatabilties, i.e. toInt32() called on a #List - * object. - * - * @see isValid() - */ - Invalid = 0, - - /** - * Type when encapsulating a boolean value. - * - * @see fromBool(), toBool() - */ - Bool, - - /** - * Type when encapsulating a byte (unsigned char) value. - * - * @see fromByte(), toByte() - */ - Byte, - - /** - * Type when encapsulating a signed 16-bit integer value. - * - * @see fromInt16(), toInt16() - */ - Int16, - - /** - * Type when encapsulating an unsigned 16-bit integer value. - * - * @see fromUInt16(), toUInt16() - */ - UInt16, - - /** - * Type when encapsulating a signed 32-bit integer value. - * - * @see fromInt32(), toInt32() - */ - Int32, - - /** - * Type when encapsulating an unsigned 32-bit integer value. - * - * @see fromUInt32(), toUInt32() - */ - UInt32, - - /** - * Type when encapsulating a signed 64-bit integer value. - * - * @see fromInt64(), toInt64() - */ - Int64, - - /** - * Type when encapsulating an unsigned 64-bit integer value. - * - * @see fromUInt64(), toUInt64() - */ - UInt64, - - /** - * Type when encapsulating a double value. - * - * @see fromDouble(), toDouble() - */ - Double, - - /** - * Type when encapsulating a string value. - * - * All strings are converted to UTF-8 during transmission - * - * @see fromString(), toString() - */ - String, - - /** - * Type when encapsulating a D-Bus object path. - * - * D-Bus defines a special string variation for transporting the - * paths used to address objects within D-Bus services, see - * @ref dbusconventions-objectpath for formatting details. - * - * @note from the point of view of this bindings an object path is - * pretty much a normal string with externally checked restrictions. - * However, method calls or return values can require a signature - * to include an object path and any remote peer might then reject - * the normal string signature. - * - * @see fromObjectPath(), toObjectPath() - */ - ObjectPath, - - /** - * Type when encapsulating a D-Bus unix file handle. - * - * @see fromUnixFd(), toUnixFd() - */ - UnixFd, - - /** - * Type when encapsulating a list of values. - * - * The D-Bus type this maps to is called @c array but since the TQt - * container class used to implement this type is TQValueList (or rather - * TQT_DBusDataList), the TQT_DBusData type is called @c List instead. - * - * A list can contain any of the supported types as elements, even - * container types. - * However it can only contain elements with the same type per list - * object. - * - * @see fromList(), toList() - */ - List, - - /** - * Type when encapsulating a struct of values. - * - * A struct is basically a list of struct member variables, each - * member can be any of the supported types, even containers types. - * - * The C++/TQt value type used in the converter methods is a TQValueList - * with type TQT_DBusData. - * For example a TQRect could be mapped like this: - * @code - * TQRect rect(0, 0, 640, 480); - * TQValueList memberList; - * - * memberList << TQT_DBusData::fromInt32(rect.x()); - * memberList << TQT_DBusData::fromInt32(rect.y()); - * memberList << TQT_DBusData::fromInt32(rect.width()); - * memberList << TQT_DBusData::fromInt32(rect.height()); - * - * TQT_DBusData data = TQT_DBusData:fromStruct(memberList); - * @endcode - * - * And reconstructed like this: - * @code - * memberList = data.toStruct(); - * - * int x = memberList[0].toInt32(); - * int y = memberList[1].toInt32(); - * int w = memberList[2].toInt32(); - * int h = memberList[3].toInt32(); - * - * rect = TQRect(x, y, w, h); - * @endcode - * - * @note Empty structs, i.e. an empty member list, are not allowed - * - * @see fromStruct(), toStruct() - * @see TQT_DBusDataConverter - */ - Struct, - - /** - * Type when encapsulating a special variable container value. - * - * See TQT_DBusVariant for details on variant usage. - * - * @see fromVariant(), toVariant() - */ - Variant, - - /** - * Type when encapsulating a map of keys to values. - * - * The D-Bus type this maps to is called @c dict but since the TQt - * container class used to implement this type is TQMap (or rather - * TQT_DBusDataMap), the TQT_DBusData type is called @c Map instead. - * - * A map can contain any of the supported types as values, even - * container types, but only the following basic types as keys: - * - #Byte - * - #Int16 - * - #UInt16 - * - #Int32 - * - #UInt32 - * - #Int64 - * - #UInt64 - * - #String - * - #ObjectPath - * - #UnixFd - * - * All values need to be of the same type. - * - * @see fromByteKeyMap(), toByteKeyMap() - * @see fromInt16KeyMap(), toInt16KeyMap() - * @see fromUInt16KeyMap(), toUInt16KeyMap() - * @see fromInt32KeyMap(), toInt32KeyMap() - * @see fromUInt32KeyMap(), toUInt32KeyMap() - * @see fromInt64KeyMap(), toInt64KeyMap() - * @see fromUInt64KeyMap(), toUInt64KeyMap() - * @see fromStringKeyMap(), toStringKeyMap() - * @see fromObjectPathKeyMap(), toObjectPathKeyMap() - * @see fromUnixFdKeyMap(), toUnixFdKeyMap() - */ - Map - }; - - /** - * @brief Creates an empty, #Invalid data object - */ - TQT_DBusData(); - - /** - * @brief Copies a given @p other data object - * - * Since TQT_DBusData is implicitly shared, both objects will have the - * same content and the last object to reference it will delete it. - * - * @param other the object to copy - */ - TQT_DBusData(const TQT_DBusData& other); - - /** - * @brief Destroys the data object - * - * If this is the last instance to a shared content, it will delete it - * as well. - */ - ~TQT_DBusData(); - - /** - * @brief Copies a given @p other data object - * - * Since TQT_DBusData is implicitly shared, both objects will have the - * same content and the last object to reference it will delete it. - * - * @param other the object to copy - * - * @return a reference to this instance - */ - TQT_DBusData& operator=(const TQT_DBusData& other); - - /** - * @brief Checks if the given @p other data object is equal to this instance - * - * Two TQT_DBusData object are considered equal if they reference the same - * shared content or have the same type and the content's equality operator - * says the contents are equal. - * - * @param other the object to compare with - * - * @return @c true if the two data objects are equal, otherwise @c false - */ - bool operator==(const TQT_DBusData& other) const; - - /** - * @brief Checks if the given @p other data object is different from this instance - * - * @param other the object to compare with - * - * @return @c false if the two data objects are not equal, otherwise @c false - * - * @see operator==() - */ - bool operator!=(const TQT_DBusData& other) const; - - /** - * @brief Checks whether the data object contains a valid content - * - * This is equal to checking type() for not being #Invalid - * - * @return @c true if the data object is valid, otherwise @c false - */ - inline bool isValid() const { return type() != TQT_DBusData::Invalid; } - - /** - * @brief Returns the #Type of the data object - * - * @return one of the values of the #Type enum - * - * @see keyType() - * @see typeName() - */ - Type type() const; - - /** - * @brief Returns the #Type of the key type for maps - * - * If the type of the data object is #Map, this method returns the type - * of the map's key, #String for a TQT_DBusDataMap - * - * If the type of the data object is not #Map, it will return #Invalid - * - * @return one of the values of the #Type enum, #Invalid if the object is - * not holding a #Map - * - * @see type() - * @see typeName() - */ - Type keyType() const; - - /** - * @brief Returns the string representation of the object's #Type - * - * @return an ASCII C-string for the object's type - * - * @see type() - * @see typeName(Type) - */ - inline const char* typeName() const { return typeName(type()); } - - /** - * @brief Returns the string representation for the given @p type - * - * @param type the #Type to get the string representation for - * - * @return an ASCII C-string for the given @p type - * - * @see type() - * @see typeName() - */ - static const char* typeName(Type type); - - /** - * @brief Creates a data object for the given boolean @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #Bool containing the @p value - * - * @see toBool() - */ - static TQT_DBusData fromBool(bool value); - - /** - * @brief Tries to get the encapsulated boolean value - * - * If the data object is not of type #Bool this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Bool) - * - * @return the encapsulated boolean value or @c false if it fails - * - * @see fromBool() - */ - bool toBool(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given byte (unsigned char) @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #Byte containing the @p value - * - * @see toByte() - */ - static TQT_DBusData fromByte(TQ_UINT8 value); - - /** - * @brief Tries to get the encapsulated byte (unsigned char) value - * - * If the data object is not of type #Byte this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Byte) - * - * @return the encapsulated byte (unsigned char) value or @c 0 if it fails - * - * @see fromByte() - */ - TQ_UINT8 toByte(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given signed 16-bit integer @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #Int16 containing the @p value - * - * @see toInt16() - */ - static TQT_DBusData fromInt16(TQ_INT16 value); - - /** - * @brief Tries to get the encapsulated signed 16-bit integer value - * - * If the data object is not of type #Int16 this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Int16) - * - * @return the encapsulated signed 16-bit integer value or @c 0 if it fails - * - * @see fromInt16() - */ - TQ_INT16 toInt16(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given unsigned 16-bit integer @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #UInt16 containing the @p value - * - * @see toUInt16() - */ - static TQT_DBusData fromUInt16(TQ_UINT16 value); - - /** - * @brief Tries to get the encapsulated unsigned 16-bit integer value - * - * If the data object is not of type #UInt16 this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #UInt16) - * - * @return the encapsulated unsigned 16-bit integer value or @c 0 if it fails - * - * @see fromUInt16() - */ - TQ_UINT16 toUInt16(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given signed 32-bit integer @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #Int32 containing the @p value - * - * @see toInt32() - */ - static TQT_DBusData fromInt32(TQ_INT32 value); - - /** - * @brief Tries to get the encapsulated signed 32-bit integer value - * - * If the data object is not of type #Int32 this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Int32) - * - * @return the encapsulated signed 32-bit integer value or @c 0 if it fails - * - * @see fromInt32() - */ - TQ_INT32 toInt32(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given unsigned 32-bit integer @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #UInt32 containing the @p value - * - * @see toUInt32() - */ - static TQT_DBusData fromUInt32(TQ_UINT32 value); - - /** - * @brief Tries to get the encapsulated unsigned 32-bit integer value - * - * If the data object is not of type #UInt32 this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #UInt32) - * - * @return the encapsulated unsigned 32-bit integer value or @c 0 if it fails - * - * @see fromUInt32() - */ - TQ_UINT32 toUInt32(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given signed 64-bit integer @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #Int64 containing the @p value - * - * @see toInt64() - */ - static TQT_DBusData fromInt64(TQ_INT64 value); - - /** - * @brief Tries to get the encapsulated signed 64-bit integer value - * - * If the data object is not of type #Int64 this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Int64) - * - * @return the encapsulated signed 64-bit integer value or @c 0 if it fails - * - * @see fromInt64() - */ - TQ_INT64 toInt64(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given unsigned 64-bit integer @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #UInt64 containing the @p value - * - * @see toUInt64() - */ - static TQT_DBusData fromUInt64(TQ_UINT64 value); - - /** - * @brief Tries to get the encapsulated unsigned 64-bit integer value - * - * If the data object is not of type #UInt64 this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #UInt64) - * - * @return the encapsulated unsigned 64-bit integer value or @c 0 if it fails - * - * @see fromUInt64() - */ - TQ_UINT64 toUInt64(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given double @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #Double containing the @p value - * - * @see toDouble() - */ - static TQT_DBusData fromDouble(double value); - - /** - * @brief Tries to get the encapsulated double value - * - * If the data object is not of type #Double this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Double) - * - * @return the encapsulated double value or @c 0.0 if it fails - * - * @see fromDouble() - */ - double toDouble(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given string @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #String containing the @p value - * - * @see toString() - */ - static TQT_DBusData fromString(const TQString& value); - - /** - * @brief Tries to get the encapsulated string value - * - * If the data object is not of type #String this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #String) - * - * @return the encapsulated string value or @c TQString() if it fails - * - * @see fromString() - */ - TQString toString(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given object path @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #ObjectPath containing the @p value - * - * @see toObjectPath() - */ - static TQT_DBusData fromObjectPath(const TQT_DBusObjectPath& value); - - /** - * @brief Tries to get the encapsulated object path value - * - * If the data object is not of type #ObjectPath this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #ObjectPath) - * - * @return the encapsulated object path value or an empty and invalid object - * if it fails - * - * @see fromObjectPath() - */ - TQT_DBusObjectPath toObjectPath(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given unix file handle @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #UnixFd containing the @p value - * - * @see toUnixFd() - */ - static TQT_DBusData fromUnixFd(const TQT_DBusUnixFd& value); - - /** - * @brief Tries to get the encapsulated unix file handle value - * - * If the data object is not of type #UnixFd this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #UnixFd) - * - * @return the encapsulated object path value or an empty and invalid object - * if it fails - * - * @see fromUnixFd() - */ - TQT_DBusUnixFd toUnixFd(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p list - * - * \note The list is allowed to be empty but is required to have a valid type - * - * Unless the list the is empty, the convenience method fromTQValueList() will - * usually be easier to use since it does not require to create a - * TQT_DBusDataList first. For empty lists this method has to be used to - * make sure there is sufficient type information on the list's elements - * available for the binding's marshalling code. - * - * @param list the list to encapsulate - * - * @return a data object of type #List containing the @p list or - * an #Invalid object if the list's type is #Invalid - * - * @see toList() - */ - static TQT_DBusData fromList(const TQT_DBusDataList& list); - - /** - * @brief Tries to get the encapsulated list - * - * If the data object is not of type #List this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #List) - * - * @return the encapsulated list or an empty and #Invalid list if it fails - * - * @see fromList() - */ - TQT_DBusDataList toList(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p list - * - * @warning All elements of the list have to be of the same #Type - * - * Convenience overload for fromList(), usually more straight forward to use - * because it doesn't require to create a TQT_DBusDataList object first, - * however it can only handle lists which contain elements, for empty lists - * fromList() is the only option. - * - * @param list the list to encapsulate - * - * @return a data object of type #List containing the @p list or - * an #Invalid object if the list is empty or if elements have - * different types. - * - * @see toTQValueList() - */ - static TQT_DBusData fromTQValueList(const TQValueList& list); - - /** - * @brief Tries to get the encapsulated list - * - * Convenience overload for toList(). - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #List) - * - * @return the encapsulated list or an empty and #Invalid list if it fails - * - * @see fromTQValueList() - */ - TQValueList toTQValueList(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given struct's @p memberList - * - * See the documentation of #Struct for an example. - * - * @param memberList the list of already encapsulated struct members - * - * @return a data object of type #Struct containing the @p memberList - * - * @see toStruct() - */ - static TQT_DBusData fromStruct(const TQValueList& memberList); - - /** - * @brief Tries to get the encapsulated struct memberList - * - * If the data object is not of type #Struct this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * See the documentation of #Struct for an example. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Struct) - * - * @return the encapsulated memberList or an empty list if it fails - * - * @see fromStruct() - */ - TQValueList toStruct(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given variant @p value - * - * @param value the value to encapsulate - * - * @return a data object of type #Variant containing the @p value - * - * @see toVariant() - */ - static TQT_DBusData fromVariant(const TQT_DBusVariant& value); - - /** - * @brief Tries to get the encapsulated variant value - * - * If the data object is not of type #Variant this will fail, i.e. - * the parameter @p ok will be set to @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Variant) - * - * @return the encapsulated variant value or an empty variant if it fails - * - * @see fromVariant() - */ - TQT_DBusVariant toVariant(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #Byte. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toByteKeyMap() - */ - static TQT_DBusData fromByteKeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not #Byte - * this will fail, i.e. the parameter @p ok will be set to @c false if - * present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #Byte) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromByteKeyMap() - */ - TQT_DBusDataMap toByteKeyMap(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #Int16. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toInt16KeyMap() - */ - static TQT_DBusData fromInt16KeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not #Int16 - * this will fail, i.e. the parameter @p ok will be set to @c false if - * present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #Int16) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromInt16KeyMap() - */ - TQT_DBusDataMap toInt16KeyMap(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #UInt16. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toUInt16KeyMap() - */ - static TQT_DBusData fromUInt16KeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not #UInt16 - * this will fail, i.e. the parameter @p ok will be set to @c false if - * present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #UInt16) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromUInt16KeyMap() - */ - TQT_DBusDataMap toUInt16KeyMap(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #Int32. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toInt32KeyMap() - */ - static TQT_DBusData fromInt32KeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not #Int32 - * this will fail, i.e. the parameter @p ok will be set to @c false if - * present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #Int32) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromInt32KeyMap() - */ - TQT_DBusDataMap toInt32KeyMap(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #UInt32. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toUInt32KeyMap() - */ - static TQT_DBusData fromUInt32KeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not #UInt32 - * this will fail, i.e. the parameter @p ok will be set to @c false if - * present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #UInt32) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromUInt32KeyMap() - */ - TQT_DBusDataMap toUInt32KeyMap(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #Int64. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toInt64KeyMap() - */ - static TQT_DBusData fromInt64KeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not #Int64 - * this will fail, i.e. the parameter @p ok will be set to @c false if - * present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #Int64) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromInt64KeyMap() - */ - TQT_DBusDataMap toInt64KeyMap(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #UInt64. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toUInt64KeyMap() - */ - static TQT_DBusData fromUInt64KeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not #UInt64 - * this will fail, i.e. the parameter @p ok will be set to @c false if - * present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #UInt64) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromUInt64KeyMap() - */ - TQT_DBusDataMap toUInt64KeyMap(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #String. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toStringKeyMap() - */ - static TQT_DBusData fromStringKeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not #String - * this will fail, i.e. the parameter @p ok will be set to @c false if - * present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #String) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromStringKeyMap() - */ - TQT_DBusDataMap toStringKeyMap(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #ObjectPath. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toObjectPathKeyMap() - */ - static TQT_DBusData fromObjectPathKeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not - * #ObjectPath this will fail, i.e. the parameter @p ok will be set to - * @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #ObjectPath) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromObjectPathKeyMap() - */ - TQT_DBusDataMap toObjectPathKeyMap(bool* ok = 0) const; - - /** - * @brief Creates a data object for the given @p map - * - * \note The map is allowed to be empty but is required to have a valid - * value type - * - * The resulting data object will have the keyType() set to #UnixFd. - * - * @param map the map to encapsulate - * - * @return a data object of type #Map containing the @p map or - * an #Invalid object if the map's value type is #Invalid - * - * @see toUnixFdhKeyMap() - */ - static TQT_DBusData fromUnixFdKeyMap(const TQT_DBusDataMap& map); - - /** - * @brief Tries to get the encapsulated map - * - * If the data object is not of type #Map or if its value type is not - * #UnixFd this will fail, i.e. the parameter @p ok will be set to - * @c false if present. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type #Map or - * value type not #UnixFd) - * - * @return the encapsulated map or an empty and #Invalid map if it fails - * - * @see fromUnixFdKeyMap() - */ - TQT_DBusDataMap toUnixFdKeyMap(bool* ok = 0) const; - - /** - * @brief Creates the data objects D-Bus signature - * - * Recursivly builds the D-Bus signature of the data object if it holds a - * container type, i.e. if the object is of type #List, #Map or #Struct - * - * This can be used to create a signature for TQT_DBusVariant when creating one - * for sending over D-Bus. - * - * @return a string containing the content's signature, or a null string - * if the data object is #Invalid - */ - TQCString buildDBusSignature() const; - -private: - class Private; - Private* d; -}; - -#endif diff --git a/tqdbusdataconverter.cpp b/tqdbusdataconverter.cpp deleted file mode 100644 index 50575b8..0000000 --- a/tqdbusdataconverter.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* qdbusdataconverter.cpp TQT_DBusDataConverter template - * - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include "tqdbusdataconverter.h" -#include "tqdbusdata.h" - -#include -#include -#include -#include - -template <> -TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertFromTQT_DBusData(const TQT_DBusData& dbusData, TQRect& typeData) -{ - if (dbusData.type() != TQT_DBusData::Struct) return InvalidSignature; - - TQValueList members = dbusData.toStruct(); - if (members.count() != 4) return InvalidSignature; - - TQ_INT32 values[4]; - - TQValueList::const_iterator it = members.begin(); - TQValueList::const_iterator endIt = members.end(); - for (uint i = 0; it != endIt; ++it, ++i) - { - bool ok = false; - values[i] = (*it).toInt32(&ok); - if (!ok) return InvalidSignature; - } - - typeData = TQRect(values[0], values[1], values[2], values[3]); - - return Success; -} - -template <> -TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertToTQT_DBusData(const TQRect& typeData, TQT_DBusData& dbusData) -{ - TQValueList members; - - members << TQT_DBusData::fromInt32(typeData.x()); - members << TQT_DBusData::fromInt32(typeData.y()); - members << TQT_DBusData::fromInt32(typeData.width()); - members << TQT_DBusData::fromInt32(typeData.height()); - - dbusData = TQT_DBusData::fromStruct(members); - - return Success; -} - -template <> -TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertFromTQT_DBusData(const TQT_DBusData& dbusData, TQPoint& typeData) -{ - if (dbusData.type() != TQT_DBusData::Struct) return InvalidSignature; - - TQValueList members = dbusData.toStruct(); - if (members.count() != 2) return InvalidSignature; - - TQ_INT32 values[2]; - - TQValueList::const_iterator it = members.begin(); - TQValueList::const_iterator endIt = members.end(); - for (uint i = 0; it != endIt; ++it, ++i) - { - bool ok = false; - values[i] = (*it).toInt32(&ok); - if (!ok) return InvalidSignature; - } - - typeData = TQPoint(values[0], values[1]); - - return Success; -} - -template <> -TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertToTQT_DBusData(const TQPoint& typeData, TQT_DBusData& dbusData) -{ - TQValueList members; - - members << TQT_DBusData::fromInt32(typeData.x()); - members << TQT_DBusData::fromInt32(typeData.y()); - - dbusData = TQT_DBusData::fromStruct(members); - - return Success; -} - -template <> -TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertFromTQT_DBusData(const TQT_DBusData& dbusData, TQSize& typeData) -{ - if (dbusData.type() != TQT_DBusData::Struct) return InvalidSignature; - - TQValueList members = dbusData.toStruct(); - if (members.count() != 2) return InvalidSignature; - - TQ_INT32 values[2]; - - TQValueList::const_iterator it = members.begin(); - TQValueList::const_iterator endIt = members.end(); - for (uint i = 0; it != endIt; ++it, ++i) - { - bool ok = false; - values[i] = (*it).toInt32(&ok); - if (!ok) return InvalidSignature; - } - - typeData = TQSize(values[0], values[1]); - - return Success; -} - -template <> -TQT_DBusDataConverter::Result TQT_DBusDataConverter::convertToTQT_DBusData(const TQSize& typeData, TQT_DBusData& dbusData) -{ - TQValueList members; - - members << TQT_DBusData::fromInt32(typeData.width()); - members << TQT_DBusData::fromInt32(typeData.height()); - - dbusData = TQT_DBusData::fromStruct(members); - - return Success; -} diff --git a/tqdbusdataconverter.h b/tqdbusdataconverter.h deleted file mode 100644 index 2ca21a0..0000000 --- a/tqdbusdataconverter.h +++ /dev/null @@ -1,207 +0,0 @@ -/* qdbusdataconverter.h TQT_DBusDataConverter template - * - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSDATACONVERTER_H -#define TQDBUSDATACONVERTER_H - -#include "tqdbusmacros.h" - -class TQT_DBusData; - -/** - * @brief Template based converter for getting complex data into or from TQT_DBusData objects - * - * Any data to transport over D-Bus, i.e. method/signal paramaters or properties, need - * to be converted into a TQT_DBusData instance. - * - * For complex types, e.g. structures or nested containers, this can be quite some code, - * and will likely be needed for more than one call. - * Therefore it is more convenient to implement the conversions once per complex type. - * - * Example: sending and recieving a TQRect over D-Bus. - * In D-Bus terminology a TQRect is a struct of four 32-bit signed integers. The code to do - * this manually looks like this: - * @code - * TQRect rect(0, 0, 100, 100); - * - * TQValueList structMembers; - * structMembers << TQT_DBusData::fromInt32(rect.x()); - * structMembers << TQT_DBusData::fromInt32(rect.y()); - * structMembers << TQT_DBusData::fromInt32(rect.wdth()); - * structMembers << TQT_DBusData::fromInt32(rect.height()); - * - * TQT_DBusData rectStruct = TQT_DBusData::fromStruct(structMembers); - * @endcode - * and reverse (without the error checking) - * @code - * TQT_DBusData dbusData; // assume we got this from a D-Bus call - * - * TQValueList structMembers = dbudData.toStruct(); - * - * int x = structMembers[0].toInt32(); - * int y = structMembers[1].toInt32(); - * int w = structMembers[2].toInt32(); - * int h = structMembers[3].toInt32(); - * - * TQRect rect(x, y, w, h); - * @endcode - * - * Rather than implementing it in the method which performs the D-Bus call, basically the same - * code can be used as a spezialisation of the TQT_DBusDataConverter methods and then used like this: - * @code - * TQRect rect(0, 0, 100, 100); - * TQT_DBusData rectStruct; - * - * TQT_DBusDataConverter::convertToTQT_DBusData(rect, rectStruct); - * @endcode - * and - * @code - * TQRect rect; - * TQT_DBusData dbusData; // assume we got this from a D-Bus call - * - * TQT_DBusDataConverter::convertFromTQT_DBusData(dbusData, rect); - * @endcode - * - * @note The bindings library contains the spezialisations for TQRect, TQPoint and TQSize. - */ -class TQDBUS_EXPORT TQT_DBusDataConverter -{ -public: - /** - * @brief Conversion result values - */ - enum Result - { - /** - * Conversion successfull - */ - Success, - - /** - * Conversion failed because the passed TQT_DBusData instance does not contain data - * of the needed signature, e.g. too few to too many members for a struct or wrong types. - * - * @see TQT_DBusError::stdInvalidSignature() - */ - InvalidSignature, - - /** - * Conversion failed because the passed TQT_DBusData contained values which are not allowed, - * e.g. out of range for a numerical type used a an enum or flags. - * - * @see TQT_DBusError::stdInvalidArgs() - */ - InvalidArgument - }; - - /** - * @brief Conversion from a filled TQT_DBusData instance to a native type - * - * For example the implementation for TQPoint looks like this: - * @code - * template <> - * TQT_DBusDataConverter::Result - * TQT_DBusDataConverter::convertFromTQT_DBusData(const TQT_DBusData& dbusData, TQPoint& typeData) - * { - * if (dbusData.type() != TQT_DBusData::Struct) return InvalidSignature; - * - * TQValueList members = dbusData.toStruct(); - * if (members.count() != 2) return InvalidSignature; - * - * bool ok = false; - * int x = members[0].toInt32(&ok); - * if (!ok) return InvalidSignature; - * - * int y = members[1].toInt32(&ok); - * if (!ok) return InvalidSignature; - * - * typeData = TQPoint(x, y); - * - * return Success; - * } - * @endcode - * - * And then can be used like this: - * @code - * TQT_DBusMessage reply; // assume we got this as a D-Bus call reply - * TQPoint point; - * - * if (TQT_DBusDataConverter::convertFromTQT_DBusData(reply[0], point) != TQT_DBusDataConverter::Success) - * { - * // error handling - * } - * @endcode - * - * @param dbusData the binding's data instance to get the content from - * @param typeData the native type instance to put the content into - * - * @return the conversion result value - */ - template - static Result convertFromTQT_DBusData(const TQT_DBusData& dbusData, T& typeData); - - /** - * @brief Conversion from a native type to a TQT_DBusData instance - * - * For example the implementation for TQPoint looks like this: - * @code - * template <> - * TQT_DBusDataConversion::Result - * TQT_DBusDataConversion::convertToTQT_DBusData(const TQPoint& typeData, TQT_DBusData& dbusData) - * { - * TQValueList members; - * members << TQT_DBusData::fromInt32(typeData.x()); - * members << TQT_DBusData::fromInt32(typeData.y()); - * - * dbusData = TQT_DBusData::fromStruct(members); - * - * return Success; - * } - * @endcode - * - * And then can be used like this: - * @code - * TQPoint point(-10, 100); - * TQT_DBusMessage methodCall; // assume created by TQBusMessage::methodCall() - * - * TQT_DBusData dbusData; - * if (TQT_DBusDataConverter::convertToTQT_DBusData(point, dbusData) != TQT_DBusDataConverter::Success) - * { - * // error handling - * } - * else - * { - * methodCall << dbusData; - * } - * @endcode - * - * @param typeData the native type instance to get the content from - * @param dbusData the binding's data instance to put the content into - * - * @return the conversion result value - */ - template - static Result convertToTQT_DBusData(const T& typeData, TQT_DBusData& dbusData); -}; - -#endif diff --git a/tqdbusdatalist.cpp b/tqdbusdatalist.cpp deleted file mode 100644 index 23f60a5..0000000 --- a/tqdbusdatalist.cpp +++ /dev/null @@ -1,786 +0,0 @@ -/* qdbusdatalist.cpp list of DBUS data transport type - * - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include "tqdbusdatalist.h" -#include "tqdbusobjectpath.h" -#include "tqdbusunixfd.h" -#include "tqdbusvariant.h" - -#include - -class TQT_DBusDataList::Private -{ -public: - Private() : type(TQT_DBusData::Invalid) {} - -public: - TQT_DBusData::Type type; - TQT_DBusData containerItem; - TQValueList list; -}; - -TQT_DBusDataList::TQT_DBusDataList() : d(new Private()) -{ -} - -TQT_DBusDataList::TQT_DBusDataList(TQT_DBusData::Type simpleItemType) : d(new Private()) -{ - d->type = simpleItemType; -} - -TQT_DBusDataList::TQT_DBusDataList(const TQT_DBusData& containerItemType) : d(new Private()) -{ - d->type = containerItemType.type(); - - switch(d->type) - { - case TQT_DBusData::List: // fall through - case TQT_DBusData::Struct: // fall through - case TQT_DBusData::Map: - d->containerItem = containerItemType; - break; - - default: // not a container - break; - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQT_DBusDataList& other) : d(new Private()) -{ - d->type = other.d->type; - d->list = other.d->list; - d->containerItem = other.d->containerItem; -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - - d->type = (*it).type(); - - TQCString elementSignature; - if (hasContainerItemType()) - { - d->containerItem = other[0]; // would be nice to get an empty one - elementSignature = d->containerItem.buildDBusSignature(); - } - - for (++it; it != endIt; ++it) - { - if (d->type != (*it).type()) - { - d->type = TQT_DBusData::Invalid; - d->containerItem = TQT_DBusData(); - - return; - } - else if (hasContainerItemType()) - { - if ((*it).buildDBusSignature() != elementSignature) - { - d->type = TQT_DBusData::Invalid; - d->containerItem = TQT_DBusData(); - - return; - } - } - } - - d->list = other; -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - d->type = TQT_DBusData::Bool; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromBool(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - d->type = TQT_DBusData::Byte; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromByte(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - d->type = TQT_DBusData::Int16; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromInt16(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - d->type = TQT_DBusData::UInt16; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromUInt16(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - d->type = TQT_DBusData::Int32; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromInt32(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - d->type = TQT_DBusData::UInt32; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromUInt32(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - d->type = TQT_DBusData::Int64; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromInt64(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - d->type = TQT_DBusData::UInt64; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromUInt64(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) : d(new Private()) -{ - d->type = TQT_DBusData::Double; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromDouble(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) - : d(new Private()) -{ - d->type = TQT_DBusData::Variant; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromVariant(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQStringList& other) : d(new Private()) -{ - d->type = TQT_DBusData::String; - - if (other.isEmpty()) return; - - TQStringList::const_iterator it = other.begin(); - TQStringList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromString(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) - : d(new Private()) -{ - d->type = TQT_DBusData::ObjectPath; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromObjectPath(*it); - } -} - -TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) - : d(new Private()) -{ - d->type = TQT_DBusData::UnixFd; - - if (other.isEmpty()) return; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromUnixFd(*it); - } -} - -TQT_DBusDataList::~TQT_DBusDataList() -{ - delete d; -} - -TQT_DBusDataList& TQT_DBusDataList::operator=(const TQT_DBusDataList& other) -{ - if (&other == this) return *this; - - d->type = other.d->type; - d->list = other.d->list; - d->containerItem = other.d->containerItem; - - return *this; -} - -TQT_DBusDataList& TQT_DBusDataList::operator=(const TQValueList& other) -{ - d->list.clear(); - d->type = TQT_DBusData::Invalid; - d->containerItem = TQT_DBusData(); - - if (other.isEmpty()) return *this; - - TQValueList::const_iterator it = other.begin(); - TQValueList::const_iterator endIt = other.end(); - - d->type = (*it).type(); - - TQCString elementSignature; - if (hasContainerItemType()) - { - d->containerItem = other[0]; // would be nice to get an empty one - - elementSignature = d->containerItem.buildDBusSignature(); - } - - for (++it; it != endIt; ++it) - { - if (d->type != (*it).type()) - { - d->type = TQT_DBusData::Invalid; - d->containerItem = TQT_DBusData(); - - return *this; - } - else if (hasContainerItemType()) - { - if ((*it).buildDBusSignature() != elementSignature) - { - d->type = TQT_DBusData::Invalid; - d->containerItem = TQT_DBusData(); - - return *this; - } - } - } - - d->list = other; - - return *this; -} - -TQT_DBusDataList& TQT_DBusDataList::operator=(const TQStringList& other) -{ - d->list.clear(); - d->type = TQT_DBusData::String; - d->containerItem = TQT_DBusData(); - - TQStringList::const_iterator it = other.begin(); - TQStringList::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - d->list << TQT_DBusData::fromString(*it); - } - - return *this; -} - -TQT_DBusData::Type TQT_DBusDataList::type() const -{ - return d->type; -} - -bool TQT_DBusDataList::hasContainerItemType() const -{ - return d->type == TQT_DBusData::List || d->type == TQT_DBusData::Map - || d->type == TQT_DBusData::Struct; -} - -TQT_DBusData TQT_DBusDataList::containerItemType() const -{ - return d->containerItem; -} - -bool TQT_DBusDataList::isEmpty() const -{ - return d->list.isEmpty(); -} - -uint TQT_DBusDataList::count() const -{ - return d->list.count(); -} - -bool TQT_DBusDataList::operator==(const TQT_DBusDataList& other) const -{ - if (&other == this) return true; - if (d == other.d) return true; - - bool containerEqual = true; - if (hasContainerItemType()) - { - if (other.hasContainerItemType()) - { - containerEqual = d->containerItem.buildDBusSignature() == - other.d->containerItem.buildDBusSignature(); - } - else - containerEqual = false; - } - else if (other.hasContainerItemType()) - containerEqual = false; - - return d->type == other.d->type && containerEqual && d->list == other.d->list; -} - -bool TQT_DBusDataList::operator!=(const TQT_DBusDataList& other) const -{ - if (&other == this) return false; - if (d == other.d) return false; - - bool containerEqual = true; - if (hasContainerItemType()) - { - if (other.hasContainerItemType()) - { - containerEqual = d->containerItem.buildDBusSignature() == - other.d->containerItem.buildDBusSignature(); - } - else - containerEqual = false; - } - else if (other.hasContainerItemType()) - containerEqual = false; - - return d->type != other.d->type || !containerEqual || d->list != other.d->list; -} - -void TQT_DBusDataList::clear() -{ - d->list.clear(); -} - -TQT_DBusDataList& TQT_DBusDataList::operator<<(const TQT_DBusData& data) -{ - if (data.type() == TQT_DBusData::Invalid) return *this; - - if (d->type == TQT_DBusData::Invalid) - { - d->type = data.type(); - - // check if we are now have container items - if (hasContainerItemType()) d->containerItem = data; - - d->list << data; - } - else if (d->type != data.type()) - { - tqWarning("TQT_DBusDataList: trying to add data of type %s to list of type %s", - data.typeName(), TQT_DBusData::typeName(d->type)); - } - else if (hasContainerItemType()) - { - TQCString ourSignature = d->containerItem.buildDBusSignature(); - TQCString dataSignature = data.buildDBusSignature(); - - if (ourSignature != dataSignature) - { - tqWarning("TQT_DBusDataList: trying to add data with signature %s " - "to list with item signature %s", - dataSignature.data(), ourSignature.data()); - } - else - d->list << data; - } - else - d->list << data; - - return *this; -} - -TQValueList TQT_DBusDataList::toTQValueList() const -{ - return d->list; -} - -TQStringList TQT_DBusDataList::toTQStringList(bool* ok) const -{ - if (d->type != TQT_DBusData::String) - { - if (ok != 0) *ok = false; - return TQStringList(); - } - - TQStringList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toString(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toBoolList(bool* ok) const -{ - if (d->type != TQT_DBusData::Bool) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toBool(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toByteList(bool* ok) const -{ - if (d->type != TQT_DBusData::Byte) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toByte(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toInt16List(bool* ok) const -{ - if (d->type != TQT_DBusData::Int16) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toInt16(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toUInt16List(bool* ok) const -{ - if (d->type != TQT_DBusData::UInt16) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toUInt16(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toInt32List(bool* ok) const -{ - if (d->type != TQT_DBusData::Int32) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toInt32(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toUInt32List(bool* ok) const -{ - if (d->type != TQT_DBusData::UInt32) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toUInt32(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toInt64List(bool* ok) const -{ - if (d->type != TQT_DBusData::Int64) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toInt64(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toUInt64List(bool* ok) const -{ - if (d->type != TQT_DBusData::UInt64) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toUInt64(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toDoubleList(bool* ok) const -{ - if (d->type != TQT_DBusData::Double) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toDouble(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toStringList(bool* ok) const -{ - return toTQStringList(ok); -} - -TQValueList TQT_DBusDataList::toObjectPathList(bool* ok) const -{ - if (d->type != TQT_DBusData::ObjectPath) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toObjectPath(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toUnixFdList(bool* ok) const -{ - if (d->type != TQT_DBusData::UnixFd) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toUnixFd(); - } - - if (ok != 0) *ok = true; - - return result; -} - -TQValueList TQT_DBusDataList::toVariantList(bool* ok) const -{ - if (d->type != TQT_DBusData::Variant) - { - if (ok != 0) *ok = false; - return TQValueList(); - } - - TQValueList result; - - TQValueList::const_iterator it = d->list.begin(); - TQValueList::const_iterator endIt = d->list.end(); - for (; it != endIt; ++it) - { - result << (*it).toVariant(); - } - - if (ok != 0) *ok = true; - - return result; -} diff --git a/tqdbusdatalist.h b/tqdbusdatalist.h deleted file mode 100644 index bd0b467..0000000 --- a/tqdbusdatalist.h +++ /dev/null @@ -1,758 +0,0 @@ -/* qdbusdatalist.h list of DBUS data transport type - * - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSDATALIST_H -#define TQDBUSDATALIST_H - -#include "tqdbusdata.h" - -template class TQValueList; -class TQT_DBusObjectPath; -class TQT_DBusVariant; -class TQT_DBusUnixFd; -class TQString; -class TQStringList; - -/** - * @brief Class to transport lists of D-Bus data types - * - * \note while the D-Bus data type is actually called @c array this bindings - * use the term @c list since the behavior and characteristics of the - * implementation is more list like. - * - * There are basically two ways to create TQT_DBusDataList objects: - * - non-empty from content - * - empty by specifying the desired element type - * - * Example for creating a filled list from content - * @code - * TQValueList intList; - * list << 2 << 3 << 5 << 7; - * - * TQT_DBusDataList dbusList(intList); - * TQT_DBusData data = TQT_DBusData::fromList(dbusList); - * - * // or even shorter, using implicit conversion - * TQT_DBusData other = TQT_DBusData::fromList(intList); - * @endcode - * - * Example for creating an empty list - * @code - * // empty list for a simple type - * TQT_DBusDataList list(TQT_DBusData::Double); - * - * // empty list for a list of string lists - * TQT_DBusData elementType = TQT_DBusData::fromList(TQT_DBusDataList(TQT_DBusData::String)); - * TQT_DBusDataList outerList(elementType); - * @endcode - * - * @see TQT_DBusDataMap - */ -class TQDBUS_EXPORT TQT_DBusDataList -{ -public: - /** - * @brief Creates an empty and invalid list - * - * @see TQT_DBusData::Invalid - */ - TQT_DBusDataList(); - - /** - * @brief Creates an empty list with the given simple type for elements - * - * The given type has be one of the non-container types, i.e. any other than - * TQT_DBusData::Map, TQT_DBusData::List or TQT_DBusData::Struct - * - * For creating a list with elements which are containers themselves, use - * TQT_DBusDataList(const TQT_DBusData&); - * - * @param simpleItemType the type of the elements in the new list - */ - explicit TQT_DBusDataList(TQT_DBusData::Type simpleItemType); - - /** - * @brief Creates an empty list with the given container type for elements - * - * For creating a list with simple elements you can also use - * TQT_DBusDataList(TQT_DBusData::Type); - * - * @param containerItemType the type of the elements in the new list - * - * @see hasContainerItemType() - */ - explicit TQT_DBusDataList(const TQT_DBusData& containerItemType); - - /** - * @brief Creates a list from the given @p other list - * - * This behaves basically like copying a TQValueList through its copy - * constructor, i.e. no value are actually copied at this time. - * - * @param other the other list object to copy from - */ - TQT_DBusDataList(const TQT_DBusDataList& other); - - /** - * @brief Creates a list from the given TQValueList of TQT_DBusData objects - * - * If the @p other list is empty, this will behave like TQT_DBusDataList(), - * i.e. create an empty and invalid list object. - * - * Type information for the list object, i.e. element type and, if applicable, - * container item type, will be derived from the @p other list's elements. - * - * \warning if the elements of the @p other list do not all have the same - * type, the list object will also be empty and invalid - * - * @param other the TQValueList of TQT_DBusData objects to copy from - * - * @see toTQValueList() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of boolean values - * - * Type information for the list object will be set to TQT_DBusData::Bool - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Bool - * - * @param other the TQValueList of boolean values to copy from - * - * @see toBoolList() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of byte (unsigned char) values - * - * Type information for the list object will be set to TQT_DBusData::Byte - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Byte - * - * @param other the TQValueList of byte (unsigned char) values to copy from - * - * @see toByteList() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of signed 16-bit integer values - * - * Type information for the list object will be set to TQT_DBusData::Int16 - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Int16 - * - * @param other the TQValueList of signed 16-bit integer values to copy from - * - * @see toInt16List() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of unsigned 16-bit integer values - * - * Type information for the list object will be set to TQT_DBusData::UInt16 - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::UInt16 - * - * @param other the TQValueList of unsigned 16-bit integer values to copy from - * - * @see toUInt16List() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of signed 32-bit integer values - * - * Type information for the list object will be set to TQT_DBusData::Int32 - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Int32 - * - * @param other the TQValueList of signed 32-bit integer values to copy from - * - * @see toInt32List() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of unsigned 32-bit integer values - * - * Type information for the list object will be set to TQT_DBusData::UInt16 - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::UInt32 - * - * @param other the TQValueList of unsigned 32-bit integer values to copy from - * - * @see toUInt32List() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of signed 64-bit integer values - * - * Type information for the list object will be set to TQT_DBusData::Int64 - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Int64 - * - * @param other the TQValueList of signed 64-bit integer values to copy from - * - * @see toInt64List() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of unsigned 64-bit integer values - * - * Type information for the list object will be set to TQT_DBusData::UInt64 - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::UInt64 - * - * @param other the TQValueList of unsigned 64-bit integer values to copy from - * - * @see toUInt64List() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of double values - * - * Type information for the list object will be set to TQT_DBusData::Double - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Double - * - * @param other the TQValueList of double values to copy from - * - * @see toDoubleList() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of TQT_DBusVariant values - * - * Type information for the list object will be set to TQT_DBusData::Variant - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::Variant - * - * @param other the TQValueList of variant values to copy from - * - * @see toVariantList() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQStringList's values - * - * Type information for the list object will be set to TQT_DBusData::String - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::String - * - * @param other the TQStringList to copy from - * - * @see toTQStringList() - */ - TQT_DBusDataList(const TQStringList& other); - - /** - * @brief Creates a list from the given TQValueList of object path values - * - * Type information for the list object will be set to TQT_DBusData::ObjectPath - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::ObjectPath - * - * @param other the TQValueList of object path values to copy from - * - * @see toObjectPathList() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Creates a list from the given TQValueList of unix file handle values - * - * Type information for the list object will be set to TQT_DBusData::UnixFd - * also when the @p other list is empty, i.e. this allows to create an - * empty but valid list object, comparable to using - * TQT_DBusDataList(TQT_DBusData::Type) with TQT_DBusData::UnixFd - * - * @param other the TQValueList of unix file handle values to copy from - * - * @see toUnixFdList() - */ - TQT_DBusDataList(const TQValueList& other); - - /** - * @brief Destroys the list object - */ - ~TQT_DBusDataList(); - - /** - * @brief Copies from the given @p other list - * - * This behaves basically like copying a TQValueList through its assignment - * operator, i.e. no value are actually copied at this time. - * - * @param other the other list object to copy from - * - * @return a reference to this list object - */ - TQT_DBusDataList& operator=(const TQT_DBusDataList& other); - - /** - * @brief Copies from the given @p other list - * - * This behaves basically like copying a TQValueList through its assignment - * operator, i.e. no value are actually copied at this time. - * - * \warning the elements of the given @p other list have to be of the same - * type. If they aren't this list's content will cleared and the - * type will be set to TQT_DBusData::Invalid - * - * @param other the other list object to copy from - * - * @return a reference to this list object - */ - TQT_DBusDataList& operator=(const TQValueList& other); - - /** - * @brief Copies from the given @p other list - * - * Convenience overload as TQStringList is a very common data type in - * TQt and D-Bus methods also use "arrays of strings" quite often. - * - * The list object's type will be set to TQT_DBusData::String. If the object - * previously had a container as its element type, this will be reset, i.e. - * hasContainerItemType() will return @c false - * - * @param other the stringlist to copy from - * - * @return a reference to this list object - */ - TQT_DBusDataList& operator=(const TQStringList& other); - - /** - * @brief Returns the element type of the list object - * - * @return one of the values of the TQT_DBusData#Type enum - * - * @see hasContainerItemType() - * @see containerItemType() - */ - TQT_DBusData::Type type() const; - - /** - * @brief Checks whether the element type is a data container itself - * - * If the elements of the list are containers as well, this will return - * @c true - * In this case containerItemType() will return a prototype for such a - * container. - * - * @return @c true if the element type is either TQT_DBusData::Map, - * TQT_DBusData::List or TQT_DBusData::Struct, otherwise @c false - * - * @see TQT_DBusDataList(const TQT_DBusData&) - */ - bool hasContainerItemType() const; - - /** - * @brief Returns a container prototype for the list's element type - * - * Lists which have containers as their elements, i.e. hasContainerItemType() - * returns @c true this will actually specify the details for the use - * container, i.e. the returned data object can be queried for type and - * possible further subtypes. - * - * @return a data object detailing the element type or an invalid data object - * if the list does not have a container as its element type - * - * @see TQT_DBusDataList(const TQT_DBusData&); - * @see type() - * @see TQT_DBusData::Invalid - */ - TQT_DBusData containerItemType() const; - - /** - * @brief Checks whether this list object has a valid element type - * - * This is equal to checking type() for not being TQT_DBusData::Invalid - * - * @return @c true if the list object is valid, otherwise @c false - */ - inline bool isValid() const { return type() != TQT_DBusData::Invalid; } - - /** - * @brief Checks whether this list object has any elements - * - * @return @c true if there are no elements in this list, otherwise @c false - * - * @see count() - */ - bool isEmpty() const; - - /** - * @brief Returns the number of elements of this list object - * - * @return the number of elements - * - * @see isEmpty() - */ - uint count() const; - - /** - * @brief Checks whether the given @p other list is equal to this one - * - * Two lists are considered equal when they have the same type (and same - * container item type if the have one) and the element lists are equal - * as well. - * - * @param other the other list object to compare with - * - * @return @c true if the lists are equal, otherwise @c false - * - * @see TQT_DBusData::operator==() - */ - bool operator==(const TQT_DBusDataList& other) const; - - /** - * @brief Checks whether the given @p other list is different from this one - * - * Two lists are considered different when they have the different type (or - * different container item type if the have one) or the element lists are - * equal are different. - * - * @param other the other list object to compare with - * - * @return @c true if the lists are different, otherwise @c false - * - * @see TQT_DBusData::operator!=() - */ - bool operator!=(const TQT_DBusDataList& other) const; - - /** - * @brief Clears the list - * - * Type and, if applicable, container element type will stay untouched. - */ - void clear(); - - /** - * @brief Appends a given value to the list - * - * Basically works like the respective TQValueList operator, but checks if - * type of the new value matches the type of the list. - * Lists that are invalid will accept any new type and will then be - * typed accordingly. - * - * If @p data is invalid itself, it will not be appended at any time. - * - * \note the more common use case is to work with a TQValueList and then - * use the respective constructor to create the TQT_DBusDataList object - * - * @param data the data item to append to the list - * - * @return a reference to this list object - */ - TQT_DBusDataList& operator<<(const TQT_DBusData& data); - - /** - * @brief Converts the list object into a TQValueList with TQT_DBusData elements - * - * @return the values of the list object as a TQValueList - */ - TQValueList toTQValueList() const; - - /** - * @brief Tries to get the list object's elements as a TQStringList - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::String. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::String) - * - * @return a TQStringList containing the list object's string elements or - * an empty list when converting fails - * - * @see toStringList() - * @see TQT_DBusData::toString() - */ - TQStringList toTQStringList(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of bool - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::Bool. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::Bool) - * - * @return a TQValueList of bool containing the list object's boolean - * elements or an empty list when converting fails - * - * @see TQT_DBusData::toBool() - */ - TQValueList toBoolList(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQ_UINT8 - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::Byte. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::Byte) - * - * @return a TQValueList of TQ_UINT8 containing the list object's byte - * elements or an empty list when converting fails - * - * @see TQT_DBusData::toByte() - */ - TQValueList toByteList(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQ_INT16 - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::Int16. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::Int16) - * - * @return a TQValueList of TQ_INT16 containing the list object's - * signed 16-bit integer elements or an empty list when converting - * fails - * - * @see TQT_DBusData::toInt16() - */ - TQValueList toInt16List(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQ_UINT16 - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::UInt16. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::UInt16) - * - * @return a TQValueList of TQ_UINT16 containing the list object's - * unsigned 16-bit integer elements or an empty list when converting - * fails - * - * @see TQT_DBusData::toUInt16() - */ - TQValueList toUInt16List(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQ_INT32 - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::Int32. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::Int32) - * - * @return a TQValueList of TQ_INT32 containing the list object's - * signed 32-bit integer elements or an empty list when converting - * fails - * - * @see TQT_DBusData::toInt32() - */ - TQValueList toInt32List(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQ_UINT32 - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::UInt32. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::UInt32) - * - * @return a TQValueList of TQ_UINT32 containing the list object's - * unsigned 32-bit integer elements or an empty list when converting - * fails - * - * @see TQT_DBusData::toUInt32() - */ - TQValueList toUInt32List(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQ_INT64 - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::Int64. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::Int64) - * - * @return a TQValueList of TQ_INT64 containing the list object's - * signed 64-bit integer elements or an empty list when converting - * fails - * - * @see TQT_DBusData::toInt64() - */ - TQValueList toInt64List(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQ_UINT64 - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::UInt64. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::UInt64) - * - * @return a TQValueList of TQ_UINT64 containing the list object's - * unsigned 64-bit integer elements or an empty list when converting - * fails - * - * @see TQT_DBusData::toUInt64() - */ - TQValueList toUInt64List(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of double - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::Double. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::Double) - * - * @return a TQValueList of double containing the list object's double - * elements or an empty list when converting fails - * - * @see TQT_DBusData::toDouble() - */ - TQValueList toDoubleList(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQString - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::String, see also toTQStringList(). - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::String) - * - * @return a TQValueList of TQString containing the list object's string - * elements or an empty list when converting fails - * - * @see TQT_DBusData::toString() - */ - TQValueList toStringList(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of object paths - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::ObjectPath) - * - * @return a TQValueList of object paths containing the list object's object path - * elements or an empty list when converting fails - * - * @see TQT_DBusData::toObjectPath() - */ - TQValueList toObjectPathList(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQT_DBusVariant - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::Variant. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::Variant) - * - * @return a TQValueList of TQT_DBusVariant containing the list object's - * TQT_DBusVariant elements or an empty list when converting fails - * - * @see TQT_DBusData::toVariant() - */ - TQValueList toVariantList(bool* ok = 0) const; - - /** - * @brief Tries to get the list object's elements as a TQValueList of TQT_DBusUnixFd - * - * This is a convenience overload for the case when the list is of - * type TQT_DBusData::UnixFd. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of type - * TQT_DBusData::UnixFd) - * - * @return a TQValueList of TQT_DBusUnixFd containing the list object's - * TQT_DBusUnixFd elements or an empty list when converting fails - * - * @see TQT_DBusData::toUnixFd() - */ - TQValueList toUnixFdList(bool* ok = 0) const; - -private: - class Private; - Private* d; -}; - -#endif diff --git a/tqdbusdatamap.h b/tqdbusdatamap.h deleted file mode 100644 index ecb06d2..0000000 --- a/tqdbusdatamap.h +++ /dev/null @@ -1,1281 +0,0 @@ -/* qdbusdatamap.h DBUS data mapping transport type - * - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSDATAMAP_H -#define TQDBUSDATAMAP_H - -#include "tqdbusmacros.h" -#include - -class TQT_DBusData; -class TQT_DBusObjectPath; -class TQT_DBusUnixFd; -class TQT_DBusVariant; - -/** - * @brief Class to transport maps of D-Bus data types - * - * \note while the D-Bus data type is actually called @c dict this bindings - * use the term @c map since TQT_DBusDataMap is essentially a TQMap - * - * There are basically two ways to create TQT_DBusDataMap objects: - * - non-empty from content - * - empty by specifying the desired element type - * - * Example for creating a filled map from content - * @code - * TQMap intToStringMap; - * map.insert(2, "two"); - * map.insert(3, "three"); - * map.insert(5, "five"); - * map.insert(7, "seven"); - * - * TQT_DBusDataMap dbusMap(intToStringMap); - * TQT_DBusData data = TQT_DBusData::fromInt16KeyMap(dbusMap); - * - * // or even shorter, using implicit conversion - * TQT_DBusData other = TQT_DBusData::fromInt16KeyMap(intList); - * @endcode - * - * Example for creating an empty map - * @code - * // empty map for a simple type, mapping from TQString to double - * TQT_DBusDataMap list(TQT_DBusData::Double); - * - * // empty map for value type string lists - * TQT_DBusData valueType = TQT_DBusData::fromList(TQT_DBusDataList(TQT_DBusData::String)); - * TQT_DBusDataMap map(valueType); - * @endcode - * - * @see TQT_DBusDataList - */ -template -class TQDBUS_EXPORT TQT_DBusDataMap : private TQMap -{ - friend class TQT_DBusData; - -public: - /** - * Constant iterator. A TQMapConstIterator with value type specified - * as TQT_DBusData - */ - typedef TQMapConstIterator const_iterator; - - /** - * @brief Creates an empty and invalid map - * - * @see TQT_DBusData::Invalid - */ - TQT_DBusDataMap() - : TQMap(), m_valueType(TQT_DBusData::Invalid) {} - - /** - * @brief Creates an empty map with the given simple type for values - * - * The given type has be one of the non-container types, i.e. any other than - * TQT_DBusData::Map, TQT_DBusData::List or TQT_DBusData::Struct - * - * For creating a map with elements which are containers themselves, use - * TQT_DBusDataMap(const TQT_DBusData&); - * - * @param simpleValueType the type of the values in the new map - */ - explicit TQT_DBusDataMap(TQT_DBusData::Type simpleValueType) - : TQMap(), m_valueType(simpleValueType) {} - - /** - * @brief Creates an empty map with the given container type for values - * - * For creating a map with simple values you can also use - * TQT_DBusDataMap(TQT_DBusData::Type); - * - * @param containerValueType the type of the values in the new map - * - * @see hasContainerValueType() - */ - explicit TQT_DBusDataMap(const TQT_DBusData& containerValueType) - : TQMap(), m_valueType(containerValueType.type()) - { - if (hasContainerValueType()) m_containerValueType = containerValueType; - } - - /** - * @brief Creates a map from the given @p other map - * - * This behaves basically like copying a TQMap through its copy - * constructor, i.e. no value are actually copied at this time. - * - * @param other the other map object to copy from - */ - TQT_DBusDataMap(const TQT_DBusDataMap& other) - : TQMap(other), m_valueType(other.m_valueType), - m_containerValueType(other.m_containerValueType) {} - - /** - * @brief Creates a map from the given TQMap of TQT_DBusData objects - * - * If the @p other map is empty, this will behave like TQT_DBusDataMap(), - * i.e. create an empty and invalid map object. - * - * Type information for the map object, i.e. value type and, if applicable, - * container value type, will be derived from the @p other map's elements. - * - * \warning if the values of the @p other map do not all have the same - * type, the map object will also be empty and invalid - * - * @param other the TQMap of TQT_DBusData objects to copy from - * - * @see toTQMap() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(other), m_valueType(TQT_DBusData::Invalid) - { - const_iterator it = begin(); - if (it == end()) return; - - m_valueType = (*it).type(); - - TQCString containerSignature; - if (hasContainerValueType()) - { - m_containerValueType = it.data(); - containerSignature = m_containerValueType.buildDBusSignature(); - } - - for (++it; it != end(); ++it) - { - if ((*it).type() != m_valueType) - { - m_valueType = TQT_DBusData::Invalid; - m_containerValueType = TQT_DBusData(); - - clear(); - return; - } - else if (hasContainerValueType()) - { - if (it.data().buildDBusSignature() != containerSignature) - { - m_valueType = TQT_DBusData::Invalid; - m_containerValueType = TQT_DBusData(); - - clear(); - return; - } - } - } - } - - /** - * @brief Creates a list from the given TQMap of boolean values - * - * Type information for the map object will be set to TQT_DBusData::Bool - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Bool - * - * @param other the TQMap of boolean values to copy from - * - * @see toBoolMap() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::Bool) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromBool(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of byte (unsigned char) values - * - * Type information for the map object will be set to TQT_DBusData::Byte - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Byte - * - * @param other the TQMap of byte (unsigned char) values to copy from - * - * @see toByteMap() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::Byte) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromByte(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of signed 16-bit integer values - * - * Type information for the map object will be set to TQT_DBusData::Int16 - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Int16 - * - * @param other the TQMap of signed 16-bit integer values to copy from - * - * @see toInt16Map() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::Int16) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromInt16(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of unsigned 16-bit integer values - * - * Type information for the map object will be set to TQT_DBusData::UInt16 - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::UInt16 - * - * @param other the TQMap of unsigned 16-bit integer values to copy from - * - * @see toUInt16Map() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::UInt16) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromUInt16(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of signed 32-bit integer values - * - * Type information for the map object will be set to TQT_DBusData::Int32 - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Int32 - * - * @param other the TQMap of signed 32-bit integer values to copy from - * - * @see toInt32Map() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::Int32) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromInt32(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of unsigned 32-bit integer values - * - * Type information for the map object will be set to TQT_DBusData::UInt16 - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::UInt32 - * - * @param other the TQMap of unsigned 32-bit integer values to copy from - * - * @see toUInt32Map() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::UInt32) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromUInt32(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of signed 64-bit integer values - * - * Type information for the map object will be set to TQT_DBusData::Int64 - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Int64 - * - * @param other the TQMap of signed 64-bit integer values to copy from - * - * @see toInt64Map() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::Int64) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromInt64(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of unsigned 64-bit integer values - * - * Type information for the map object will be set to TQT_DBusData::UInt64 - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::UInt64 - * - * @param other the TQMap of unsigned 64-bit integer values to copy from - * - * @see toUInt64Map() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::UInt64) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromUInt64(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of double values - * - * Type information for the map object will be set to TQT_DBusData::Double - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Double - * - * @param other the TQMap of double values to copy from - * - * @see toDoubleMap() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::Double) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromDouble(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of TQString values - * - * Type information for the map object will be set to TQT_DBusData::String - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::String - * - * @param other the TQMap of TQString values to copy from - * - * @see toStringMap() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::String) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromString(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of object path values - * - * Type information for the map object will be set to TQT_DBusData::ObjectPath - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::ObjectPath - * - * @param other the TQMap of object path values to copy from - * - * @see toObjectPathMap() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::ObjectPath) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromObjectPath(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of TQT_DBusUnixFd values - * - * Type information for the map object will be set to TQT_DBusData::UnixFd - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::UnixFd - * - * @param other the TQMap of TQT_DBusUnixFd values to copy from - * - * @see toUnixFdMap() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::UnixFd) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromUnixFd(it.data())); - } - } - - /** - * @brief Creates a map from the given TQMap of TQT_DBusVariant values - * - * Type information for the map object will be set to TQT_DBusData::Variant - * also when the @p other map is empty, i.e. this allows to create an - * empty but valid map object, comparable to using - * TQT_DBusDataMap(TQT_DBusData::Type) with TQT_DBusData::Variant - * - * @param other the TQMap of variant values to copy from - * - * @see toVariantMap() - */ - TQT_DBusDataMap(const TQMap& other) - : TQMap(), m_valueType(TQT_DBusData::Variant) - { - typename TQMap::const_iterator it = other.begin(); - typename TQMap::const_iterator endIt = other.end(); - for (; it != endIt; ++it) - { - insert(it.key(), TQT_DBusData::fromVariant(it.data())); - } - } - - /** - * @brief Copies from the given @p other map - * - * This behaves basically like copying a TQMap through its assignment - * operator, i.e. no value are actually copied at this time. - * - * @param other the other map object to copy from - * - * @return a reference to this map object - */ - TQT_DBusDataMap& operator=(const TQT_DBusDataMap& other) - { - TQMap::operator=(other); - - m_valueType = other.m_valueType; - m_containerValueType = other.m_containerValueType; - - return *this; - } - - /** - * @brief Copies from the given @p other map - * - * This behaves basically like copying a TQMap through its assignment - * operator, i.e. no value are actually copied at this time. - * - * \warning the value of the given @p other map have to be of the same - * type. If they aren't this maps's content will cleared and the - * value type will be set to TQT_DBusData::Invalid - * - * @param other the other map object to copy from - * - * @return a reference to this map object - */ - TQT_DBusDataMap& operator=(const TQMap& other) - { - TQMap::operator=(other); - - m_valueType = TQT_DBusData::Invalid; - m_containerValueType = TQT_DBusData(); - - const_iterator it = begin(); - if (it == end()) return *this; - - m_valueType = (*it).type(); - - TQCString containerSignature; - if (hasContainerValueType()) - { - m_containerValueType = it.data(); - containerSignature = m_containerValueType.buildDBusSignature(); - } - - for (++it; it != end(); ++it) - { - if ((*it).type() != m_valueType) - { - m_valueType = TQT_DBusData::Invalid; - m_containerValueType = TQT_DBusData(); - - clear(); - return *this; - } - else if (hasContainerValueType()) - { - if (it.data()->buildSignature() != containerSignature) - { - m_valueType = TQT_DBusData::Invalid; - m_containerValueType = TQT_DBusData(); - - clear(); - return *this; - } - } - } - - return *this; - } - - /** - * @brief Returns the key type of the map object - * - * @return one of the values of the TQT_DBusData#Type enum suitable for - * map keys. See TQT_DBusData::Map for details - * - * @see valueType() - */ - TQT_DBusData::Type keyType() const { return m_keyType; } - - /** - * @brief Returns the value type of the map object - * - * @return one of the values of the TQT_DBusData#Type enum - * - * @see hasContainerValueType() - * @see containerValueType() - * @see keyType() - */ - TQT_DBusData::Type valueType() const { return m_valueType; } - - /** - * @brief Checks whether the value type is a data container itself - * - * If the value of the map are containers as well, this will return - * @c true - * In this case containerValueType() will return a prototype for such a - * container. - * - * @return @c true if the value type is either TQT_DBusData::Map, - * TQT_DBusData::List or TQT_DBusData::Struct, otherwise @c false - * - * @see TQT_DBusDataMap(const TQT_DBusData&) - */ - bool hasContainerValueType() const - { - return m_valueType == TQT_DBusData::List || m_valueType == TQT_DBusData::Struct - || m_valueType == TQT_DBusData::Map; - } - - /** - * @brief Returns a container prototype for the map's value type - * - * Lists which have containers as their elements, i.e. hasContainerValueType() - * returns @c true this will actually specify the details for the use - * container, i.e. the returned data object can be queried for type and - * possible further subtypes. - * - * @return a data object detailing the value type or an invalid data object - * if the map does not have a container as its element type - * - * @see TQT_DBusDataMap(const TQT_DBusData&); - * @see valueType() - * @see TQT_DBusData::Invalid - */ - TQT_DBusData containerValueType() const { return m_containerValueType; } - - /** - * @brief Checks whether this map object has a valid value type - * - * This is equal to checking valueType() for not being TQT_DBusData::Invalid - * - * @return @c true if the map object is valid, otherwise @c false - */ - inline bool isValid() const { return valueType() != TQT_DBusData::Invalid; } - - /** - * @brief Checks whether this map object has any key/value pairs - * - * @return @c true if there are no key/values in this map, otherwise @c false - * - * @see count() - */ - bool isEmpty() const { return TQMap::empty(); } - - /** - * @brief Returns the number of key/value pairs of this map object - * - * @return the number of key/value pairs - * - * @see isEmpty() - */ - uint count() const { return TQMap::count(); } - - /** - * @brief Checks whether the given @p other map is equal to this one - * - * Two maps are considered equal when they have the same value type (and same - * container value type if the have one) and the key/value pairs are equal - * as well. - * - * @param other the other map object to compare with - * - * @return @c true if the maps are equal, otherwise @c false - * - * @see TQT_DBusData::operator==() - */ - bool operator==(const TQT_DBusDataMap& other) const - { - if (m_valueType != other.m_valueType) return false; - - if (count() != other.count()) return false; - - if (hasContainerValueType() != other.hasContainerValueType()) return false; - - if (hasContainerValueType()) - { - if (m_containerValueType.buildDBusSignature() != - other.m_containerValueType.buildDBusSignature()) return false; - } - - const_iterator it = begin(); - const_iterator otherIt = other.begin(); - for (; it != end() && otherIt != other.end(); ++it, ++otherIt) - { - if (it.key() != otherIt.key()) return false; - - if (!(it.data() == otherIt.data())) return false; - } - - return true; - } - - /** - * @brief Clears the map - * - * Value type and, if applicable, container value type will stay untouched. - */ - void clear() { TQMap::clear(); } - - /** - * @brief Returns an iterator to the first item according to the key sort order - * - * @see TQMap::begin() - */ - const_iterator begin() const - { - return TQMap::begin(); - } - - /** - * @brief Returns an iterator to an invalid position - * - * @see TQMap::end() - */ - const_iterator end() const - { - return TQMap::end(); - } - - /** - * @brief Inserts a given value for a given key - * - * Basically works like the respective TQMap method, but checks if - * type of the new value matches the value type of the list. - * Maps that are invalid will accept any new type and will then be - * typed accordingly. - * - * If @p data is invalid itself, it will not be inserted at any time. - * - * \note the more common use case is to work with a TQMap and then - * use the respective constructor to create the TQT_DBusDataMap object - * - * @param key the key were to insert into the map - * @param data the data item to insert into the map - * - * @return @c true on successfull insert, otherwise @c false - */ - bool insert(const T& key, const TQT_DBusData& data) - { - if (data.type() == TQT_DBusData::Invalid) return false; - - if (m_valueType == TQT_DBusData::Invalid) - { - m_valueType = data.type(); - - // TODO: create empty copy of container - if (hasContainerValueType()) m_containerValueType = data; - - TQMap::insert(key, data); - } - else if (data.type() != m_valueType) - { - tqWarning("TQT_DBusDataMap: trying to add data of type %s to map of type %s", - data.typeName(), TQT_DBusData::typeName(m_valueType)); - } - else if (hasContainerValueType()) - { - TQCString ourSignature = m_containerValueType.buildDBusSignature(); - TQCString dataSignature = data.buildDBusSignature(); - - if (ourSignature != dataSignature) - { - tqWarning("TQT_DBusDataMap: trying to add data with signature %s " - "to map with value signature %s", - dataSignature.data(), ourSignature.data()); - } - else - TQMap::insert(key, data); - } - else - TQMap::insert(key, data); - - return true; - } - - /** - * @brief Converts the map object into a TQMap with TQT_DBusData elements - * - * @return the key/value pairs of the map object as a TQMap - */ - TQMap toTQMap() const { return *this; } - - /** - * @brief Tries to get the map object's pairs as a TQMap of bool - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::Bool. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::Bool) - * - * @return a TQMap of bool containing the list object's boolean - * values or an empty map when converting fails - * - * @see TQT_DBusData::toBool() - */ - TQMap toBoolMap(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::Bool) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toBool()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQ_UINT8 - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::Byte. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::Byte) - * - * @return a TQMap of TQ_UINT8 containing the list object's byte - * values or an empty map when converting fails - * - * @see TQT_DBusData::toBool() - */ - TQMap toByteMap(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::Byte) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toByte()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQ_INT16 - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::Int16. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::Int16) - * - * @return a TQMap of TQ_INT16 containing the map object's - * signed 16-bit integer values or an empty map when converting - * fails - * - * @see TQT_DBusData::toInt16() - */ - TQMap toInt16Map(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::Int16) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toInt16()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQ_UINT16 - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::UInt16. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::UInt16) - * - * @return a TQMap of TQ_UINT16 containing the map object's - * unsigned 16-bit integer values or an empty map when converting - * fails - * - * @see TQT_DBusData::toUInt16() - */ - TQMap toUInt16Map(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::UInt16) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toUInt16()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQ_INT32 - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::Int32. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::Int32) - * - * @return a TQMap of TQ_INT32 containing the map object's - * signed 32-bit integer values or an empty map when converting - * fails - * - * @see TQT_DBusData::toInt32() - */ - TQMap toInt32Map(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::Int32) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toInt32()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQ_UINT32 - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::UInt32. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::UInt32) - * - * @return a TQMap of TQ_UINT32 containing the map object's - * unsigned 32-bit integer values or an empty map when converting - * fails - * - * @see TQT_DBusData::toUInt32() - */ - TQMap toUInt32Map(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::UInt32) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toUInt32()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQ_INT64 - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::Int64. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::Int64) - * - * @return a TQMap of TQ_INT64 containing the map object's - * signed 64-bit integer values or an empty map when converting - * fails - * - * @see TQT_DBusData::toInt64() - */ - TQMap toInt64Map(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::Int64) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toInt64()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQ_UINT64 - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::UInt64. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::UInt64) - * - * @return a TQMap of TQ_UINT64 containing the map object's - * unsigned 64-bit integer values or an empty map when converting - * fails - * - * @see TQT_DBusData::toUInt64() - */ - TQMap toUInt64Map(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::UInt64) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toUInt64()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of double - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::Double. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::Double) - * - * @return a TQMap of double containing the map object's double - * values or an empty map when converting fails - * - * @see TQT_DBusData::toDouble() - */ - TQMap toDoubleMap(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::Double) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toDouble()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQString - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::String, see also toTQStringList(). - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::String) - * - * @return a TQMap of TQString containing the map object's string - * values or an empty map when converting fails - * - * @see TQT_DBusData::toString() - */ - TQMap toStringMap(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::String) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toString()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of object paths - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::ObjectPath) - * - * @return a TQMap of object paths containing the map object's object path - * values or an empty map when converting fails - * - * @see TQT_DBusData::toObjectPath() - */ - TQMap toObjectPathMap(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::ObjectPath) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toObjectPath()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQT_DBusUnixFd - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::UnixFd) - * - * @return a TQMap of TQT_DBusUnixFd containing the map object's TQT_DBusUnixFd - * values or an empty map when converting fails - * - * @see TQT_DBusData::toUnixFd() - */ - TQMap toUnixFdMap(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::UnixFd) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toUnixFd()); - } - - if (ok != 0) *ok = true; - - return result; - } - - /** - * @brief Tries to get the map object's pairs as a TQMap of TQT_DBusVariant - * - * This is a convenience overload for the case when the map is of - * value type TQT_DBusData::Variant. - * - * @param ok optional pointer to a bool variable to store the - * success information in, i.e. will be set to @c true on success - * and to @c false if the conversion failed (not of value type - * TQT_DBusData::Variant) - * - * @return a TQMap of TQT_DBusVariant containing the map object's - * TQT_DBusVariant values or an empty map when converting fails - * - * @see TQT_DBusData::toVariant() - */ - TQMap toVariantMap(bool* ok = 0) const - { - if (m_valueType != TQT_DBusData::Variant) - { - if (ok != 0) *ok = false; - return TQMap(); - } - - TQMap result; - - const_iterator it = begin(); - const_iterator endIt = end(); - for (; it != endIt; ++it) - { - result.insert(it.key(), (*it).toVariant()); - } - - if (ok != 0) *ok = true; - - return result; - } - -private: - TQT_DBusData::Type m_valueType; - TQT_DBusData m_containerValueType; - - static const TQT_DBusData::Type m_keyType; -}; - -#endif diff --git a/tqdbuserror.cpp b/tqdbuserror.cpp deleted file mode 100644 index d0b1eb9..0000000 --- a/tqdbuserror.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* qdbuserror.cpp TQT_DBusError object - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2005-2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include "tqdbuserror.h" - -#include - -#include - -typedef TQMap ErrorNameMap; -static ErrorNameMap errorTypesByName; - -static TQString qDBusErrorNameForType(TQT_DBusError::ErrorType type) -{ - switch (type) - { - case TQT_DBusError::InvalidError: - Q_ASSERT(false); - return TQString(); - - case TQT_DBusError::Failed: - return TQString::fromUtf8(DBUS_ERROR_FAILED); - case TQT_DBusError:: NoMemory: - return TQString::fromUtf8(DBUS_ERROR_NO_MEMORY); - case TQT_DBusError:: ServiceUnknown: - return TQString::fromUtf8(DBUS_ERROR_SERVICE_UNKNOWN); - case TQT_DBusError:: NameHasNoOwner: - return TQString::fromUtf8(DBUS_ERROR_NAME_HAS_NO_OWNER); - case TQT_DBusError:: NoReply: - return TQString::fromUtf8(DBUS_ERROR_NO_REPLY); - case TQT_DBusError:: IOError: - return TQString::fromUtf8(DBUS_ERROR_IO_ERROR); - case TQT_DBusError:: BadAddress: - return TQString::fromUtf8(DBUS_ERROR_BAD_ADDRESS); - case TQT_DBusError:: NotSupported: - return TQString::fromUtf8(DBUS_ERROR_NOT_SUPPORTED); - case TQT_DBusError:: LimitsExceeded: - return TQString::fromUtf8(DBUS_ERROR_LIMITS_EXCEEDED); - case TQT_DBusError:: AccessDenied: - return TQString::fromUtf8(DBUS_ERROR_ACCESS_DENIED); - case TQT_DBusError:: AuthFailed: - return TQString::fromUtf8(DBUS_ERROR_AUTH_FAILED); - case TQT_DBusError:: NoServer: - return TQString::fromUtf8(DBUS_ERROR_NO_SERVER); - case TQT_DBusError:: Timeout: - return TQString::fromUtf8(DBUS_ERROR_TIMEOUT); - case TQT_DBusError:: NoNetwork: - return TQString::fromUtf8(DBUS_ERROR_NO_NETWORK); - case TQT_DBusError:: Disconnected: - return TQString::fromUtf8(DBUS_ERROR_DISCONNECTED); - case TQT_DBusError:: InvalidArgs: - return TQString::fromUtf8(DBUS_ERROR_INVALID_ARGS); - case TQT_DBusError:: FileNotFound: - return TQString::fromUtf8(DBUS_ERROR_FILE_NOT_FOUND); - case TQT_DBusError:: FileExists: - return TQString::fromUtf8(DBUS_ERROR_FILE_EXISTS); - case TQT_DBusError:: UnknownMethod: - return TQString::fromUtf8(DBUS_ERROR_UNKNOWN_METHOD); - case TQT_DBusError:: TimedOut: - return TQString::fromUtf8(DBUS_ERROR_TIMED_OUT); - case TQT_DBusError:: InvalidSignature: - return TQString::fromUtf8(DBUS_ERROR_INVALID_SIGNATURE); - - case TQT_DBusError::UserDefined: - Q_ASSERT(false); - return TQString(); - } - - Q_ASSERT(false); - return TQString(); -} - -static void qDBusErrorSetupNameMapping() -{ - for (int i = TQT_DBusError::InvalidError + 1; i < TQT_DBusError::UserDefined; ++i) - { - TQT_DBusError::ErrorType type = static_cast(i); - errorTypesByName[qDBusErrorNameForType(type)] = type; - } -} - -static TQT_DBusError::ErrorType qDBusErrorTypeForName(const TQString& name) -{ - if (name.isEmpty()) return TQT_DBusError::InvalidError; - - if (errorTypesByName.isEmpty()) - qDBusErrorSetupNameMapping(); - - ErrorNameMap::const_iterator it = errorTypesByName.find(name); - if (it != errorTypesByName.end()) return it.data(); - - return TQT_DBusError::UserDefined; -} - -TQT_DBusError::TQT_DBusError() : errorType(InvalidError), m_dbusErrorSet(false) -{ -} - -TQT_DBusError::TQT_DBusError(const DBusError *error) : errorType(InvalidError), m_dbusErrorSet(false) -{ - if (!error || !dbus_error_is_set(error)) - return; - - nm = TQString::fromUtf8(error->name); - msg = TQString::fromUtf8(error->message); - - errorType = qDBusErrorTypeForName(nm); -} - -TQT_DBusError::TQT_DBusError(const TQString& error, const TQString& message) - : errorType(UserDefined), m_dbusErrorSet(false), nm(error), msg(message) -{ - errorType = qDBusErrorTypeForName(nm); -} - -bool TQT_DBusError::isValid() const -{ - return errorType != InvalidError && !nm.isEmpty() && !msg.isEmpty(); -} - -TQT_DBusError::TQT_DBusError(ErrorType type, const TQString& message) - : errorType(type), m_dbusErrorSet(false), msg(message) -{ - nm = qDBusErrorNameForType(type); -} - -TQT_DBusError TQT_DBusError::stdFailed(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::Failed, message); -} - -TQT_DBusError TQT_DBusError::stdNoMemory(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::NoMemory, message); -} - -TQT_DBusError TQT_DBusError::stdNoReply(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::NoReply, message); -} - -TQT_DBusError TQT_DBusError::stdIOError(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::IOError, message); -} - -TQT_DBusError TQT_DBusError::stdNotSupported(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::NotSupported, message); -} - -TQT_DBusError TQT_DBusError::stdLimitsExceeded(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::LimitsExceeded, message); -} - -TQT_DBusError TQT_DBusError::stdAccessDenied(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::AccessDenied, message); -} - -TQT_DBusError TQT_DBusError::stdAuthFailed(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::AuthFailed, message); -} - -TQT_DBusError TQT_DBusError::stdTimeout(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::Timeout, message); -} - -TQT_DBusError TQT_DBusError::stdInvalidArgs(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::InvalidArgs, message); -} - -TQT_DBusError TQT_DBusError::stdFileNotFound(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::FileNotFound, message); -} - -TQT_DBusError TQT_DBusError::stdFileExists(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::FileExists, message); -} - -TQT_DBusError TQT_DBusError::stdUnknownMethod(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::UnknownMethod, message); -} - -TQT_DBusError TQT_DBusError::stdInvalidSignature(const TQString& message) -{ - return TQT_DBusError(TQT_DBusError::InvalidSignature, message); -} diff --git a/tqdbuserror.h b/tqdbuserror.h deleted file mode 100644 index ff11ffb..0000000 --- a/tqdbuserror.h +++ /dev/null @@ -1,476 +0,0 @@ -/* qdbuserror.h TQT_DBusError object - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2005 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSERROR_H -#define TQDBUSERROR_H - -#include "tqdbusmacros.h" -#include - -struct DBusError; - -/** - * @brief Class for transporting D-Bus errors - * - * A D-Bus error has two parts: an error name (see section - * @ref dbusconventions-errorname) and a message string detailing the error in - * human presentable form. - */ -class TQDBUS_EXPORT TQT_DBusError -{ -public: - /** - * @brief Enum of standard D-Bus error types - * - * D-Bus defines a list of common error types and their names. - * The values of this enum map to those an application is likely to encounter - * and likely to create itself. - * - * Standard errors can either be created by specifying the D-Bus error name - * or, as a convenience, by using factory methods of this class for the - * most common ones. - * - * All D-Bus standard error names are within the @c "org.freedesktop.DBus.Error" - * namespace. - * - * @see name() - */ - enum ErrorType - { - /** - * @brief TQT_DBusError specific value, to represent invalid error objects. - * - * @see isValid() - */ - InvalidError, - - /** - * @brief Generic failure cause - * - * Can be used whenever the other predefined errors do no match. Basically - * just meaning "something when wrong, see message() for details" - * - * @see stdFailed() - */ - Failed, - - /** - * @brief An operation could not allocate enough memory - * - * @see stdNoMemory() - */ - NoMemory, - - /** - * @brief An addressed service is neither connected nor can it be activated - */ - ServiceUnknown, - - /** - * @brief A non-unique name used in a message is not known - * - * If a message addresses a D-Bus connection through a non-unique - * (requested) name and the D-Bus does not have a mapping to any of the - * unique names. - */ - NameHasNoOwner, - - /** - * @brief An call failed to send a reply but one was expected - * - * @see stdNoReply() - */ - NoReply, - - /** - * @brief An IO error occured during an operation - * - * Generic indicator that some kind of IO operation failed, e.g. - * reading from a socket. - * - * @see stdIOError() - */ - IOError, - - /** - * @brief Caused by trying to connect to a malformed address - * - * Returned by TQT_DBusConnection's addConnection if the specified address - * isn't a valid D-Bus bus address. - * - * @see TQT_DBusConnection::addConnection(const TQString&,const TQString&); - */ - BadAddress, - - /** - * @brief An otherwise valid operation request could not be handled - * - * Primarily useful when a service implements a specific interface but - * does not (yet) handle all possible situations. - * - * @see stdNotSupported() - */ - NotSupported, - - /** - * @brief Use of a limited resource reached its limit - * - * @see stdLimitsExceeded() - */ - LimitsExceeded, - - /** - * @brief Caused by security restrictions denying an operation - * - * Primarily useful when a client tries to manipulate resources a service - * has associated with a different client and which should not be changable - * by anyone else. - * - * @see stdAccessDenied() - */ - AccessDenied, - - /** - * @brief An authentification mechanism failed - * - * @see stdAuthFailed() - */ - AuthFailed, - - /** - * @brief Connection to a D-Bus server failed - */ - NoServer, - - /** - * @brief An timeout occured during an operation - * - * @warning D-Bus defined to quite similar errors but does not detail - * when either one can occur. See #TimedOut - * - * @see stdTimeout() - */ - Timeout, - - /** - * @brief The network intended as a transport channel is not available - */ - NoNetwork, - - /** - * @brief Caused by trying to use an unconnected D-Bus connection - * - * @see TQT_DBusConnection::isConnected() - */ - Disconnected, - - /** - * @brief Caused by invalid arguments passed to a method call - * - * Primarily usefull for service implementations when the incoming - * call does not transport the expected parameters, e.g. wrong types - * or wrong values. - * - * @see stdInvalidArgs() - */ - InvalidArgs, - - /** - * @brief A file necessary for an operation is not avaiable - * - * @see stdFileNotFound() - */ - FileNotFound, - - /** - * @brief Target file exists but operation does not allow overwriting - * - * @see stdFileExists() - */ - FileExists, - - /** - * @brief A method call addresses and unknown method - * - * @see stdUnknownMethod() - */ - UnknownMethod, - - /** - * @brief An operation timed out - * - * @warning D-Bus defined to quite similar errors but does not detail - * when either one can occur. See #Timeout - */ - TimedOut, - - /** - * @brief An type signature is not valid - * - * A possible cause is a TQT_DBusVariant with an invalid signature, i.e. - * the transported signature is empty, contains unknown type characters - * or has mismatched container enclosings. - * - * @note in case a service implementation wants to indicate that a method - * call did not transport the correct parameter types, use - * #InvalidArgs instead - * - * @see stdInvalidSignature() - */ - InvalidSignature, - - /** - * @brief Generic type for all errors not matching on of the other predefined - * - * @see TQT_DBusError(const TQString&,const TQString&); - */ - UserDefined - }; - - /** - * @brief Creates an empty and invalid error object - */ - TQT_DBusError(); - - /** - * @brief Creates an error object from an C API D-Bus error object - * - * @param error a pointer to the C API D-Bus error - */ - TQT_DBusError(const DBusError *error); - - /** - * @brief Creates an error object for its two given components - * - * @param error a D-Bus error name - * @param message the potentially i18n'ed error description message - * - * @see name() - */ - TQT_DBusError(const TQString& error, const TQString& message); - - /** - * @brief Returns the D-Bus error name - * - * See section @ref dbusconventions-errorname for details. - * - * @return the D-Bus error name - * - * @see message() - */ - inline TQString name() const { return nm; } - - /** - * @brief Returns a string describing the error - * - * The message is meant to further detail or describe the error. - * It is usually a translated error message meant for direct - * presentation to the user. - * - * @return the error's message - * - * @see name() - */ - inline TQString message() const { return msg; } - - /** - * @brief Returns a type for checking of standard errors - * - * D-Bus specifies a couple of standard error names, which are mapped to - * TQT_DBusError types in order to make creating and checking for them easier. - * - * @return the error's type - * - * @see name() - */ - inline ErrorType type() const { return errorType; } - - /** - * @brief Returns whether the error was caused by DBUS itself - * - * A TQT_DBusError is considered valid if both name and message are set. - * - * @return @c true if dbus_error_is_set was true after DBUS call completion - */ - inline bool dbusErrorSet() const { return m_dbusErrorSet; } - - /** - * @internal - */ - inline void setDBUSError(bool err) const { m_dbusErrorSet = err; } - - /** - * @brief Returns whether the error object is valid - * - * A TQT_DBusError is considered valid if both name and message are set. - * - * @return @c true if neither name nor message is @c TQString() and the - * error type is a valid type - */ - bool isValid() const; - - /** - * @brief Creates a D-Bus standard error for generic failure - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #Failed with the given @p message - */ - static TQT_DBusError stdFailed(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for out of memory situations - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #NoMemory with the given @p message - */ - static TQT_DBusError stdNoMemory(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for expected reply missing - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #NoReply with the given @p message - */ - static TQT_DBusError stdNoReply(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for generic IO errors - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #IOError with the given @p message - */ - static TQT_DBusError stdIOError(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for unsupported operations - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #NotSupported with the given @p message - */ - static TQT_DBusError stdNotSupported(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for exceeding a limited resource - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #LimitsExceeded with the given @p message - */ - static TQT_DBusError stdLimitsExceeded(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for access to a resource being denied - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #AccessDenied with the given @p message - */ - static TQT_DBusError stdAccessDenied(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for failed authentification - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #AuthFailed with the given @p message - */ - static TQT_DBusError stdAuthFailed(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for timeouts during operations - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #Timeout with the given @p message - */ - static TQT_DBusError stdTimeout(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for call arguments being invalid - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #InvalidArgs with the given @p message - */ - static TQT_DBusError stdInvalidArgs(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for a file not being available - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #FileNotFound with the given @p message - */ - static TQT_DBusError stdFileNotFound(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for a file being in the way - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #FileExists with the given @p message - */ - static TQT_DBusError stdFileExists(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for an unknown methods being called - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #UnknownMethod with the given @p message - */ - static TQT_DBusError stdUnknownMethod(const TQString& message); - - /** - * @brief Creates a D-Bus standard error for D-Bus type signature not valid - * - * @param message the message detailing the encountered problem - * - * @return an error object of type #InvalidSignature with the given @p message - */ - static TQT_DBusError stdInvalidSignature(const TQString& message); - -private: - ErrorType errorType; - mutable bool m_dbusErrorSet; - - TQString nm, msg; - - /** - * @brief Creates an error object for one of the standard D-Bus errors - * - * @param type one of the standard error causes - * @param message the potentially i18n'ed error description message - * - * @see ErrorType - */ - TQT_DBusError(ErrorType type, const TQString& message); -}; - -#endif diff --git a/tqdbusintegrator.cpp b/tqdbusintegrator.cpp deleted file mode 100644 index c7129bd..0000000 --- a/tqdbusintegrator.cpp +++ /dev/null @@ -1,689 +0,0 @@ -/* qdbusintegrator.cpp TQT_DBusConnection private implementation - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2005 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include -#include -#include -#include -#include - -#include "tqdbusconnection_p.h" -#include "tqdbusmessage.h" - -Atomic::Atomic(int value) : m_value(value) -{ -} - -void Atomic::ref() -{ - m_value++; -} - -bool Atomic::deref() -{ - m_value--; - return m_value > 0; -} - -int TQT_DBusConnectionPrivate::messageMetaType = 0; - -static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data) -{ - Q_ASSERT(timeout); - Q_ASSERT(data); - - // tqDebug("addTimeout %d", dbus_timeout_get_interval(timeout)); - - TQT_DBusConnectionPrivate *d = static_cast(data); - - if (!dbus_timeout_get_enabled(timeout)) - return true; - - if (!tqApp) { - d->pendingTimeouts.append(timeout); - return true; - } - int timerId = d->startTimer(dbus_timeout_get_interval(timeout)); - if (!timerId) - return false; - - d->timeouts[timerId] = timeout; - return true; -} - -static void qDBusRemoveTimeout(DBusTimeout *timeout, void *data) -{ - Q_ASSERT(timeout); - Q_ASSERT(data); - - // tqDebug("removeTimeout"); - - TQT_DBusConnectionPrivate *d = static_cast(data); - for (TQValueList::iterator it = d->pendingTimeouts.begin(); - it != d->pendingTimeouts.end();) { - if ((*it) == timeout) { - it = d->pendingTimeouts.erase(it); - } - else - ++it; - } - - TQT_DBusConnectionPrivate::TimeoutHash::iterator it = d->timeouts.begin(); - while (it != d->timeouts.end()) { - if (it.data() == timeout) { - d->killTimer(it.key()); - TQT_DBusConnectionPrivate::TimeoutHash::iterator copyIt = it; - ++it; - d->timeouts.erase(copyIt); - } else { - ++it; - } - } -} - -static void qDBusToggleTimeout(DBusTimeout *timeout, void *data) -{ - Q_ASSERT(timeout); - Q_ASSERT(data); - - //tqDebug("ToggleTimeout"); - - qDBusRemoveTimeout(timeout, data); - qDBusAddTimeout(timeout, data); -} - -static dbus_bool_t qDBusAddWatch(DBusWatch *watch, void *data) -{ - Q_ASSERT(watch); - Q_ASSERT(data); - - TQT_DBusConnectionPrivate *d = static_cast(data); - - int flags = dbus_watch_get_flags(watch); - int fd = dbus_watch_get_unix_fd(watch); - - TQT_DBusConnectionPrivate::Watcher watcher; - if (flags & DBUS_WATCH_READABLE) { - bool enabled = dbus_watch_get_enabled(watch); - //tqDebug("addReadWatch %d %s", fd, (enabled ? "enabled" : "disabled")); - watcher.watch = watch; - if (tqApp) { - watcher.read = new TQSocketNotifier(fd, TQSocketNotifier::Read, d); - if (!enabled) watcher.read->setEnabled(false); - d->connect(watcher.read, TQT_SIGNAL(activated(int)), TQT_SLOT(socketRead(int))); - } - } - if (flags & DBUS_WATCH_WRITABLE) { - bool enabled = dbus_watch_get_enabled(watch); - //tqDebug("addWriteWatch %d %s", fd, (enabled ? "enabled" : "disabled")); - watcher.watch = watch; - if (tqApp) { - watcher.write = new TQSocketNotifier(fd, TQSocketNotifier::Write, d); - if (!enabled) watcher.write->setEnabled(false); - d->connect(watcher.write, TQT_SIGNAL(activated(int)), TQT_SLOT(socketWrite(int))); - } - } - // FIXME-QT4 d->watchers.insertMulti(fd, watcher); - TQT_DBusConnectionPrivate::WatcherHash::iterator it = d->watchers.find(fd); - if (it == d->watchers.end()) - { - it = d->watchers.insert(fd, TQT_DBusConnectionPrivate::WatcherList()); - } - it.data().append(watcher); - - return true; -} - -static void qDBusRemoveWatch(DBusWatch *watch, void *data) -{ - Q_ASSERT(watch); - Q_ASSERT(data); - - //tqDebug("remove watch"); - - TQT_DBusConnectionPrivate *d = static_cast(data); - int fd = dbus_watch_get_unix_fd(watch); - - TQT_DBusConnectionPrivate::WatcherHash::iterator it = d->watchers.find(fd); - if (it != d->watchers.end()) - { - TQT_DBusConnectionPrivate::WatcherList& list = *it; - for (TQT_DBusConnectionPrivate::WatcherList::iterator wit = list.begin(); - wit != list.end(); ++wit) - { - if ((*wit).watch == watch) - { - // migth be called from a function triggered by a socket listener - // so just disconnect them and schedule their delayed deletion. - - d->removedWatches.append(*wit); - if ((*wit).read) - { - (*wit).read->disconnect(d); - (*wit).read = 0; - } - if ((*wit).write) - { - (*wit).write->disconnect(d); - (*wit).write = 0; - } - (*wit).watch = 0; - } - } - } - - if (d->removedWatches.count() > 0) - TQTimer::singleShot(0, d, TQT_SLOT(purgeRemovedWatches())); -} - -static void qDBusToggleWatch(DBusWatch *watch, void *data) -{ - Q_ASSERT(watch); - Q_ASSERT(data); - - //tqDebug("toggle watch"); - - TQT_DBusConnectionPrivate *d = static_cast(data); - int fd = dbus_watch_get_unix_fd(watch); - - TQT_DBusConnectionPrivate::WatcherHash::iterator it = d->watchers.find(fd); - if (it != d->watchers.end()) { - TQT_DBusConnectionPrivate::WatcherList& list = *it; - for (TQT_DBusConnectionPrivate::WatcherList::iterator wit = list.begin(); wit != list.end(); - ++wit) - { - if ((*wit).watch == watch) { - bool enabled = dbus_watch_get_enabled(watch); - int flags = dbus_watch_get_flags(watch); - -// tqDebug("toggle watch %d to %d (write: %d, read: %d)", -// dbus_watch_get_unix_fd(watch), enabled, -// flags & DBUS_WATCH_WRITABLE, flags & DBUS_WATCH_READABLE); - - if (flags & DBUS_WATCH_READABLE && (*wit).read) - (*wit).read->setEnabled(enabled); - if (flags & DBUS_WATCH_WRITABLE && (*wit).write) - (*wit).write->setEnabled(enabled); - return; - } - } - } -} - -static void qDBusNewConnection(DBusServer *server, DBusConnection *c, void *data) -{ - Q_ASSERT(data); Q_ASSERT(server); Q_ASSERT(c); - - tqDebug("SERVER: GOT A NEW CONNECTION"); // TODO -} - -static DBusHandlerResult qDBusSignalFilter(DBusConnection *connection, - DBusMessage *message, void *data) -{ - Q_ASSERT(data); - Q_UNUSED(connection); - - TQT_DBusConnectionPrivate *d = static_cast(data); - if (d->mode == TQT_DBusConnectionPrivate::InvalidMode) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - int msgType = dbus_message_get_type(message); - bool handled = false; - - //TQT_DBusMessage amsg = TQT_DBusMessage::fromDBusMessage(message); - //tqDebug() << "got message: " << dbus_message_get_type(message) << amsg; - - if (msgType == DBUS_MESSAGE_TYPE_SIGNAL) { - handled = d->handleSignal(message); - } else if (msgType == DBUS_MESSAGE_TYPE_METHOD_CALL) { - handled = d->handleObjectCall(message); - } - - return handled ? DBUS_HANDLER_RESULT_HANDLED : - DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -int TQT_DBusConnectionPrivate::registerMessageMetaType() -{ - // FIXME-QT4 int tp = messageMetaType = qRegisterMetaType("TQT_DBusMessage"); - int tp = 0; - return tp; -} - -TQT_DBusConnectionPrivate::TQT_DBusConnectionPrivate(TQObject *parent) - : TQObject(parent), ref(1), mode(InvalidMode), connection(0), server(0), - dispatcher(0), inDispatch(false) -{ - static const int msgType = registerMessageMetaType(); - Q_UNUSED(msgType); - - dbus_error_init(&error); - - dispatcher = new TQTimer(this); - TQObject::connect(dispatcher, TQT_SIGNAL(timeout()), this, TQT_SLOT(dispatch())); - - m_resultEmissionQueueTimer = new TQTimer(this); - TQObject::connect(m_resultEmissionQueueTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(transmitResultEmissionQueue())); - m_messageEmissionQueueTimer = new TQTimer(this); - TQObject::connect(m_messageEmissionQueueTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(transmitMessageEmissionQueue())); -} - -TQT_DBusConnectionPrivate::~TQT_DBusConnectionPrivate() -{ - for (PendingCallMap::iterator it = pendingCalls.begin(); it != pendingCalls.end();) - { - PendingCallMap::iterator copyIt = it; - ++it; - dbus_pending_call_cancel(copyIt.key()); - dbus_pending_call_unref(copyIt.key()); - delete copyIt.data(); - pendingCalls.erase(copyIt); - } - - if (dbus_error_is_set(&error)) - dbus_error_free(&error); - - closeConnection(); -} - -void TQT_DBusConnectionPrivate::closeConnection() -{ - ConnectionMode oldMode = mode; - mode = InvalidMode; // prevent reentrancy - if (oldMode == ServerMode) { - if (server) { - dbus_server_disconnect(server); - dbus_server_unref(server); - server = 0; - } - } else if (oldMode == ClientMode) { - if (connection) { - // closing shared connections is forbidden -#if 0 - dbus_connection_close(connection); - // send the "close" message - while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS); -#endif - dbus_connection_unref(connection); - connection = 0; - } - } -} - -bool TQT_DBusConnectionPrivate::handleError() -{ - lastError = TQT_DBusError(&error); - if (dbus_error_is_set(&error)) - dbus_error_free(&error); - return lastError.isValid(); -} - -void TQT_DBusConnectionPrivate::emitPendingCallReply(const TQT_DBusMessage& message) -{ - emit dbusPendingCallReply(message); -} - -void TQT_DBusConnectionPrivate::bindToApplication() -{ - // Yay, now that we have an application we are in business - // Re-add all watchers - WatcherHash oldWatchers = watchers; - watchers.clear(); - // FIXME-QT4 TQHashIterator it(oldWatchers); - for (WatcherHash::const_iterator it = oldWatchers.begin(); it != oldWatchers.end(); ++it) - { - const WatcherList& list = *it; - for (WatcherList::const_iterator wit = list.begin(); wit != list.end(); ++wit) - { - if (!(*wit).read && !(*wit).write) { - qDBusAddWatch((*wit).watch, this); - } - } - } - - // Re-add all timeouts - while (!pendingTimeouts.isEmpty()) { - qDBusAddTimeout(pendingTimeouts.first(), this); - pendingTimeouts.pop_front(); - } -} - -void TQT_DBusConnectionPrivate::socketRead(int fd) -{ - // FIXME-QT4 TQHashIterator it(watchers); - WatcherHash::const_iterator it = watchers.find(fd); - if (it != watchers.end()) { - const WatcherList& list = *it; - for (WatcherList::const_iterator wit = list.begin(); wit != list.end(); ++wit) { - if ((*wit).read && (*wit).read->isEnabled()) { - if (!dbus_watch_handle((*wit).watch, DBUS_WATCH_READABLE)) - tqDebug("OUT OF MEM"); - } - } - } - if (mode == ClientMode) - scheduleDispatch(); -} - -void TQT_DBusConnectionPrivate::socketWrite(int fd) -{ - // FIXME-QT4 TQHashIterator it(watchers); - WatcherHash::const_iterator it = watchers.find(fd); - if (it != watchers.end()) { - const WatcherList& list = *it; - for (WatcherList::const_iterator wit = list.begin(); wit != list.end(); ++wit) { - if ((*wit).write && (*wit).write->isEnabled()) { - if (!dbus_watch_handle((*wit).watch, DBUS_WATCH_WRITABLE)) - tqDebug("OUT OF MEM"); - } - } - } -} - -void TQT_DBusConnectionPrivate::objectDestroyed(TQObject* object) -{ - //tqDebug("Object destroyed"); - for (PendingCallMap::iterator it = pendingCalls.begin(); it != pendingCalls.end();) - { - TQObject* receiver = (TQObject*) it.data()->receiver; - if (receiver == object || receiver == 0) - { - PendingCallMap::iterator copyIt = it; - ++it; - - dbus_pending_call_cancel(copyIt.key()); - dbus_pending_call_unref(copyIt.key()); - delete copyIt.data(); - pendingCalls.erase(copyIt); - } - else - ++it; - } -} - -void TQT_DBusConnectionPrivate::purgeRemovedWatches() -{ - if (removedWatches.isEmpty()) return; - - WatcherList::iterator listIt = removedWatches.begin(); - for (; listIt != removedWatches.end(); ++listIt) - { - delete (*listIt).read; - delete (*listIt).write; - } - removedWatches.clear(); - - uint count = 0; - WatcherHash::iterator it = watchers.begin(); - while (it != watchers.end()) - { - WatcherList& list = *it; - listIt = list.begin(); - while (listIt != list.end()) - { - if (!((*listIt).read) && !((*listIt).write)) - { - listIt = list.erase(listIt); - ++count; - } - } - - if (list.isEmpty()) - { - WatcherHash::iterator copyIt = it; - ++it; - watchers.erase(copyIt); - } - else - ++it; - } -} - -void TQT_DBusConnectionPrivate::scheduleDispatch() -{ - dispatcher->start(0); -} - -void TQT_DBusConnectionPrivate::dispatch() -{ - // dbus_connection_dispatch will hang if called recursively - if (inDispatch) { - printf("[dbus-1-tqt] WARNING: Attempt to call dispatch() recursively was silently ignored to prevent lockup!\n\r"); fflush(stdout); - return; - } - inDispatch = true; - - if (mode == ClientMode) - { - if (dbus_connection_dispatch(connection) != DBUS_DISPATCH_DATA_REMAINS) - { - // stop dispatch timer - dispatcher->stop(); - } - } - - inDispatch = false; -} - -void TQT_DBusConnectionPrivate::transmitMessageEmissionQueue() -{ - TQT_DBusConnectionPrivate::PendingMessagesForEmit::iterator pmfe; - pmfe = pendingMessages.begin(); - while (pmfe != pendingMessages.end()) { - TQT_DBusMessage msg = *pmfe; - pmfe = pendingMessages.remove(pmfe); - dbusSignal(msg); - } -} - -bool TQT_DBusConnectionPrivate::handleObjectCall(DBusMessage *message) -{ - TQT_DBusMessage msg = TQT_DBusMessage::fromDBusMessage(message); - - ObjectMap::iterator it = registeredObjects.find(msg.path()); - if (it == registeredObjects.end()) - return false; - - return it.data()->handleMethodCall(msg); -} - -bool TQT_DBusConnectionPrivate::handleSignal(DBusMessage *message) -{ - TQT_DBusMessage msg = TQT_DBusMessage::fromDBusMessage(message); - - // yes, it is a single "|" below... - // FIXME-QT4 - //return handleSignal(TQString(), msg) | handleSignal(msg.path(), msg); - - // If dbusSignal(msg) were called here, it could easily cause a lockup as it would enter the TQt3 event loop, - // which could result in arbitrary methods being called while still inside dbus_connection_dispatch. - // Instead, I enqueue the messages here for TQt3 event loop transmission after dbus_connection_dispatch is finished. - pendingMessages.append(msg); - if (!m_messageEmissionQueueTimer->isActive()) m_messageEmissionQueueTimer->start(0, TRUE); - - return true; -} - -static dbus_int32_t server_slot = -1; - -void TQT_DBusConnectionPrivate::setServer(DBusServer *s) -{ - if (!server) { - handleError(); - return; - } - - server = s; - mode = ServerMode; - - dbus_server_allocate_data_slot(&server_slot); - if (server_slot < 0) - return; - - dbus_server_set_watch_functions(server, qDBusAddWatch, qDBusRemoveWatch, - qDBusToggleWatch, this, 0); // ### check return type? - dbus_server_set_timeout_functions(server, qDBusAddTimeout, qDBusRemoveTimeout, - qDBusToggleTimeout, this, 0); - dbus_server_set_new_connection_function(server, qDBusNewConnection, this, 0); - - dbus_server_set_data(server, server_slot, this, 0); -} - -void TQT_DBusConnectionPrivate::setConnection(DBusConnection *dbc) -{ - if (!dbc) { - handleError(); - return; - } - - connection = dbc; - mode = ClientMode; - - dbus_connection_set_exit_on_disconnect(connection, false); - dbus_connection_set_watch_functions(connection, qDBusAddWatch, qDBusRemoveWatch, - qDBusToggleWatch, this, 0); - dbus_connection_set_timeout_functions(connection, qDBusAddTimeout, qDBusRemoveTimeout, - qDBusToggleTimeout, this, 0); -// dbus_bus_add_match(connection, "type='signal',interface='com.trolltech.dbus.Signal'", &error); -// dbus_bus_add_match(connection, "type='signal'", &error); - - dbus_bus_add_match(connection, "type='signal'", &error); - if (handleError()) { - closeConnection(); - return; - } - - const char *service = dbus_bus_get_unique_name(connection); - if (service) { - TQCString filter; - filter += "destination='"; - filter += service; - filter += "\'"; - - dbus_bus_add_match(connection, filter.data(), &error); - if (handleError()) { - closeConnection(); - return; - } - } else { - tqWarning("TQT_DBusConnectionPrivate::SetConnection: Unable to get unique name"); - } - - dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0); - - //tqDebug("unique name: %s", service); -} - -static void qDBusResultReceived(DBusPendingCall *pending, void *user_data) -{ - //tqDebug("Pending Call Result received"); - TQT_DBusConnectionPrivate* d = reinterpret_cast(user_data); - TQT_DBusConnectionPrivate::PendingCallMap::iterator it = d->pendingCalls.find(pending); - - DBusMessage *dbusReply = dbus_pending_call_steal_reply(pending); - - dbus_set_error_from_message(&d->error, dbusReply); - d->handleError(); - - if (it != d->pendingCalls.end()) - { - TQT_DBusMessage reply = TQT_DBusMessage::fromDBusMessage(dbusReply); - - TQT_DBusResultInfo dbusResult; - dbusResult.message = reply; - dbusResult.receiver = it.data()->receiver; - dbusResult.method = it.data()->method.data(); - d->m_resultEmissionQueue.append(dbusResult); - d->newMethodInResultEmissionQueue(); - } - - dbus_message_unref(dbusReply); - dbus_pending_call_unref(pending); - delete it.data(); - - d->pendingCalls.erase(it); -} - -int TQT_DBusConnectionPrivate::sendWithReplyAsync(const TQT_DBusMessage &message, TQObject *receiver, - const char *method) -{ - if (!receiver || !method) - return 0; - - if (!TQObject::connect(receiver, TQT_SIGNAL(destroyed(TQObject*)), - this, TQT_SLOT(objectDestroyed(TQObject*)))) - return false; - - DBusMessage *msg = message.toDBusMessage(); - if (!msg) - return 0; - - int msg_serial = 0; - DBusPendingCall *pending = 0; - if (dbus_connection_send_with_reply(connection, msg, &pending, message.timeout())) { - TQT_DBusPendingCall *pcall = new TQT_DBusPendingCall; - pcall->receiver = receiver; - pcall->method = method; - pcall->pending = pending; - pendingCalls.insert(pcall->pending, pcall); - - dbus_pending_call_set_notify(pending, qDBusResultReceived, this, 0); - - msg_serial = dbus_message_get_serial(msg); - } - - dbus_message_unref(msg); - return msg_serial; -} - -void TQT_DBusConnectionPrivate::flush() -{ - if (!connection) return; - - dbus_connection_flush(connection); -} - -void TQT_DBusConnectionPrivate::newMethodInResultEmissionQueue() -{ - if (!m_resultEmissionQueueTimer->isActive()) m_resultEmissionQueueTimer->start(0, TRUE); -} - -void TQT_DBusConnectionPrivate::transmitResultEmissionQueue() -{ - if (!m_resultEmissionQueue.isEmpty()) { - TQT_DBusResultInfoList::Iterator it; - it = m_resultEmissionQueue.begin(); - while (it != m_resultEmissionQueue.end()) { - TQT_DBusResultInfo dbusResult = (*it); - m_resultEmissionQueue.remove(it); - it = m_resultEmissionQueue.begin(); - - TQObject::connect(this, TQT_SIGNAL(dbusPendingCallReply(const TQT_DBusMessage&)), dbusResult.receiver, dbusResult.method.data()); - emitPendingCallReply(dbusResult.message); - TQObject::disconnect(this, TQT_SIGNAL(dbusPendingCallReply(const TQT_DBusMessage&)), dbusResult.receiver, dbusResult.method.data()); - } - } -} - -#include "tqdbusconnection_p.moc" diff --git a/tqdbusmacros.h b/tqdbusmacros.h deleted file mode 100644 index 2470094..0000000 --- a/tqdbusmacros.h +++ /dev/null @@ -1,31 +0,0 @@ -/* qdbusmacros TQDBUS macro definitions - * - * Copyright (C) 2005 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSMACROS_H -#define TQDBUSMACROS_H - -#include - -#define TQDBUS_EXPORT TQ_EXPORT - -#endif diff --git a/tqdbusmarshall.cpp b/tqdbusmarshall.cpp deleted file mode 100644 index 7f0781f..0000000 --- a/tqdbusmarshall.cpp +++ /dev/null @@ -1,1254 +0,0 @@ -/* qdbusmarshall.cpp - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include "tqdbusmarshall.h" -#include "tqdbusdata.h" -#include "tqdbusdatalist.h" -#include "tqdbusdatamap.h" -#include "tqdbusobjectpath.h" -#include "tqdbusunixfd.h" -#include "tqdbusvariant.h" - -#include -#include -#include -#include -#include - -#include - -template -inline T qIterGet(DBusMessageIter *it) -{ - T t; - dbus_message_iter_get_basic(it, &t); - return t; -} - -static TQT_DBusData::Type qSingleTypeForDBusSignature(char signature) -{ - switch (signature) - { - case 'b': return TQT_DBusData::Bool; - case 'y': return TQT_DBusData::Byte; - case 'n': return TQT_DBusData::Int16; - case 'q': return TQT_DBusData::UInt16; - case 'i': return TQT_DBusData::Int32; - case 'u': return TQT_DBusData::UInt32; - case 'x': return TQT_DBusData::Int64; - case 't': return TQT_DBusData::UInt64; - case 'd': return TQT_DBusData::Double; - case 's': return TQT_DBusData::String; - case 'o': return TQT_DBusData::ObjectPath; - case 'g': return TQT_DBusData::String; - case 'v': return TQT_DBusData::Variant; - case 'h': return TQT_DBusData::UnixFd; - - default: - break; - } - - return TQT_DBusData::Invalid; -} - -static TQValueList parseSignature(TQCString& signature) -{ -// tqDebug("parseSignature(%s)", signature.data()); - TQValueList result; - - while (!signature.isEmpty()) - { - switch (signature[0]) - { - case '(': { - signature = signature.mid(1); - TQValueList memberList = parseSignature(signature); - result << TQT_DBusData::fromStruct(memberList); - Q_ASSERT(!signature.isEmpty() && signature[0] == ')'); - signature = signature.mid(1); - break; - } - case ')': return result; - case '{': { - TQT_DBusData::Type keyType = - qSingleTypeForDBusSignature(signature[1]); - TQT_DBusData::Type valueType = - qSingleTypeForDBusSignature(signature[2]); - if (valueType != TQT_DBusData::Invalid) - { - switch (keyType) - { - case TQT_DBusData::Byte: - result << TQT_DBusData::fromByteKeyMap( - TQT_DBusDataMap(valueType)); - break; - case TQT_DBusData::Int16: - result << TQT_DBusData::fromInt16KeyMap( - TQT_DBusDataMap(valueType)); - break; - case TQT_DBusData::UInt16: - result << TQT_DBusData::fromUInt16KeyMap( - TQT_DBusDataMap(valueType)); - break; - case TQT_DBusData::Int32: - result << TQT_DBusData::fromInt32KeyMap( - TQT_DBusDataMap(valueType)); - break; - case TQT_DBusData::UInt32: - result << TQT_DBusData::fromUInt32KeyMap( - TQT_DBusDataMap(valueType)); - break; - case TQT_DBusData::Int64: - result << TQT_DBusData::fromInt64KeyMap( - TQT_DBusDataMap(valueType)); - break; - case TQT_DBusData::UInt64: - result << TQT_DBusData::fromUInt64KeyMap( - TQT_DBusDataMap(valueType)); - break; - case TQT_DBusData::String: - result << TQT_DBusData::fromStringKeyMap( - TQT_DBusDataMap(valueType)); - break; - case TQT_DBusData::ObjectPath: - result << TQT_DBusData::fromObjectPathKeyMap( - TQT_DBusDataMap(valueType)); - break; - case TQT_DBusData::UnixFd: - result << TQT_DBusData::fromUnixFdKeyMap( - TQT_DBusDataMap(valueType)); - break; - default: - tqWarning("TQT_DBusMarshall: unsupported map key type %s " - "at de-marshalling", - TQT_DBusData::typeName(keyType)); - break; - } - signature = signature.mid(3); - } - else - { - signature = signature.mid(2); - TQValueList valueContainer = - parseSignature(signature); - Q_ASSERT(valueContainer.count() == 1); - - switch (keyType) - { - case TQT_DBusData::Byte: - result << TQT_DBusData::fromByteKeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - case TQT_DBusData::Int16: - result << TQT_DBusData::fromInt16KeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - case TQT_DBusData::UInt16: - result << TQT_DBusData::fromUInt16KeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - case TQT_DBusData::Int32: - result << TQT_DBusData::fromInt32KeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - case TQT_DBusData::UInt32: - result << TQT_DBusData::fromUInt32KeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - case TQT_DBusData::Int64: - result << TQT_DBusData::fromInt64KeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - case TQT_DBusData::UInt64: - result << TQT_DBusData::fromUInt64KeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - case TQT_DBusData::String: - result << TQT_DBusData::fromStringKeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - case TQT_DBusData::ObjectPath: - result << TQT_DBusData::fromObjectPathKeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - case TQT_DBusData::UnixFd: - result << TQT_DBusData::fromUnixFdKeyMap( - TQT_DBusDataMap(valueContainer[0])); - break; - default: - tqWarning("TQT_DBusMarshall: unsupported map key type %s " - "at de-marshalling", - TQT_DBusData::typeName(keyType)); - break; - } - } - Q_ASSERT(!signature.isEmpty() && signature[0] == '}'); - signature = signature.mid(1); - break; - } - case '}': return result; - case 'a': { - TQT_DBusData::Type elementType = - qSingleTypeForDBusSignature(signature[1]); - if (elementType != TQT_DBusData::Invalid) - { - TQT_DBusDataList list(elementType); - result << TQT_DBusData::fromList(list); - signature = signature.mid(2); - } - else - { - signature = signature.mid(1); - bool array = signature[0] != '{'; - - TQValueList elementContainer = - parseSignature(signature); - Q_ASSERT(elementContainer.count() == 1); - - if (array) - { - TQT_DBusDataList list(elementContainer[0]); - result << TQT_DBusData::fromList(list); - } - else - result << elementContainer[0]; - } - break; - } - default: - TQT_DBusData::Type elementType = - qSingleTypeForDBusSignature(signature[0]); - if (elementType != TQT_DBusData::Invalid) - { - switch (elementType) - { - case TQT_DBusData::Bool: - result << TQT_DBusData::fromBool( - (0)); - break; - case TQT_DBusData::Byte: - result << TQT_DBusData::fromByte( - (0)); - break; - case TQT_DBusData::Int16: - result << TQT_DBusData::fromInt16( - (0)); - break; - case TQT_DBusData::UInt16: - result << TQT_DBusData::fromUInt16( - (0)); - break; - case TQT_DBusData::Int32: - result << TQT_DBusData::fromInt32( - (0)); - break; - case TQT_DBusData::UInt32: - result << TQT_DBusData::fromUInt32( - (0)); - break; - case TQT_DBusData::Int64: - result << TQT_DBusData::fromInt64( - (0)); - break; - case TQT_DBusData::UInt64: - result << TQT_DBusData::fromUInt64( - (0)); - break; - case TQT_DBusData::String: - result << TQT_DBusData::fromString( - (TQString())); - break; - case TQT_DBusData::ObjectPath: - result << TQT_DBusData::fromObjectPath( - (TQT_DBusObjectPath())); - break; - case TQT_DBusData::UnixFd: - result << TQT_DBusData::fromUnixFd( - (TQT_DBusUnixFd())); - break; - default: - result << TQT_DBusData(); - tqWarning("TQT_DBusMarshall: unsupported element type %s " - "at de-marshalling", - TQT_DBusData::typeName(elementType)); - break; - } - signature = signature.mid(1); - } - else { - result << TQT_DBusData(); - signature = signature.mid(1); - } - break; - } - } - - return result; -} - -static TQT_DBusData qFetchParameter(DBusMessageIter *it); - -void qFetchByteKeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) -{ - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - Q_ASSERT(dbus_message_iter_has_next(&itemIter)); - - TQ_UINT8 key = qFetchParameter(&itemIter).toByte(); - - dbus_message_iter_next(&itemIter); - - map.insert(key, qFetchParameter(&itemIter)); -} - -void qFetchInt16KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) -{ - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - Q_ASSERT(dbus_message_iter_has_next(&itemIter)); - - TQ_INT16 key = qFetchParameter(&itemIter).toInt16(); - - dbus_message_iter_next(&itemIter); - - map.insert(key, qFetchParameter(&itemIter)); -} - -void qFetchUInt16KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) -{ - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - Q_ASSERT(dbus_message_iter_has_next(&itemIter)); - - TQ_UINT16 key = qFetchParameter(&itemIter).toUInt16(); - - dbus_message_iter_next(&itemIter); - - map.insert(key, qFetchParameter(&itemIter)); -} - -void qFetchInt32KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) -{ - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - Q_ASSERT(dbus_message_iter_has_next(&itemIter)); - - TQ_INT32 key = qFetchParameter(&itemIter).toInt32(); - - dbus_message_iter_next(&itemIter); - - map.insert(key, qFetchParameter(&itemIter)); -} - -void qFetchUInt32KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) -{ - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - Q_ASSERT(dbus_message_iter_has_next(&itemIter)); - - TQ_UINT32 key = qFetchParameter(&itemIter).toUInt32(); - - dbus_message_iter_next(&itemIter); - - map.insert(key, qFetchParameter(&itemIter)); -} - -void qFetchInt64KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) -{ - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - Q_ASSERT(dbus_message_iter_has_next(&itemIter)); - - TQ_INT64 key = qFetchParameter(&itemIter).toInt64(); - - dbus_message_iter_next(&itemIter); - - map.insert(key, qFetchParameter(&itemIter)); -} - -void qFetchUInt64KeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) -{ - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - Q_ASSERT(dbus_message_iter_has_next(&itemIter)); - - TQ_UINT64 key = qFetchParameter(&itemIter).toUInt64(); - - dbus_message_iter_next(&itemIter); - - map.insert(key, qFetchParameter(&itemIter)); -} - -void qFetchObjectPathKeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) -{ - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - Q_ASSERT(dbus_message_iter_has_next(&itemIter)); - - TQT_DBusObjectPath key = qFetchParameter(&itemIter).toObjectPath(); - - dbus_message_iter_next(&itemIter); - - map.insert(key, qFetchParameter(&itemIter)); -} - -void qFetchStringKeyMapEntry(TQT_DBusDataMap& map, DBusMessageIter* it) -{ - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - Q_ASSERT(dbus_message_iter_has_next(&itemIter)); - - TQString key = qFetchParameter(&itemIter).toString(); - - dbus_message_iter_next(&itemIter); - - map.insert(key, qFetchParameter(&itemIter)); -} - -static TQT_DBusData qFetchMap(DBusMessageIter *it, const TQT_DBusData& prototype) -{ - if (dbus_message_iter_get_arg_type(it) == DBUS_TYPE_INVALID) - return prototype; - - DBusMessageIter itemIter; - dbus_message_iter_recurse(it, &itemIter); - if (dbus_message_iter_get_arg_type(&itemIter) == DBUS_TYPE_INVALID) - return prototype; - - switch (dbus_message_iter_get_arg_type(&itemIter)) { - case DBUS_TYPE_BYTE: { - TQT_DBusDataMap map = prototype.toByteKeyMap(); - do { - qFetchByteKeyMapEntry(map, it); - } while (dbus_message_iter_next(it)); - - return TQT_DBusData::fromByteKeyMap(map); - } - - case DBUS_TYPE_INT16: { - TQT_DBusDataMap map = prototype.toInt16KeyMap(); - do { - qFetchInt16KeyMapEntry(map, it); - } while (dbus_message_iter_next(it)); - - return TQT_DBusData::fromInt16KeyMap(map); - } - - case DBUS_TYPE_UINT16: { - TQT_DBusDataMap map = prototype.toUInt16KeyMap(); - do { - qFetchUInt16KeyMapEntry(map, it); - } while (dbus_message_iter_next(it)); - - return TQT_DBusData::fromUInt16KeyMap(map); - } - - case DBUS_TYPE_INT32: { - TQT_DBusDataMap map = prototype.toInt32KeyMap(); - do { - qFetchInt32KeyMapEntry(map, it); - } while (dbus_message_iter_next(it)); - - return TQT_DBusData::fromInt32KeyMap(map); - } - - case DBUS_TYPE_UINT32: { - TQT_DBusDataMap map = prototype.toUInt32KeyMap(); - do { - qFetchUInt32KeyMapEntry(map, it); - } while (dbus_message_iter_next(it)); - - return TQT_DBusData::fromUInt32KeyMap(map); - } - - case DBUS_TYPE_INT64: { - TQT_DBusDataMap map = prototype.toInt64KeyMap(); - do { - qFetchInt64KeyMapEntry(map, it); - } while (dbus_message_iter_next(it)); - - return TQT_DBusData::fromInt64KeyMap(map); - } - - case DBUS_TYPE_UINT64: { - TQT_DBusDataMap map = prototype.toUInt64KeyMap(); - do { - qFetchUInt64KeyMapEntry(map, it); - } while (dbus_message_iter_next(it)); - - return TQT_DBusData::fromUInt64KeyMap(map); - } - - case DBUS_TYPE_OBJECT_PATH: { - TQT_DBusDataMap map = prototype.toObjectPathKeyMap(); - do { - qFetchObjectPathKeyMapEntry(map, it); - } while (dbus_message_iter_next(it)); - - return TQT_DBusData::fromObjectPathKeyMap(map); - } - case DBUS_TYPE_STRING: // fall through - case DBUS_TYPE_SIGNATURE: { - TQT_DBusDataMap map = prototype.toStringKeyMap(); - do { - qFetchStringKeyMapEntry(map, it); - } while (dbus_message_iter_next(it)); - - return TQT_DBusData::fromStringKeyMap(map); - } - - default: - break; - } - - return prototype; -} - -static TQT_DBusData qFetchParameter(DBusMessageIter *it) -{ - switch (dbus_message_iter_get_arg_type(it)) { - case DBUS_TYPE_BOOLEAN: - return TQT_DBusData::fromBool(qIterGet(it)); - case DBUS_TYPE_BYTE: - return TQT_DBusData::fromByte(qIterGet(it)); - case DBUS_TYPE_INT16: - return TQT_DBusData::fromInt16(qIterGet(it)); - case DBUS_TYPE_UINT16: - return TQT_DBusData::fromUInt16(qIterGet(it)); - case DBUS_TYPE_INT32: - return TQT_DBusData::fromInt32(qIterGet(it)); - case DBUS_TYPE_UINT32: - return TQT_DBusData::fromUInt32(qIterGet(it)); - case DBUS_TYPE_INT64: - return TQT_DBusData::fromInt64(qIterGet(it)); - case DBUS_TYPE_UINT64: - return TQT_DBusData::fromUInt64(qIterGet(it)); - case DBUS_TYPE_DOUBLE: - return TQT_DBusData::fromDouble(qIterGet(it)); - case DBUS_TYPE_STRING: - case DBUS_TYPE_SIGNATURE: - return TQT_DBusData::fromString(TQString::fromUtf8(qIterGet(it))); - case DBUS_TYPE_OBJECT_PATH: - return TQT_DBusData::fromObjectPath(TQT_DBusObjectPath(qIterGet(it))); - case DBUS_TYPE_ARRAY: { - int arrayType = dbus_message_iter_get_element_type(it); - - char* sig = dbus_message_iter_get_signature(it); - TQCString signature = sig; - dbus_free(sig); - - TQValueList prototypeList = parseSignature(signature); - - if (arrayType == DBUS_TYPE_DICT_ENTRY) { - DBusMessageIter sub; - dbus_message_iter_recurse(it, &sub); - - return qFetchMap(&sub, prototypeList[0]); - } else { - TQT_DBusDataList list = prototypeList[0].toList(); - - DBusMessageIter arrayIt; - dbus_message_iter_recurse(it, &arrayIt); - - while (dbus_message_iter_get_arg_type(&arrayIt) != DBUS_TYPE_INVALID) { - list << qFetchParameter(&arrayIt); - - dbus_message_iter_next(&arrayIt); - } - - return TQT_DBusData::fromList(list); - } - } - case DBUS_TYPE_VARIANT: { - TQT_DBusVariant dvariant; - DBusMessageIter sub; - dbus_message_iter_recurse(it, &sub); - - char* signature = dbus_message_iter_get_signature(&sub); - dvariant.signature = TQString::fromUtf8(signature); - dbus_free(signature); - - dvariant.value = qFetchParameter(&sub); - - return TQT_DBusData::fromVariant(dvariant); - } - case DBUS_TYPE_STRUCT: { - TQValueList memberList; - - DBusMessageIter subIt; - dbus_message_iter_recurse(it, &subIt); - - uint index = 0; - while (dbus_message_iter_get_arg_type(&subIt) != DBUS_TYPE_INVALID) { - memberList << qFetchParameter(&subIt); - - dbus_message_iter_next(&subIt); - ++index; - } - - return TQT_DBusData::fromStruct(memberList); - } - case DBUS_TYPE_UNIX_FD: { - TQT_DBusUnixFd unixFd; - unixFd.giveFileDescriptor(qIterGet(it)); - return TQT_DBusData::fromUnixFd(unixFd); - } -#if 0 - case DBUS_TYPE_INVALID: - // TODO: check if there is better way to detect empty arrays - return TQT_DBusData(); - break; -#endif - default: - tqWarning("TQT_DBusMarshall: Don't know how to de-marshall type %d '%c'", - dbus_message_iter_get_arg_type(it), - dbus_message_iter_get_arg_type(it)); - return TQT_DBusData(); - break; - } -} - -void TQT_DBusMarshall::messageToList(TQValueList& list, DBusMessage* message) -{ - Q_ASSERT(message); - - DBusMessageIter it; - if (!dbus_message_iter_init(message, &it)) return; - - do - { - list << qFetchParameter(&it); - } - while (dbus_message_iter_next(&it)); -} - -static void tqAppendToMessage(DBusMessageIter *it, const TQString &str) -{ - TQByteArray ba = str.utf8(); - const char *cdata = ba.data(); - dbus_message_iter_append_basic(it, DBUS_TYPE_STRING, &cdata); -} - -static void tqAppendToMessage(DBusMessageIter *it, const TQT_DBusObjectPath &path) -{ - const char *cdata = path.data(); - dbus_message_iter_append_basic(it, DBUS_TYPE_OBJECT_PATH, &cdata); -} - -static void tqAppendToMessage(DBusMessageIter *it, const TQT_DBusUnixFd &unixFd) -{ - const dbus_int32_t cdata = unixFd.fileDescriptor(); - dbus_message_iter_append_basic(it, DBUS_TYPE_UNIX_FD, &cdata); -} - -static const char* qDBusTypeForTQT_DBusType(TQT_DBusData::Type type) -{ - switch (type) - { - case TQT_DBusData::Invalid: - return 0; - - case TQT_DBusData::Bool: - return DBUS_TYPE_BOOLEAN_AS_STRING; - - case TQT_DBusData::Byte: - return DBUS_TYPE_BYTE_AS_STRING; - - case TQT_DBusData::Int16: - return DBUS_TYPE_INT16_AS_STRING; - - case TQT_DBusData::UInt16: - return DBUS_TYPE_UINT16_AS_STRING; - - case TQT_DBusData::Int32: - return DBUS_TYPE_INT32_AS_STRING; - - case TQT_DBusData::UInt32: - return DBUS_TYPE_UINT32_AS_STRING; - - case TQT_DBusData::Int64: - return DBUS_TYPE_INT64_AS_STRING; - - case TQT_DBusData::UInt64: - return DBUS_TYPE_UINT64_AS_STRING; - - case TQT_DBusData::Double: - return DBUS_TYPE_DOUBLE_AS_STRING; - - case TQT_DBusData::String: - return DBUS_TYPE_STRING_AS_STRING; - - case TQT_DBusData::ObjectPath: - return DBUS_TYPE_OBJECT_PATH_AS_STRING; - - case TQT_DBusData::List: - return DBUS_TYPE_ARRAY_AS_STRING; - - case TQT_DBusData::Struct: - return DBUS_TYPE_STRUCT_AS_STRING; - - case TQT_DBusData::Variant: - return DBUS_TYPE_VARIANT_AS_STRING; - - case TQT_DBusData::Map: - return DBUS_TYPE_DICT_ENTRY_AS_STRING; - - case TQT_DBusData::UnixFd: - return DBUS_TYPE_UNIX_FD_AS_STRING; - } - return 0; -} - -static void qDBusDataToIterator(DBusMessageIter* it, const TQT_DBusData& var); - -static void qDBusByteKeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toByteKeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - dbus_message_iter_append_basic(it, DBUS_TYPE_BYTE, &(mit.key())); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusInt16KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toInt16KeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - dbus_message_iter_append_basic(it, DBUS_TYPE_INT16, &(mit.key())); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusUInt16KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toUInt16KeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - dbus_message_iter_append_basic(it, DBUS_TYPE_UINT16, &(mit.key())); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusInt32KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toInt32KeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - dbus_message_iter_append_basic(it, DBUS_TYPE_INT32, &(mit.key())); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusUInt32KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toUInt32KeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - dbus_message_iter_append_basic(it, DBUS_TYPE_UINT32, &(mit.key())); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusInt64KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toInt64KeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - dbus_message_iter_append_basic(it, DBUS_TYPE_INT64, &(mit.key())); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusUInt64KeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toUInt64KeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - dbus_message_iter_append_basic(it, DBUS_TYPE_UINT64, &(mit.key())); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusStringKeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toStringKeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - tqAppendToMessage(&itemIterator, mit.key()); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusObjectPathKeyMapToIterator(DBusMessageIter* it, - const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toObjectPathKeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - tqAppendToMessage(&itemIterator, mit.key()); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusUnixFdKeyMapToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - DBusMessageIter sub; - TQCString sig; - - TQT_DBusDataMap map = var.toUnixFdKeyMap(); - - sig += DBUS_DICT_ENTRY_BEGIN_CHAR; - sig += qDBusTypeForTQT_DBusType(map.keyType()); - - if (map.hasContainerValueType()) - sig += map.containerValueType().buildDBusSignature(); - else - sig += qDBusTypeForTQT_DBusType(map.valueType()); - sig += DBUS_DICT_ENTRY_END_CHAR; - - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.data(), &sub); - - TQT_DBusDataMap::const_iterator mit = map.begin(); - for (; mit != map.end(); ++mit) - { - DBusMessageIter itemIterator; - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, - 0, &itemIterator); - - dbus_message_iter_append_basic(it, DBUS_TYPE_UNIX_FD, &(mit.key())); - qDBusDataToIterator(&itemIterator, mit.data()); - - dbus_message_iter_close_container(&sub, &itemIterator); - } - - dbus_message_iter_close_container(it, &sub); -} - -static void qDBusDataToIterator(DBusMessageIter* it, const TQT_DBusData& var) -{ - switch (var.type()) - { - case TQT_DBusData::Bool: - { - dbus_bool_t value = var.toBool(); - dbus_message_iter_append_basic(it, DBUS_TYPE_BOOLEAN, &value); - break; - } - case TQT_DBusData::Byte: - { - TQ_UINT8 value = var.toByte(); - dbus_message_iter_append_basic(it, DBUS_TYPE_BYTE, &value); - break; - } - case TQT_DBusData::Int16: { - TQ_INT16 value = var.toInt16(); - dbus_message_iter_append_basic(it, DBUS_TYPE_INT16, &value); - break; - } - case TQT_DBusData::UInt16: { - TQ_UINT16 value = var.toUInt16(); - dbus_message_iter_append_basic(it, DBUS_TYPE_UINT16, &value); - break; - } - case TQT_DBusData::Int32: { - TQ_INT32 value = var.toInt32(); - dbus_message_iter_append_basic(it, DBUS_TYPE_INT32, &value); - break; - } - case TQT_DBusData::UInt32: { - TQ_UINT32 value = var.toUInt32(); - dbus_message_iter_append_basic(it, DBUS_TYPE_UINT32, &value); - break; - } - case TQT_DBusData::Int64: { - TQ_INT64 value = var.toInt64(); - dbus_message_iter_append_basic(it, DBUS_TYPE_INT64, &value); - break; - } - case TQT_DBusData::UInt64: { - TQ_UINT64 value = var.toUInt64(); - dbus_message_iter_append_basic(it, DBUS_TYPE_UINT64, &value); - break; - } - case TQT_DBusData::Double: { - double value = var.toDouble(); - dbus_message_iter_append_basic(it, DBUS_TYPE_DOUBLE, &value); - break; - } - case TQT_DBusData::String: - tqAppendToMessage(it, var.toString()); - break; - case TQT_DBusData::ObjectPath: - tqAppendToMessage(it, var.toObjectPath()); - break; - case TQT_DBusData::UnixFd: { - tqAppendToMessage(it, var.toUnixFd()); - break; - } - case TQT_DBusData::List: { - TQT_DBusDataList list = var.toList(); - - TQCString signature = 0; - if (list.hasContainerItemType()) - signature = list.containerItemType().buildDBusSignature(); - else - signature = qDBusTypeForTQT_DBusType(list.type()); - - DBusMessageIter sub; - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, - signature.data(), &sub); - - const TQValueList valueList = var.toTQValueList(); - TQValueList::const_iterator listIt = valueList.begin(); - TQValueList::const_iterator listEndIt = valueList.end(); - for (; listIt != listEndIt; ++listIt) - { - qDBusDataToIterator(&sub, *listIt); - } - dbus_message_iter_close_container(it, &sub); - break; - } - case TQT_DBusData::Map: { - switch (var.keyType()) { - case TQT_DBusData::Byte: - qDBusByteKeyMapToIterator(it, var); - break; - case TQT_DBusData::Int16: - qDBusInt16KeyMapToIterator(it, var); - break; - case TQT_DBusData::UInt16: - qDBusUInt16KeyMapToIterator(it, var); - break; - case TQT_DBusData::Int32: - qDBusInt32KeyMapToIterator(it, var); - break; - case TQT_DBusData::UInt32: - qDBusUInt32KeyMapToIterator(it, var); - break; - case TQT_DBusData::Int64: - qDBusInt64KeyMapToIterator(it, var); - break; - case TQT_DBusData::UInt64: - qDBusUInt64KeyMapToIterator(it, var); - break; - case TQT_DBusData::String: - qDBusStringKeyMapToIterator(it, var); - break; - case TQT_DBusData::ObjectPath: - qDBusObjectPathKeyMapToIterator(it, var); - break; - case TQT_DBusData::UnixFd: - qDBusUnixFdKeyMapToIterator(it, var); - break; - default: - tqWarning("TQT_DBusMarshall: unhandled map key type %s " - "at marshalling", - TQT_DBusData::typeName(var.keyType())); - break; - } - break; - } - case TQT_DBusData::Variant: { - TQT_DBusVariant variant = var.toVariant(); - if (variant.signature.isEmpty() || !variant.value.isValid()) break; - - DBusMessageIter sub; - dbus_message_iter_open_container(it, DBUS_TYPE_VARIANT, - variant.signature.utf8(), &sub); - - qDBusDataToIterator(&sub, variant.value); - - dbus_message_iter_close_container(it, &sub); - break; - } - case TQT_DBusData::Struct: { - TQValueList memberList = var.toStruct(); - if (memberList.isEmpty()) break; - - DBusMessageIter sub; - dbus_message_iter_open_container(it, DBUS_TYPE_STRUCT, NULL, &sub); - - TQValueList::const_iterator memberIt = memberList.begin(); - TQValueList::const_iterator memberEndIt = memberList.end(); - for (; memberIt != memberEndIt; ++memberIt) - { - qDBusDataToIterator(&sub, *memberIt); - } - - dbus_message_iter_close_container(it, &sub); - } -#if 0 - case TQVariant::ByteArray: { - const TQByteArray array = var.toByteArray(); - const char* cdata = array.data(); - DBusMessageIter sub; - dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &sub); - dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &cdata, array.size()); - dbus_message_iter_close_container(it, &sub); - break; - } -#endif - default: - //tqWarning("Don't know how to handle type %s", var.typeName()); - break; - } -} - -void qListToIterator(DBusMessageIter* it, const TQValueList& list) -{ - if (list.isEmpty()) return; - - TQValueList::const_iterator listIt = list.begin(); - TQValueList::const_iterator listEndIt = list.end(); - for (; listIt != listEndIt; ++listIt) - { - qDBusDataToIterator(it, *listIt); - } -} - -void TQT_DBusMarshall::listToMessage(const TQValueList &list, DBusMessage *msg) -{ - Q_ASSERT(msg); - DBusMessageIter it; - dbus_message_iter_init_append(msg, &it); - qListToIterator(&it, list); -} diff --git a/tqdbusmarshall.h b/tqdbusmarshall.h deleted file mode 100644 index 6c41587..0000000 --- a/tqdbusmarshall.h +++ /dev/null @@ -1,40 +0,0 @@ -/* qdbusmarshall.h TQT_DBusMarshall object - * - * Copyright (C) 2005 Harald Fernengel - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSMARSHALL_H -#define TQDBUSMARSHALL_H - -struct DBusMessage; - -class TQT_DBusData; - -template class TQValueList; - -class TQT_DBusMarshall -{ -public: - static void listToMessage(const TQValueList &list, DBusMessage* message); - static void messageToList(TQValueList& list, DBusMessage* message); -}; - -#endif diff --git a/tqdbusmessage.cpp b/tqdbusmessage.cpp deleted file mode 100644 index 455e549..0000000 --- a/tqdbusmessage.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* qdbusmessage.cpp - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2005 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include "tqdbusmessage.h" - -#include - -#include - -#include "tqdbusmarshall.h" -#include "tqdbusmessage_p.h" - -TQT_DBusMessagePrivate::TQT_DBusMessagePrivate(TQT_DBusMessage *qq) - : msg(0), reply(0), q(qq), type(DBUS_MESSAGE_TYPE_INVALID), timeout(-1), ref(1) -{ -} - -TQT_DBusMessagePrivate::~TQT_DBusMessagePrivate() -{ - if (msg) - dbus_message_unref(msg); - if (reply) - dbus_message_unref(reply); -} - -/////////////// - - -TQT_DBusMessage TQT_DBusMessage::signal(const TQString &path, const TQString &interface, - const TQString &member) -{ - TQT_DBusMessage message; - message.d->type = DBUS_MESSAGE_TYPE_SIGNAL; - message.d->path = path; - message.d->interface = interface; - message.d->member = member; - - return message; -} - -TQT_DBusMessage TQT_DBusMessage::methodCall(const TQString &service, const TQString &path, - const TQString &interface, const TQString &method) -{ - TQT_DBusMessage message; - message.d->type = DBUS_MESSAGE_TYPE_METHOD_CALL; - message.d->service = service; - message.d->path = path; - message.d->interface = interface; - message.d->member = method; - - return message; -} - -TQT_DBusMessage TQT_DBusMessage::methodReply(const TQT_DBusMessage &other) -{ - Q_ASSERT(other.d->msg); - - TQT_DBusMessage message; - message.d->type = DBUS_MESSAGE_TYPE_METHOD_RETURN; - message.d->reply = dbus_message_ref(other.d->msg); - - return message; -} - -TQT_DBusMessage TQT_DBusMessage::methodError(const TQT_DBusMessage &other, const TQT_DBusError& error) -{ - Q_ASSERT(other.d->msg); - - TQT_DBusMessage message; - if (!error.isValid()) - { - tqWarning("TQT_DBusMessage: error passed to methodError() is not valid!"); - return message; - } - - message.d->type = DBUS_MESSAGE_TYPE_ERROR; - message.d->reply = dbus_message_ref(other.d->msg); - message.d->error = error; - - return message; -} - -TQT_DBusMessage::TQT_DBusMessage() -{ - d = new TQT_DBusMessagePrivate(this); -} - -TQT_DBusMessage::TQT_DBusMessage(const TQT_DBusMessage &other) - : TQValueList(other) -{ - d = other.d; - d->ref.ref(); -} - -TQT_DBusMessage::~TQT_DBusMessage() -{ - if (!d->ref.deref()) - delete d; -} - -TQT_DBusMessage &TQT_DBusMessage::operator=(const TQT_DBusMessage &other) -{ - TQValueList::operator=(other); - // FIXME-QT4 qAtomicAssign(d, other.d); - if (other.d) other.d->ref.ref(); - TQT_DBusMessagePrivate* old = d; - d = other.d; - if (old && !old->ref.deref()) - delete old; - return *this; -} - -DBusMessage *TQT_DBusMessage::toDBusMessage() const -{ - DBusMessage *msg = 0; - switch (d->type) { - case DBUS_MESSAGE_TYPE_METHOD_CALL: - msg = dbus_message_new_method_call(d->service.utf8().data(), - d->path.utf8().data(), d->interface.utf8().data(), - d->member.utf8().data()); - break; - case DBUS_MESSAGE_TYPE_SIGNAL: - msg = dbus_message_new_signal(d->path.utf8().data(), - d->interface.utf8().data(), d->member.utf8().data()); - break; - case DBUS_MESSAGE_TYPE_METHOD_RETURN: - msg = dbus_message_new_method_return(d->reply); - break; - case DBUS_MESSAGE_TYPE_ERROR: - msg = dbus_message_new_error(d->reply, d->error.name().utf8().data(), - d->error.message().utf8().data()); - break; - } - if (!msg) - return 0; - - TQT_DBusMarshall::listToMessage(*this, msg); - return msg; -} - -TQT_DBusMessage TQT_DBusMessage::fromDBusMessage(DBusMessage *dmsg) -{ - TQT_DBusMessage message; - if (!dmsg) - return message; - - message.d->type = dbus_message_get_type(dmsg); - message.d->path = TQString::fromUtf8(dbus_message_get_path(dmsg)); - message.d->interface = TQString::fromUtf8(dbus_message_get_interface(dmsg)); - message.d->member = TQString::fromUtf8(dbus_message_get_member(dmsg)); - message.d->sender = TQString::fromUtf8(dbus_message_get_sender(dmsg)); - message.d->msg = dbus_message_ref(dmsg); - - DBusError dbusError; - dbus_error_init(&dbusError); - if (dbus_set_error_from_message(&dbusError, dmsg)) - { - message.d->error = TQT_DBusError(&dbusError); - } - - TQT_DBusMarshall::messageToList(message, dmsg); - - return message; -} - -TQString TQT_DBusMessage::path() const -{ - return d->path; -} - -TQString TQT_DBusMessage::interface() const -{ - return d->interface; -} - -TQString TQT_DBusMessage::member() const -{ - return d->member; -} - -TQString TQT_DBusMessage::sender() const -{ - return d->sender; -} - -TQT_DBusError TQT_DBusMessage::error() const -{ - return d->error; -} - -int TQT_DBusMessage::timeout() const -{ - return d->timeout; -} - -void TQT_DBusMessage::setTimeout(int ms) -{ - d->timeout = ms; -} - -/*! - Returns the unique serial number assigned to this message - or 0 if the message was not sent yet. - */ -int TQT_DBusMessage::serialNumber() const -{ - if (!d->msg) - return 0; - return dbus_message_get_serial(d->msg); -} - -/*! - Returns the unique serial number assigned to the message - that triggered this reply message. - - If this message is not a reply to another message, 0 - is returned. - - */ -int TQT_DBusMessage::replySerialNumber() const -{ - if (!d->msg) - return 0; - return dbus_message_get_reply_serial(d->msg); -} - -TQT_DBusMessage::MessageType TQT_DBusMessage::type() const -{ - switch (d->type) { - case DBUS_MESSAGE_TYPE_METHOD_CALL: - return MethodCallMessage; - case DBUS_MESSAGE_TYPE_METHOD_RETURN: - return ReplyMessage; - case DBUS_MESSAGE_TYPE_ERROR: - return ErrorMessage; - case DBUS_MESSAGE_TYPE_SIGNAL: - return SignalMessage; - default: - return InvalidMessage; - } -} - diff --git a/tqdbusmessage.h b/tqdbusmessage.h deleted file mode 100644 index 665a83f..0000000 --- a/tqdbusmessage.h +++ /dev/null @@ -1,514 +0,0 @@ -/* qdbusmessage.h TQT_DBusMessage object - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2005-2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSMESSAGE_H -#define TQDBUSMESSAGE_H - -#include "tqdbusmacros.h" -#include "tqdbusdata.h" - -#include - -#include - -class TQT_DBusError; -class TQT_DBusMessagePrivate; -struct DBusMessage; - -/** - * @brief A message converts and transports data over D-Bus - * - * A TQT_DBusMessage is implicitly shared, similar to a TQString, i.e. copying - * a message creates just a shallow copy. - * - * The TQT_DBusMessage is the TQt3 bindings means of encapsulating data for a - * method call, a method reply or an error. - * - * Data specifying the sender and receipient is directly accessible through - * getter methods, while data, e.g. method parameters or return values, are - * managed as a list of TQT_DBusData. - * - * To create a message suitable for sending use one of the static factory - * methods: - * - signal() for creating a D-Bus signal message - * - * - methodCall() for creating a D-Bus method calls to a service object - * - * - methodReply() for creating a method reply on success - * - * - methodError() for creating a method reply on error - * - * @note for applications that just want to perform method calls and/or receive - * signals, it is usually more convenient to use TQT_DBusProxy instead. - * - * Message sending is achieved through TQT_DBusConnection - * - * Example: - * @code - * TQT_DBusConnection con = TQT_DBusConnection::sessionBus(); - * - * // receipient service is the bus' main interface - * - * TQString service = "org.freedesktop.DBus"; - * TQString path = "/org/freedesktop/DBus"; - * TQString interface = "org.freedesktop.DBus"; - * - * TQT_DBusMessage msg = TQBusMessage::methodCall(service, path, interface, "ListNames"); - * - * TQT_DBusMessage reply = con.sendWithReply(msg); - * - * // awaiting for a message list - * - * if (reply.type() != TQT_DBusMessage::ReplyMessage || reply.count() != 2 || - * reply[0].type() != TQT_DBusData::List) - * { - * // error handling here - * } - * else - * { - * TQStringList list = reply[0].toTQStringList(); - * - * // reply handling here - * } - * @endcode - * - * A service returning such a reply would do something like this - * @code - * bool Service::handleMethodCall(const TQT_DBusMessage& call) - * { - * // checks for correctness, i.e. correct interface, member, - * // would usually haven been placed here - * - * TQStringList result; - * result << "Foo" << "Bar"; - * - * TQT_DBusMessage reply = TQT_DBusMessage::methodReply(call); - * reply << TQT_DBusData::fromList(result); - * - * connection.send(reply); - * - * return true; - * } - * @endcode - */ -class TQDBUS_EXPORT TQT_DBusMessage: public TQValueList -{ - friend class TQT_DBusConnection; -public: - /** - * @brief Anonymous enum for timeout constants - * - * @see timeout() - * @see setTimeout() - */ - enum - { - /** - * Use whatever D-Bus has as default timeout - */ - DefaultTimeout = -1, - - /** - * Use no timeout at all, i.e. wait as long as necessary - */ - NoTimeout = INT_MAX - }; - - /** - * @brief D-Bus message types - * - * A message of a specific type can be created using the respective factory - * method. A message created by the default constructor becomes an - * InvalidMessage - * - * @see type() - * @see signal() - * @see methodCall() - * @see methodReply() - * @see methodError() - */ - enum MessageType - { - /** - * An invalid message cannot be sent over D-Bus. This type serves for - * initializing message variables without requiring a "real" message - */ - InvalidMessage, - - /** - * A message for doing method calls on remote service objects - * - * @see methodCall() - */ - MethodCallMessage, - - /** - * A message for replying to a method call in case of success - * - * @see methodReply() - */ - ReplyMessage, - - /** - * A message for replying to a method call in case of failure - * - * @see methodError() - */ - ErrorMessage, - - /** - * A message for emitting D-Bus signals - * - * @see signal() - */ - SignalMessage - }; - - /** - * @brief Creates an empty and invalid message - * - * To create a message suitable for sending through D-Bus see the factory - * methods signal(), methodCall(), methodReply() and methodError() - * - * @see #InvalidMessage - */ - TQT_DBusMessage(); - - - /** - * @brief Creates a shallow copy of the given message - * - * This instance will become a handle to the same message data the other - * message is using, including #MessageType - * - * @param other the message to copy - */ - TQT_DBusMessage(const TQT_DBusMessage &other); - - /** - * @brief Destroys a message - * - * If this message handle is the last one using this respective message - * content, the message content will be deleted as well - */ - ~TQT_DBusMessage(); - - /** - * @brief Creates a shallow copy of the given message - * - * This instance will become a handle to the same message data the other - * message is usingm including #MessageType - * - * Any content used in this instance will be deleted if this instance was - * the last handle using that content - * - * @param other the message to copy - * - * @return a reference to this instance as required by assignment operator - * semantics - */ - TQT_DBusMessage &operator=(const TQT_DBusMessage &other); - - /** - * @brief Creates a message for sending a D-Bus signal - * - * Sending/emitting a signal over D-Bus requires a message of type - * #SignalMessage as well as the information where it is coming from, i.e. - * which interface of which object is sending it. - * See @ref dbusconventions for recommendations on those parameters. - * - * @param path the object path of the service object - * @param interface the object's interface to which the signal belongs - * @param member the signal's name - * - * @return a message suitable for appending arguments and for sending - * - * @see TQT_DBusConnection::send() - */ - static TQT_DBusMessage signal(const TQString &path, const TQString &interface, - const TQString &member); - - /** - * @brief Creates a message for sending a D-Bus method call - * - * Invoking a method over D-Bus requires a message of type - * #MethodCallMessage as well as the information where it should be sent - * to, e.g which interface of which object in which service. - * See @ref dbusconventions for recommendations on those parameters. - * - * @param service the D-Bus name of the application hosting the service - * object - * @param path the object path of the service object - * @param interface the object's interface to which the method belongs - * @param method the method's name - * - * @return a message suitable for appending arguments and for sending - * - * @see methodReply() - * @see methodError() - * @see TQT_DBusConnection::send() - */ - static TQT_DBusMessage methodCall(const TQString &service, const TQString &path, - const TQString &interface, const TQString &method); - - /** - * @brief Creates a message for replying to a D-Bus method call - * - * Replying to a D-Bus method call in the case of success requires a message - * of type #ReplyMessage as well as the information to which method call it - * is replying to. - * - * @param other the method call message it is replying to - * - * @return a message suitable for appending arguments and for sending - * - * @see methodCall() - * @see methodError() - * @see TQT_DBusConnection::send() - */ - static TQT_DBusMessage methodReply(const TQT_DBusMessage &other); - - /** - * @brief Creates a message for replying to a D-Bus method call - * - * Replying to a D-Bus method call in the case of failure requires a message - * of type #ErrorMessage as well as the information to which method call it - * is replying to and which error occured. - * - * @param other the method call message it is replying to - * @param error the error which occured during during the method call - * - * @return a message suitable for appending arguments and for sending - * - * @see methodCall() - * @see methodReply() - * @see TQT_DBusConnection::send() - */ - static TQT_DBusMessage methodError(const TQT_DBusMessage &other, const TQT_DBusError& error); - - /** - * @brief Returns the message's object path - * - * See section @ref dbusconventions-objectpath for details. - * - * The context of the object path depends on the message type: - * - #SignalMessage: the path of the service object which emits the signal - * - #MethodCallMessage: the path of the service object the call is sent to - * - #ReplyMessage: the path of the object which is replying - * - #ErrorMessage: the path of the object which is replying - * - * @return a non-empty object path or @c TQString() - * - * @see interface() - * @see member() - * @see sender() - */ - TQString path() const; - - /** - * @brief Returns the message's interface name - * - * See section @ref dbusconventions-interfacename for details. - * - * The context of the interface name depends on the message type: - * - #SignalMessage: the name of the interface which emits the signal - * - #MethodCallMessage: the name of the interface the call is sent to - * - #ReplyMessage: the name of the interface to which the method belonged - * - #ErrorMessage: the name of the interface to which the method belonged - * - * @return a non-empty interface name or @c TQString() - * - * @see path() - * @see member() - * @see sender() - */ - TQString interface() const; - - /** - * @brief Returns the message's member name - * - * See section @ref dbusconventions-membername for details. - * - * The context of the member name depends on the message type: - * - #SignalMessage: the name of the emitted signal - * - #MethodCallMessage: the name of the method to call - * - #ReplyMessage: the name of the method which replies - * - #ErrorMessage: the name of the method which replies - * - * @return a non-empty member name or @c TQString() - * - * @see path() - * @see interface() - * @see sender() - */ - TQString member() const; - - /** - * @brief Returns the name of the message sender - * - * The message sender name or address used on the D-Bus message bus - * to refer to the application which sent this message. - * - * See section @ref dbusconventions-servicename for details. - * - * This can either be a unique name as handed out by the bus, see - * TQT_DBusConnection::uniqueName() or a name registered with - * TQT_DBusConnection::requestName() - * - * @return a non-empty D-Bus sender name or @c TQString() - * - * @see path() - * @see interface() - * @see member() - */ - TQString sender() const; - - /** - * @brief Returns the error of an error message - * - * If this message is of type #ErrorMessage, this method can be used - * to retrieve the respective error object - * - * @return the transported error object. Will be empty if this is not an - * error message - * - * @see type() - */ - TQT_DBusError error() const; - - /** - * @brief Returns which kind of message this is - * - * @return the message's type - */ - MessageType type() const; - - /** - * @brief Returns the message's timeout - * - * @return the asynchronous wait timeout in milliseconds - * - * @see setTimeout() - */ - int timeout() const; - - /** - * @brief Sets the message's timeout - * - * The timeout is the number of milliseconds the D-Bus connection will - * wait for the reply of an asynchronous call. - * - * If no reply is received in time, an error message will be delivered to - * the asynchronous reply receiver. - * - * If no timeout is set explicitly, #DefaultTimeout is assumed, which is - * usually the best option - * - * @return the asynchronous wait timeout in milliseconds - * - * @param ms timeout in milliseconds - * - * @see timeout() - * @see #DefaultTimeout - * @see #NoTimeout - */ - void setTimeout(int ms); - - /** - * @brief Returns the message's serial number - * - * The serial number is some kind of short term identifier for messages - * travelling the same connection. - * - * It can be used to associate a reply or error message with a method - * call message. - * - * @return the message's serial number or @c 0 if the message hasn't been - * send yets - * - * @see replySerialNumber() - */ - int serialNumber() const; - - /** - * @brief Returns the message's reply serial number - * - * The reply serial number is the serial number of the method call message - * this message is a reply to. - * - * If this is neither a message of type #ReplyMessage or #ErrorMessage, the - * returned value will be @c 0 - * - * It can be used to associate a reply or error message with a method - * call message. - * - * @return the serial number of the associated method call message or @c 0 - * if this message is not a reply message - * - * @see serialNumber() - * @see methodReply() - * @see methodError() - * @see TQT_DBusConnection::sendWithAsyncReply() - * @see TQT_DBusProxy::sendWithAsyncReply() - */ - int replySerialNumber() const; - -//protected: - /** - * @brief Creates a raw D-Bus message from this TQt3-bindings message - * - * Marshalls data contained in the message's value list into D-Bus data - * format and creates a low level API D-Bus message for it. - * - * @note ownership of the returned message is transferred to the caller, - * i.e. it has to be deleted using dbus_message_unref() - * - * @return a C API D-Bus message or @c 0 if this is an #InvalidMessage - * or marshalling failed - */ - DBusMessage *toDBusMessage() const; - - /** - * @brief Creates a TQt3-bindings message from the given raw D-Bus message - * - * De-marshalls data contained in the message to a list of TQT_DBusData. - * - * @note ownership of the given message is shared between the caller and - * the returned message, i.e. the message as increased the reference - * counter and will still have access to the raw message even if the - * caller "deleted" it using dbus_message_unref() - * - * @param dmsg a C API D-Bus message - * - * @return a TQt3 bindings message. Can be an #InvalidMessage if the given - * message was @c 0 or if de-marshalling failed - */ - static TQT_DBusMessage fromDBusMessage(DBusMessage *dmsg); - -private: - TQT_DBusMessagePrivate *d; -}; - -#endif - diff --git a/tqdbusmessage_p.h b/tqdbusmessage_p.h deleted file mode 100644 index 657460f..0000000 --- a/tqdbusmessage_p.h +++ /dev/null @@ -1,52 +0,0 @@ -/* qdbusmessage.h TQT_DBusMessage private object - * - * Copyright (C) 2005 Harald Fernengel - * Copyright (C) 2005 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSMESSAGE_P_H -#define TQDBUSMESSAGE_P_H - -#include - -#include "tqdbusatomic.h" -#include "tqdbuserror.h" - -struct DBusMessage; - -class TQT_DBusMessagePrivate -{ -public: - TQT_DBusMessagePrivate(TQT_DBusMessage *qq); - ~TQT_DBusMessagePrivate(); - - TQString path, interface, member, service, sender; - TQT_DBusError error; - DBusMessage *msg; - DBusMessage *reply; - TQT_DBusMessage *q; - int type; - int timeout; - // FIXME-QT4 TQAtomic ref; - Atomic ref; -}; - -#endif diff --git a/tqdbusobject.h b/tqdbusobject.h deleted file mode 100644 index aa16750..0000000 --- a/tqdbusobject.h +++ /dev/null @@ -1,372 +0,0 @@ -/* qdbusobject.h DBUS service object interface - * - * Copyright (C) 2005-2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSOBJECT_H -#define TQDBUSOBJECT_H - -/** - * @page dbusservice Providing services over D-Bus - * - * Contents: - * - @ref dbusservice-introduction - * - @ref dbusservice-example - * - @ref dbusservice-requestname - * - @ref dbusservice-registerobjects - * - @ref dbusservice-interfaces - * - * @section dbusservice-introduction Introduction - * - * The TQt3 bindings do not support autogeneration of service objects yet. In - * order to provide interfaces over D-Bus, an application has to implement the - * TQT_DBusObjectBase interface and register an instance of the resulting class - * with the TQT_DBusConnection. - * - * @section dbusservice-example A simple D-Bus client example - * - * @code - * #include ; - * #include ; - * - * class TQStringList; - * - * class TestService : public TQT_DBusObjectBase - * { - * public: - * TestService(const TQT_DBusConnection& connection); - * virtual ~TestService(); - * - * protected: - * virtual bool handleMethodCall(const TQT_DBusMessage& message); - * - * private: - * TQT_DBusConnection m_connection; - * - * private: - * TQStringList sortStrings(const TQStringList& list); - * }; - * @endcode - * @code - * - * #include ; - * - * #include ; - * #include ; - * - * TestService::TestService(const TQT_DBusConnection& connection) : m_connection(connection) - * { - * m_connection.registerObject("/ListSorter", this); - * } - * - * TestService::~TestService() - * { - * m_connection.unregisterObject("/ListSorter"); - * } - * - * // return false to let D-Bus send a standard error message that the method is unknown - * - * bool TestService::handleMethod(const TQT_DBusMessage& message) - * { - * if (message.interface() != "org.example.Sort") return false; - * - * if (message.member() == "Strings") - * { - * // check parameters - * - * if (message.count() != 1 || message[0].type() != TQT_DBusData::List) - * { - * // method signature not what we expected - * - * TQT_DBusError error = TQT_DBusError::stdInvalidArgs( - * "Expected one argument of type array of string"); - * - * TQT_DBusMessage reply = TQT_DBusMessage::methodError(message, error); - * - * // send error - * - * m_connection.send(reply); - * - * // tell D-Bus we did handle the call - * - * return true; - * } - * - * // call implementation - * - * TQStringList result = sortStrings(message[0].toTQStringList()); - * - * // prepare reply - * - * TQT_DBusMessage reply = TQT_DBusMessage::methodReply(message); - * - * reply << TQT_DBusData::fromList(result); - * - * // send reply - * - * m_connection.send(reply); - * - * // tell D-Bus we did handle the call - * - * return true; - * } - * - * return false; - * } - * - * TQStringList TestService::sortStrings(const TQStringList& list) - * { - * TQStringList result = list; - * - * result.sort(); - * - * return result; - * } - * @endcode - * @code - * int main(int argc, char** argv) - * { - * TQApplication app(argc, argv, false); - * - * TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); - * if (!connection.isConnected()) - * tqFatal("Cannot connect to session bus"); - * - * // try to get a specific service name - * if (!connection.requestName("org.example.SortService")) - * { - * tqWarning("Requesting name 'org.example.SortService' failed. " - * "Will only be addressable through unique name '%s'", - * connection.uniqueName().local8Bit().data()); - * } - * else - * { - * tqDebug("Requesting name 'org.example.SortService' successfull"); - * } - * - * TestService service(connection); - * - * return app.exec(); - * } - * @endcode - * - * @section dbusservice-requestname Requesting service name - * - * When an application connects to D-Bus it gets a unique name generated by - * the bus daemon. - * - * However, an application providing service will often want to be reachable - * under a fixed name, like a webserver being reachable through a domain name - * independent from its actual IP address. - * See section @ref dbusconventions-servicename for details on service names. - * - * In order to get such a specific name an application has to request it - * using TQT_DBusConnection::requestName() - * - * The example above request @c "org.example.SortService" but continues with - * the default unique name in the case some other application is currently - * owning that name. - * - * @section dbusservice-registerobjects Registering objects - * - * To make service objects available to other applications on the same - * bus the application has to register the objects instances with the - * connection to the bus using TQT_DBusConnection::registerObject() - * - * Registering means to specify an object path where the object will be - * located, i.e. how it can be unambiguously be addressed in method calls. - * See section @ref dbusconventions-objectpath for details on object paths. - * - * If the applications has introspectable objects it is recommended to - * register an introspectable root object, i.e. using @c "/" as the path, so - * other applications have a common place to start asking for introspection - * data. - * - * In the example above a service object providing sorting services on lists is - * registered on the path @c "/ListSorter" - * - * @section dbusservice-interfaces Service interfaces - * - * D-Bus methods and signals of a service object a grouped into interfaces. - * - * See section @ref dbusconventions-interfacename for details on interface - * naming. - * - * An object can implement any number of interfaces, for example the interface - * for the functionality it wants to provide and a D-Bus standard interface like - * @c "org.freedesktop.DBus.Introspectable" for providing an XML description of - * all its interfaces. - * - * - * The service object of the example above implements just one interface - * @c "org.example.Sort" and its handleMethodCall() explicitly checks all - * received messages and rejects any messsage not sent to this particular - * interface by returning @c false and thus telling the D-Bus layer to - * generate a standard error response. - * - * Multiple interfaces can of course be directly implemented in one C++ class, - * however it might sometimes be wise to delegate calls for different - * interfaces to different implementations: - * @code - * class Interface1 : public TQT_DBusObjectBase - * { - * public: - * Interface1(const TQT_DBusConnection&); - * - * protected: - * virtual bool handleMethodCall(const TQT_DBusMessage&); - * }; - * - * class Interface2 : public TQT_DBusObjectBase - * { - * public: - * Interface2(const TQT_DBusConnection&); - * - * protected: - * virtual bool handleMethodCall(const TQT_DBusMessage&); - * }; - * - * class MultiInterfaceService : public TQT_DBusObjectBase - * { - * public: - * MultiInterfaceService(const TQT_DBusConnection&); - * - * protected: - * virtual bool handleMethodCall(const TQT_DBusMessage&); - * - * private: - * TQMap m_interfaces; - * }; - * - * MultiInterfaceService::MultiInterfaceService(const TQT_DBusConnection& connection) - * { - * m_interfaces.insert("org.example.Interface1", new Interface1(connection)); - * m_interfaces.insert("org.example.Interface2", new Interface2(connection)); - * } - * - * bool MultiInterfaceService::handleMethodCall(const TQT_DBusMessage& message) - * { - * // delegate call to its interface handler - * TQT_DBusObjectBase* handler = m_interfaces[message.interface()]; - * if (handler != 0) - * return delegateMethodCall->(message, handler); - * else - * return false; // no such interface - * } - * @endcode - */ - -/** - * @include example-service.h - * @example example-service.cpp - */ - -#include "tqdbusmacros.h" - -class TQT_DBusMessage; - -/** - * @brief Base interface for D-Bus service objects - * - * In order to register a service object with the TQT_DBusConnection it needs to - * implement the interface specified by this class. - * - * The connection will forward all method calls that have a path equivalent - * to the path the service object was registered with to the object's - * handleMethodCall() method. See TQT_DBusConnection::registerObject() - * - * If for some reason, e.g. the call is not meant for this interface, or the - * method is unknown, the implementation can just return @c false and the - * connection will handle the rest. - * - * See section @ref dbusservice for documentation on how to use TQT_DBusObjectBase - */ -class TQDBUS_EXPORT TQT_DBusObjectBase -{ - friend class TQT_DBusConnectionPrivate; -public: - /** - * @brief Destroys the object - */ - virtual ~TQT_DBusObjectBase() {} - -protected: - /** - * @brief Method call entry point - * - * This method has to be implemented to handle method calls sent to the - * service object. - * An object implementation can handle all its interfaces in one class or - * again forward the method call to interface implementators. - * - * If for some reason, e.g. the call is not meant for this interface, or - * the method is unknown, the implementation can just return @c false and - * the connection will handle the rest. - * - * If an error occurs during the method call, e.g. the number of parameters - * or their types are not what would be expected, the service object - * should reply with a TQT_DBusMessage of type TQT_DBusMessage::ErrorMessage - * which in turn should include the D-Bus error describing the problem. - * See TQT_DBusConnection::send() for sending reply messages. - * - * See TQT_DBusMessage::methodError() and TQT_DBusMessage::methodReply() on - * how to create suitable reply messages for the given method call. - * - * @param message the method call to handle - * - * @return @c true if the message can be handled independent if handling - * resulted in an error. In this case implementations should an - * error reply. Returns @c false only if interface or method are - * unknown - */ - virtual bool handleMethodCall(const TQT_DBusMessage& message) = 0; - - /** - * @brief Delegate a method call to another object - * - * When a service object is built as a collection of separated interface - * class instances, i.e. each interface of the object is implemented in - * its own TQT_DBusObjectBase subclass and the main object just wanst to pass - * on the method calls to the respective interface implementations, it - * can do so by calling this base class method. - * - * Since it is a method of the base class, it can call the otherwise - * protected handleMethodCall() of the interface implementor. - * - * See @ref dbusservice-interfaces for an example. - * - * @param message the method call to delegate - * @param delegate the object which should handle the call instead - * - * @return @c true if the message can be handled independent if handling - * resulted in an error. In this case implementations should an - * error reply. Returns @c false only if interface or method are - * unknown - * - */ - bool delegateMethodCall(const TQT_DBusMessage& message, TQT_DBusObjectBase* delegate) - { - return delegate->handleMethodCall(message); - } -}; - -#endif - diff --git a/tqdbusobjectpath.cpp b/tqdbusobjectpath.cpp deleted file mode 100644 index 0f42860..0000000 --- a/tqdbusobjectpath.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* qdbusobjectpath.cpp DBUS object path data type - * - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include "tqdbusobjectpath.h" - -TQT_DBusObjectPath::TQT_DBusObjectPath() : TQCString() -{ -} - -TQT_DBusObjectPath::TQT_DBusObjectPath(const TQT_DBusObjectPath& other) : TQCString(static_cast(other)) -{ -} - -TQT_DBusObjectPath::TQT_DBusObjectPath(const TQCString& other) : TQCString(static_cast(other)) -{ -} - -TQT_DBusObjectPath::TQT_DBusObjectPath(const TQT_DBusObjectPath& parentNode, - const TQCString& nodeName) - : TQCString(static_cast(parentNode)) -{ - if (parentNode.length() != 1) append("/"); - - append(nodeName); -} - -bool TQT_DBusObjectPath::isValid() const -{ - return (validate(*this) == -1); -} - -TQT_DBusObjectPath TQT_DBusObjectPath::parentNode() const -{ - if (length() == 1) return TQT_DBusObjectPath(); - - int index = findRev('/'); - - if (index == -1) return TQT_DBusObjectPath(); - - if (index == 0) return left(1); - - return left(index); -} - -int TQT_DBusObjectPath::validate(const TQCString& path) -{ - if (path.isEmpty()) return 0; - - if (path[0] != '/') return 0; - - // TODO add additional checks - - uint len = path.length(); - - // only root node allowed to end in slash - if (path[len - 1] == '/' && len > 1) return (len - 1); - - return -1; -} diff --git a/tqdbusobjectpath.h b/tqdbusobjectpath.h deleted file mode 100644 index 7a166c6..0000000 --- a/tqdbusobjectpath.h +++ /dev/null @@ -1,119 +0,0 @@ -/* qdbusobjectpath.h DBUS object path data type - * - * Copyright (C) 2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSOBJECTPATH_H -#define TQDBUSOBJECTPATH_H - -#include -#include "tqdbusmacros.h" - -/** - * @brief Class for representing D-Bus object paths - * - * This data type is necessary to correctly represent object paths in the - * context of D-Bus messages, since normal strings have a different D-Bus - * signature than object paths. - * - * @see @ref dbusconventions-objectpath - */ -class TQDBUS_EXPORT TQT_DBusObjectPath : public TQCString -{ -public: - /** - * @brief Creates an empty and invalid object path - */ - TQT_DBusObjectPath(); - - /** - * @brief Creates copy of the given @p other object path - * - * @param other the object path to copy - */ - TQT_DBusObjectPath(const TQT_DBusObjectPath& other); - - /** - * @brief Creates copy of the given @p other object path - * - * @param other the object path to copy - */ - TQT_DBusObjectPath(const TQCString& other); - - /** - * @brief Creates an object path for an object as a child of the parent node - * - * This is basically like specifying a directory and a file name to create - * the file's full path. - * - * Example: - * @code - * TQT_DBusObjectPath rootNode("/"); // => "/" - * - * TQT_DBusObjectPath childNod(rootNode, "child"); // => "/child" - * - * TQT_DBusObjectPath grandChildNode(childNode, "grandchild"); // => "/child/grandchild" - * @endcode - * - * @param parentNode the object path to create the child on - * @param nodeName the name of the child node - */ - TQT_DBusObjectPath(const TQT_DBusObjectPath& parentNode, const TQCString& nodeName); - - /** - * @brief Returns whether the current content is considered a valid object path - * - * @note Calls validate() to perform a check on the current content - * - * @return \c true if the object's content describe a valid object path, - * otherwise @c false - * - * @see @ref dbusconventions-objectpath - */ - bool isValid() const; - - /** - * @brief Returns the object path of this path's parent node - * - * This is basically like getting the directory of an file path - * - * @return the parent node's object path or an empty and invalid object - * if this is already the root node - */ - TQT_DBusObjectPath parentNode() const; - - /** - * @brief Checks the given string for validity as a D-Bus object path - * - * See section @ref dbusconventions-objectpath for information on object - * path formatting. - * - * @param path the string to check - * - * @return @c -1 if the object path is valid, otherwise the index of the - * first violating character - * - * @see isValid() - */ - static int validate(const TQCString& path); -}; - -#endif diff --git a/tqdbusproxy.cpp b/tqdbusproxy.cpp deleted file mode 100644 index 7ca6118..0000000 --- a/tqdbusproxy.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* qdbusproxy.cpp DBUS Object proxy - * - * Copyright (C) 2005 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include "tqdbuserror.h" -#include "tqdbusconnection.h" -#include "tqdbusmessage.h" -#include "tqdbusproxy.h" - -class TQT_DBusProxy::Private -{ -public: - Private() : canSend(false) {} - ~Private() {} - - void checkCanSend() - { - canSend = !path.isEmpty() && !service.isEmpty() && !interface.isEmpty(); - } - -public: - TQT_DBusConnection connection; - - TQString service; - TQString path; - TQString interface; - bool canSend; - - TQT_DBusError error; -}; - -TQT_DBusProxy::TQT_DBusProxy(TQObject* parent, const char* name) - : TQObject(parent, (name ? name : "TQT_DBusProxy")), - d(new Private()) -{ -} - -TQT_DBusProxy::TQT_DBusProxy(const TQT_DBusConnection& connection, - TQObject* parent, const char* name) - : TQObject(parent, (name ? name : "TQT_DBusProxy")), - d(new Private()) -{ - setConnection(connection); -} - -TQT_DBusProxy::TQT_DBusProxy(const TQString& service, const TQString& path, - const TQString& interface, const TQT_DBusConnection& connection, - TQObject* parent, const char* name) - : TQObject(parent, (name ? name : "TQT_DBusProxy")), - d(new Private()) -{ - setConnection(connection); - - d->service = service; - d->path = path; - d->interface = interface; - d->checkCanSend(); -} - -TQT_DBusProxy::~TQT_DBusProxy() -{ - delete d; -} - -bool TQT_DBusProxy::setConnection(const TQT_DBusConnection& connection) -{ - d->connection.disconnect(this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); - - d->connection = connection; - - return d->connection.connect(this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); -} - -const TQT_DBusConnection& TQT_DBusProxy::connection() const -{ - return d->connection; -} - -void TQT_DBusProxy::setService(const TQString& service) -{ - d->service = service; - d->checkCanSend(); -} - -TQString TQT_DBusProxy::service() const -{ - return d->service; -} - -void TQT_DBusProxy::setPath(const TQString& path) -{ - d->path = path; - d->checkCanSend(); -} - -TQString TQT_DBusProxy::path() const -{ - return d->path; -} - -void TQT_DBusProxy::setInterface(const TQString& interface) -{ - d->interface = interface; - d->checkCanSend(); -} - -TQString TQT_DBusProxy::interface() const -{ - return d->interface; -} - -bool TQT_DBusProxy::canSend() const -{ - return d->canSend && d->connection.isConnected(); -} - -bool TQT_DBusProxy::send(const TQString& method, const TQValueList& params) const -{ - if (!d->canSend || method.isEmpty() || !d->connection.isConnected()) - return false; - - TQT_DBusMessage message = TQT_DBusMessage::methodCall(d->service, d->path, - d->interface, method); - message += params; - - return d->connection.send(message); -} - -TQT_DBusMessage TQT_DBusProxy::sendWithReply(const TQString& method, - const TQValueList& params, - TQT_DBusError* error) const -{ - if (!d->canSend || method.isEmpty() || !d->connection.isConnected()) - return TQT_DBusMessage(); - - TQT_DBusMessage message = TQT_DBusMessage::methodCall(d->service, d->path, - d->interface, method); - message += params; - - TQT_DBusMessage reply = d->connection.sendWithReply(message, &d->error); - - if (error) - *error = d->error; - - return reply; -} - -int TQT_DBusProxy::sendWithAsyncReply(const TQString& method, const TQValueList& params) -{ - if (!d->canSend || method.isEmpty() || !d->connection.isConnected()) - return 0; - - TQT_DBusMessage message = TQT_DBusMessage::methodCall(d->service, d->path, - d->interface, method); - message += params; - - return d->connection.sendWithAsyncReply(message, this, - TQT_SLOT(handleAsyncReply(const TQT_DBusMessage&))); -} - -TQT_DBusError TQT_DBusProxy::lastError() const -{ - return d->error; -} - -void TQT_DBusProxy::handleDBusSignal(const TQT_DBusMessage& message) -{ - if (!d->path.isEmpty() && d->path != message.path()) - return; - - // only filter by service name if the name is a unique name - // because signals are always coming from a connection's unique name - // and filtering by a generic name would reject all signals - if (d->service.startsWith(":") && d->service != message.sender()) - return; - - if (!d->interface.isEmpty() && d->interface != message.interface()) - return; - - emit dbusSignal(message); -} - -void TQT_DBusProxy::handleAsyncReply(const TQT_DBusMessage& message) -{ - d->error = message.error(); - - emit asyncReply(message.replySerialNumber(), message); -} - -#include "tqdbusproxy.moc" diff --git a/tqdbusproxy.h b/tqdbusproxy.h deleted file mode 100644 index 8d594cd..0000000 --- a/tqdbusproxy.h +++ /dev/null @@ -1,585 +0,0 @@ -/* qdbusproxy.h DBUS Object proxy - * - * Copyright (C) 2005-2007 Kevin Krammer - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSPROXY_H -#define TQDBUSPROXY_H - -/** - * @page dbusclient Using D-Bus as a client - * - * Contents: - * - @ref dbusclient-introduction - * - * - @ref dbusclient-example - * - * - @ref dbusclient-initialization - * - * - @ref dbusclient-methodcall - * - @ref dbusclient-synccall - * - @ref dbusclient-asynccall - * - * - @ref dbusclient-signals - * - @ref dbusclient-signals-example - * - * @section dbusclient-introduction Introduction - * - * While it is of course possible to just exchange D-Bus messages with a - * D-Bus service, it is a lot more comfortable to use TQT_DBusProxy. - * - * With TQT_DBusProxy you only need to specify the service object once, i.e. - * its D-Bus name, path and interface, and just provide the method and its - * parameters when initiating an invokation. - * - * Additionally the proxy transforms D-Bus signals from the proxy's peer - * (the D-Bus service object's interface it is associated with) to TQObject - * signal carrying the original signal's content. - * - * @section dbusclient-example A simple D-Bus client example - * - * @code - * #include - * #include - * #include - * - * int main() - * { - * // establish a connection to the session bus - * - * TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); - * if (!connection.isConnected()) - * tqFatal("Failed to connect to session bus"); - * - * // create a proxy object for method calls - * - * TQT_DBusProxy proxy(connection); - * proxy.setService("org.freedesktop.DBus"); // who we work with - * proxy.setPath("/org/freedesktop/DBus"); // which object inside the peer work with - * proxy.setInterface("org.freedesktop.DBus"); // which of its interfaces we will use - * - * // call the "ListNames" method. It returns an array of string, in TQt3 terms - * // a TQStringList, it expects no parameters - * - * TQValueList params; - * TQT_DBusMessage reply = proxy.sendWithReply("ListNames", params); - * - * if (reply.type() != TQT_DBusMessage::ReplyMessage) - * tqFatal("Call failed"); - * - * if (reply.count() != 1 || reply[0].type() != TQT_DBusData::List) - * tqFatal("Unexpected reply"); - * - * bool ok = false; - * TQStringList names = reply[0].toTQStringList(&ok); - * - * if (!ok) tqFatal("Unexpected reply"); - * - * for (TQStringList::iterator it = names.begin(); it != names.end(); ++it) - * { - * tqDebug("%s", (*it).local8Bit().data()); - * } - * - * return 0; - * } - * @endcode - * - * @section dbusclient-initialization Program initialization - * - * A connection to the bus is acquired using TQT_DBusConnection::sessionBus() - * - * Next, a proxy is created for the object @c "/org/freedesktop/DBus" with - * interface @c "org.freedesktop.DBus" on the service @c "org.freedesktop.DBus" - * - * This is a proxy for the message bus itself. - * - * @section dbusclient-methodcall Method invocation - * - * There are two choices for method invocation: - * - sychronous (blocking) calls - * - asynchronous (non-blocking) calls - * - * @subsection dbusclient-synccall Synchronous method calls - * - * As seen in the example code above, a synchronous method call can be achieved - * by TQT_DBusProxy::sendWithReply(). It sends a method call to the remote object, - * and blocks until reply is received. The outgoing arguments are specified as - * a list of TQT_DBusData. - * - * @subsection dbusclient-asynccall Asynchronous method calls - * - * To invoke a method asynchronously, connect the proxy's signal - * TQT_DBusProxy::asyncReply(int, const TQT_DBusMessage&) to a suitable slot like - * with any other TQt Signal-Slot connection. - * - * Then call TQT_DBusProxy::sendWithAsyncReply() - * It returns a numerical identifier of the call, so it can be related in the - * slot once the result is available. - * - * The slot's first argument is the reveived reply's call identifier as - * returned by the method call. The second parameter is the reply message - * similar to the one in the synchronous call. - * - * @note For asynchronous calls you'll need a running event loop, i.e. a - * TQApplication object and its exec() having been invoked. - * - * @section dbusclient-signals Connecting to D-Bus signals - * - * To receive D-BUS signals just connect to the TQT_DBusProxy's signal - * TQT_DBusProxy::dbusSignal(const TQT_DBusMessage&) - * - * It will be emitted whenever a D-Bus signal message is received from the peer - * object. - * Filtering of signals is based on the value set for @c service, @c path and - * @c interface - * - * @note Filtering for @c service will only happen if @c service is a unique - * D-Bus name, i.e. if it starts with a colon @c ":" since D-Bus signals - * carry the sender's unique name and filtering by a requested name - * would reject all signals - * - * Usually a proxy will be also be used to send to the peer object, thus having - * them all set. However if a proxy is only needed for signals, any of the - * three properties can be omitted (e.g. set to @c TQString() ), in which - * case only the available properties will be checked against the respective - * message field when deciding about dropping or emitting the message. - * See TQT_DBusProxy::handleDBusSignal() - * - * If you want all signal travelling on the bus, or apply filtering for - * different criteria, e.g. get all signals coming from interfaces starting - * with @c "org.", use @c TQT_DBusConnection::connect() instead. - * The signature of the slot stays the same. - * - * @subsection dbusclient-signals-example Signal example - * - * First declare a receiver class: - * @code - * class MyReceiver : public TQObject - * { - * Q_OBJECT - * - * public slots: - * void handleDBusSignal(const TQT_DBusMessage&); - * }; - * @endcode - * Then somewhere else in a source file: - * @code - * TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); - * - * MyReceiver* receiver1 = new MyReceiver(); - * - * connection.connect(receiver1, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); - * @endcode - * @c receiver1 will get all signals on this connection - * - * @code - * TQT_DBusProxy* proxy = new TQT_DBusProxy(connection); - * proxy->setService("org.freedesktop.DBus"); // who we work with - * proxy->setPath("/org/freedesktop/DBus"); // which object inside the peer work with - * proxy->setInterface("org.freedesktop.DBus"); // which of its interfaces we will use - * - * MyReceiver* receiver2 = new MyReceiver(); - * - * TQObject::connect(proxy, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), - * receiver2, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); - * @endcode - * @c receiver2 will only get signals coming from the proxy's peer interface - */ - -/** - * @include example-client.h - * @example example-client.cpp - */ - -#include - -#include "tqdbusmacros.h" - -class TQT_DBusConnection; -class TQT_DBusData; -class TQT_DBusError; -class TQT_DBusMessage; - -template class TQValueList; - -/** - * @brief Client interface to a remote service object - * - * TQT_DBusProxy provides a convenience interface for working with D-Bus services, - * or more precisely, interfaces of D-Bus service objects. - * - * A D-Bus service object is identified through the name of its host application - * on the bus and its path (logical location) within the host application. - * Such a service object can implement any number of interfaces, i.e. groups - * methods and signals, and can create a TQT_DBusProxy instance for every one - * your application needs to work with. - * - * See section @ref dbusclient for documentation on how to use TQT_DBusProxy - */ -class TQDBUS_EXPORT TQT_DBusProxy : public TQObject -{ - Q_OBJECT - -public: - /** - * @brief Creates a proxy without binding it to a service or connection - * - * This basic constructor allows to create a proxy and specify the peer - * object and interface later on. - * - * @param parent TQObject parent - * @param name TQObject name - */ - TQT_DBusProxy(TQObject* parent = 0, const char* name = 0); - - /** - * @brief Creates a proxy on a given connection without binding it to a - * service - * - * Similar to the above constructor, it does not yet specify and details - * about the proxy's peer, but already specifies which connection to work - * on. - * - * This can be useful to monitor all signal on a connection without - * filtering for a specific peer. - * - * @param connection the D-Bus connection to work on - * @param parent TQObject parent - * @param name TQObject name - */ - TQT_DBusProxy(const TQT_DBusConnection& connection, TQObject* parent = 0, - const char* name = 0); - - /** - * @brief Creates a proxy for a given peer on a given connection - * - * This creates a proxy for a specific peer object-interface combination - * It is equvalent to creating an "empty" proxy and calling setConnection(), - * setService(), setPath() and setInterface() manually. - * - * @param service the name the peer's host application uses on the bus - * @param path the peer object's path within its host application - * @param interface the interface to work with - * @param connection the D-Bus connection to work on - * @param parent TQObject parent - * @param name TQObject name - */ - TQT_DBusProxy(const TQString& service, const TQString& path, - const TQString& interface, const TQT_DBusConnection& connection, - TQObject* parent = 0, const char* name = 0); - - /** - * @brief Destroys the proxy instance - */ - virtual ~TQT_DBusProxy(); - - /** - * @brief Sets the D-Bus connection to work on - * - * Disconnects from any previously used connection and connects - * to the new connection's signal distribution. - * If no peer information has been provided at creation time or through - * the other set methods, the instance's signal dbusSignal() will emit - * all signals received on the given connection. - * - * @param connection the D-Bus connection to work on - * - * @return @c true if connecting to the new connection's signal succeeded, - * @c false if it failed, e.g. if the connection is a "null" - * connection - * - * @see connection() - * @see setService() - * @see setPath() - * @see setInterface() - */ - bool setConnection(const TQT_DBusConnection& connection); - - /** - * @brief Returns the currently used D-Bus connection - * - * @see setConnection() - */ - const TQT_DBusConnection& connection() const; - - /** - * @brief Sets the peer's service name - * - * A non-empty service name is required if the proxy is to be used for - * method calls. See section @ref dbusconventions-servicename for details. - * - * If a string other than @c TQString() is set, it will be used to - * filter signals, i.e. a signal received by the proxy will only be emitted - * if the service name matches. - * - * @param service the peer's name on the bus - * - * @see service() - * @see setPath() - * @see setInterface() - */ - void setService(const TQString& service); - - /** - * @brief Returns the peer's service name - * - * @return the peer object's service name - * - * @see setService() - */ - TQString service() const; - - /** - * @brief Sets the peer's object path - * - * A non-empty object path is required if the proxy is to be used for - * method calls. See section @ref dbusconventions-objectpath for details. - * - * If a string other than @c TQString() is set, it will be used to - * filter signals, i.e. a signal received by the proxy will only be emitted - * if the object path matches. - * - * @param path the peer's object path inside its host application - * (logical address) - * - * @see path() - * @see setService() - * @see setInterface() - */ - void setPath(const TQString& path); - - /** - * @brief Returns the peer's object path - * - * @return the peer object's path - * - * @see setPath() - */ - TQString path() const; - - /** - * @brief Sets the name of the peer interface - * - * A non-empty interface name is required if the proxy is to be used for - * method calls. See section @ref dbusconventions-interfacename for - * details. - * - * If a string other than @c TQString() is set, it will be used to - * filter signals, i.e. a signal received by the proxy will only be emitted - * if the interface name matches. - * - * @param interface the peer's interface to work with - * - * @see interface() - * @see setService() - * @see setPath() - */ - void setInterface(const TQString& interface); - - /** - * @brief Returns the name of the peer interface - * - * @return the peer object's interface - * - * @see setInterface() - */ - TQString interface() const; - - /** - * @brief Returns whether the proxy can be used to send method calls - * - * The capabilitly to send method calls depends on having all necessary - * base information: - * - Service name, see setService() - * - Object path, see setPath() - * - Interface, see setInterface() - * - * and a working connection, see setConnection() - * - * @return @c true if method calls can be sent, @c false if any of the three - * base information is missing or if the connection is not connected - * - * @see send() - * @see sendWithReply() - * @see sendWithAsyncReply() - */ - bool canSend() const; - - /** - * @brief Sends a method call to the peer object - * - * This is roughly equivalent to calling a C++ method with no return value - * or like ignoring the it. - * - * @param method the name of the method to invoke - * @param params the method parameters. Use an empty list if the method - * does not require parameters - * - * @return @c true if sending succeeded, @c false if sending failed, - * the method name was empty or any of the conditions for - * successfull sending as described for canSend() are not met - * - * @see lastError() - * @see sendWithReply() - * @see sendWithAsyncReply() - * @see @ref dbusconventions-membername - */ - bool send(const TQString& method, const TQValueList& params) const; - - /** - * @brief Sends a method call to the peer object and waits for the reply - * - * This is roughly equivalent to calling a C++ method on a local object. - * - * @param method the name of the method to invoke - * @param params the method parameters. Use an empty list if the method - * does not require parameters - * @param error optional parameter to get any error directly - * - * @return a TQT_DBusMessage containing any return values of the invoked method. - * Will be an invalid message if an error occurs. The error can be - * accessed through the optional paramater @p error or through - * lastError() - * - * @see canSend() - * @see send() - * @see sendWithAsyncReply() - * @see @ref dbusconventions-membername - */ - TQT_DBusMessage sendWithReply(const TQString& method, - const TQValueList& params, TQT_DBusError* error = 0) const; - - /** - * @brief Sends a method call to the peer object but does not wait for an - * answer - * - * This is roughly equivalent to calling a C++ method on a local TQt - * event loop driven object, where the result of the method call is - * delivered later through a signal. - * - * @note as with TQt's asychronous classes this needs a running event loop - * - * @param method the name of the method to invoke - * @param params the method parameters. Use an empty list if the method - * does not require parameters - * - * @return a serial number to easily identify the reply once it is received - * or 0 if the call is not possible, i.e. the method name is empty - * or any of the conditions for canSend() are not met - * - * @warning if a asynchronous call is followed by a synchronous call, e.g. - * using sendWithReply(), without returning to the event loop, - * is recommended to call TQT_DBusConnection::scheduleDispatch() - * after the synchronous call to make sure any reply received - * during the blocking call is delivered - * - * @see asyncReply() - * @see send() - * @see sendWithReply() - * @see @ref dbusconventions-membername - */ - int sendWithAsyncReply(const TQString& method, const TQValueList& params); - - /** - * @brief Returns the last error seen by the proxy - * - * The last error can a connection error, e.g. sending a message failed due - * connection being lost, or the error of the last call to sendWithReply or - * the error of the last received asyncReply() - * - * @return the last dbus error seen by this proxy - */ - TQT_DBusError lastError() const; - -signals: - /** - * @brief Signal emitted for D-Bus signals from the peer - * - * Signals received on the proxy's connection are filtered by - * handleDBusSignal() for all proxy properties that are not empty. - * - * @param message the signal's content - * - * @see TQT_DBusMessage::SignalMessage - */ - void dbusSignal(const TQT_DBusMessage& message); - - /** - * @brief Signal emitted for received replies to asynchronous method calls - * - * If a method invoked by using sendWithAsyncReply() send a response, e.g. - * method return value or errors, this signal is emitted to notify the - * proxy's user. - * - * @param callID the method call's serial number as returned by - * sendWithAsyncReply() - * @param message the reply's content - * - * @see handleAsyncReply() - * @see TQT_DBusMessage::replySerialNumber() - */ - void asyncReply(int callID, const TQT_DBusMessage& message); - -protected slots: - /** - * @brief Handles D-Bus signals received on the proxy's connection - * - * The base implementation checks each non-empty property, i.e. service - * name, object path and interface, with the respective field of the - * signal's D-Bus message. - * - * If all available matches succeed, the message is emitted by - * dbusSignal(), otherwise it is discarded. - * - * @note Filtering for @c service will only happen if @c service is a - * unique D-Bus name, i.e. if it starts with a colon @c ":" since - * D-Bus signals carry the sender's unique name and filtering by a - * requested name would reject all signals. - * - * @param message the D-Bus signal message as received - * - * @see TQT_DBusMessage::SignalMessage - */ - virtual void handleDBusSignal(const TQT_DBusMessage& message); - - /** - * @brief Handles replies to asynchronous method calls - * - * The base implementation simply extracts the reply's error and makes - * it available for lastError(). It then emits asyncReply() - * - * @param message the D-Bus reply message as received - * - * @see TQT_DBusMessage::replySerialNumber() - */ - virtual void handleAsyncReply(const TQT_DBusMessage& message); - -private: - class Private; - Private* d; - -private: - TQT_DBusProxy(const TQT_DBusProxy&); - TQT_DBusProxy& operator=(const TQT_DBusProxy&); -}; - -#endif - diff --git a/tqdbusserver.cpp b/tqdbusserver.cpp deleted file mode 100644 index 6bad746..0000000 --- a/tqdbusserver.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* qdbusserver.cpp - * - * Copyright (C) 2005 Harald Fernengel - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include "tqdbusserver.h" -#include "tqdbusconnection_p.h" - -TQT_DBusServer::TQT_DBusServer(const TQString &addr, TQObject *parent) - : TQObject(parent) -{ - d = new TQT_DBusConnectionPrivate(this); - - if (addr.isEmpty()) - return; - - d->setServer(dbus_server_listen(addr.utf8().data(), &d->error)); -} - -bool TQT_DBusServer::isConnected() const -{ - return d->server && dbus_server_get_is_connected(d->server); -} - -TQT_DBusError TQT_DBusServer::lastError() const -{ - return d->lastError; -} - -TQString TQT_DBusServer::address() const -{ - TQString addr; - if (d->server) { - char *c = dbus_server_get_address(d->server); - addr = TQString::fromUtf8(c); - dbus_free(c); - } - - return addr; -} - -#include "tqdbusserver.moc" diff --git a/tqdbusserver.h b/tqdbusserver.h deleted file mode 100644 index 0660a87..0000000 --- a/tqdbusserver.h +++ /dev/null @@ -1,53 +0,0 @@ -/* qdbusserver.h TQT_DBusServer object - * - * Copyright (C) 2005 Harald Fernengel - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSSERVER_H -#define TQDBUSSERVER_H - -#include "tqdbusmacros.h" -#include - -class TQString; - -class TQT_DBusConnectionPrivate; -class TQT_DBusError; - - -class TQDBUS_EXPORT TQT_DBusServer: public TQObject -{ - Q_OBJECT - -public: - TQT_DBusServer(const TQString &address, TQObject *parent = 0); - - bool isConnected() const; - TQT_DBusError lastError() const; - TQString address() const; - -private: - TQT_DBusServer(const TQT_DBusServer&); - TQT_DBusServer& operator=(const TQT_DBusServer&); - TQT_DBusConnectionPrivate *d; -}; - -#endif diff --git a/tqdbusunixfd.cpp b/tqdbusunixfd.cpp deleted file mode 100644 index 3aa4ba2..0000000 --- a/tqdbusunixfd.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* tqdbusunixfd.cpp DBUS unix file handle data type - * - * Copyright (C) 2013 Slávek Banko - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#include -#include "tqdbusunixfd.h" - -TQT_DBusUnixFd::TQT_DBusUnixFd() : d(new TQT_DBusUnixFdPrivate()) -{ - d->ref(); - d->fd = -1; -}; - -TQT_DBusUnixFd::TQT_DBusUnixFd(const TQT_DBusUnixFd& other) : d(other.d) -{ - d->ref(); -} - -TQT_DBusUnixFd::TQT_DBusUnixFd(int other) : d(0) -{ - setFileDescriptor(other); -} - -TQT_DBusUnixFd::~TQT_DBusUnixFd() -{ - if (d && d->deref() ) { - if ( isValid() ) { - close(d->fd); - } - delete d; - } -} - -bool TQT_DBusUnixFd::isValid() const -{ - return d ? d->fd != -1 : false; -} - -int TQT_DBusUnixFd::fileDescriptor() const -{ - return d ? d->fd : -1; -} - -void TQT_DBusUnixFd::setFileDescriptor(int fileDescriptor) -{ - giveFileDescriptor(fileDescriptor != -1 ? dup(fileDescriptor) : -1); -} - -void TQT_DBusUnixFd::giveFileDescriptor(int fileDescriptor) -{ - if ( d && d->deref() ) { - if ( isValid() ) { - close(d->fd); - } - } - else { - d = new TQT_DBusUnixFdPrivate; - } - d->ref(); - d->fd = fileDescriptor; -} - -TQT_DBusUnixFd &TQT_DBusUnixFd::operator=( const TQT_DBusUnixFd &other ) -{ - if (other.d) { - other.d->ref(); - } - if ( d && d->deref() ) { - if ( isValid() ) { - close(d->fd); - } - delete d; - } - d = other.d; - return *this; -} diff --git a/tqdbusunixfd.h b/tqdbusunixfd.h deleted file mode 100644 index 9f48a37..0000000 --- a/tqdbusunixfd.h +++ /dev/null @@ -1,150 +0,0 @@ -/* tqdbusunixfd.h DBUS unix file handle data type - * - * Copyright (C) 2013 Slávek Banko - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSUNIXFD_H -#define TQDBUSUNIXFD_H - -#include "dbus/dbus.h" -#ifndef QT_H -#include "ntqshared.h" -#endif // QT_H -#include "tqdbusmacros.h" - - -#ifndef DBUS_TYPE_UNIX_FD -#define DBUS_TYPE_UNIX_FD ((int) 'h') -#endif - -#ifndef DBUS_TYPE_UNIX_FD_AS_STRING -#define DBUS_TYPE_UNIX_FD_AS_STRING "h" -#endif - -/** - * @brief Class for representing D-Bus unix file handles - * - * This data type is necessary to correctly represent unix file handles in the - * context of D-Bus messages, since normal strings have a different D-Bus - * signature than unix file handles. - * - * @see @ref dbusconventions-unixfd - */ -class TQDBUS_EXPORT TQT_DBusUnixFd -{ -public: - /** - * @brief Creates an empty and invalid unix file handle - */ - TQT_DBusUnixFd(); - - /** - * @brief Creates copy of the given @p other unix file handle - * - * @param other the unix file handle to copy - */ - TQT_DBusUnixFd(const TQT_DBusUnixFd& other); - - /** - * @brief Creates copy of the given @p other unix file handle - * - * @param other the unix file handle to copy - */ - TQT_DBusUnixFd(int other); - - /** - * @brief Destroys the unix file handle - */ - virtual ~TQT_DBusUnixFd(); - - /** - * @brief Returns whether the current content is considered a valid unix file handle - * - * @return \c true if the object's content describe a valid unix file handle, - * otherwise @c false - * - * @see @ref dbusconventions-unixfd - */ - bool isValid() const; - - /** - * @brief Get unix file handle - * - * @see @ref dbusconventions-unixfd - */ - int fileDescriptor() const; - - /** - * @brief Set new unix file handle - * - * @see @ref dbusconventions-unixfd - */ - void setFileDescriptor(int fileDescriptor); - - /** - * @brief Give unix file handle - * - * @see @ref dbusconventions-unixfd - */ - void giveFileDescriptor(int fileDescriptor); - - /** - * @brief Copy unix file handle from TQT_DBusUnixFd - * - * @see @ref dbusconventions-unixfd - */ - TQT_DBusUnixFd &operator=( const TQT_DBusUnixFd &other ); - - /** - * @brief Checks if the given @p other variant is equal to this one - * - * @param other unix file handle to compare with - * - * @return @c true if both use same file handle, otherwise - * @c false - */ - inline bool operator==(const TQT_DBusUnixFd& other) const - { - return (&other == this) || (other.d == d); - } - - /** - * @brief Checks if the given @p other variant is not equal to this one - * - * @param other unix file handle to compare with - * - * @return @c true if both use different file handle, otherwise - * @c false - */ - inline bool operator!=(const TQT_DBusUnixFd& other) const - { - return (&other != this) && (other.d != d); - } - - -protected: - struct TQT_DBusUnixFdPrivate : public TQShared { - int fd; - } *d; - -}; - -#endif diff --git a/tqdbusvariant.h b/tqdbusvariant.h deleted file mode 100644 index 11c0ec5..0000000 --- a/tqdbusvariant.h +++ /dev/null @@ -1,120 +0,0 @@ -/* qdbusvariant.h DBUS variant struct - * - * Copyright (C) 2005 Harald Fernengel - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - */ - -#ifndef TQDBUSVARIANT_H -#define TQDBUSVARIANT_H - -#include "tqdbusmacros.h" -#include "tqdbusdata.h" - -#include - -/** - * @brief Data type for representing a D-Bus variant - * - * When D-Bus methods or signal require that a paramater can have any of the - * D-Bus data types, a D-Bus variant can be used. - * - * Basically a D-Bus variant includes the actual data and a D-Bus data signature - * to allow a receiver to determine the contents. - * - * Since the TQT_DBusVariant's #value member will already be fully de-marshalled, - * a receiver using this bindings can savely ignore the signature if it doesn't - * need it for a different purpose (e.g. logging). - * - * However, when creating a TQT_DBusVariant object for sending, make sure the - * #signature member is correctly setup, for example by using the #value - * member's buildDBusSignature() method. - * - * @code - * TQT_DBusVariant variant; - * - * variant.value = TQT_DBusData::fromInt32(131719); - * variant.signature = variant.value.buildDBusSignature(); - * @endcode - */ -class TQDBUS_EXPORT TQT_DBusVariant -{ -public: - /** - * @brief Creates an empty variant object - */ - TQT_DBusVariant() {} - - /** - * @brief Copies the given @p other variant object - * - * @param other the variant object to copy from - */ - TQT_DBusVariant(const TQT_DBusVariant& other) - { - signature = other.signature; - value = other.value; - } - - /** - * @brief Checks if the given @p other variant is equal to this one - * - * @param other the variant object to compare with - * - * @return @c true if both #signature and #value are equal, otherwise - * @c false - */ - inline bool operator==(const TQT_DBusVariant& other) const - { - if (&other == this) return true; - - return signature == other.signature && value == other.value; - } - - /** - * @brief Checks if the given @p other variant is not equal to this one - * - * @param other the variant object to compare with - * - * @return @c true if either #signature or #value is different, otherwise - * @c false - */ - inline bool operator!=(const TQT_DBusVariant& other) const - { - if (&other == this) return false; - - return signature != other.signature || value != other.value; - } - -public: - /** - * @brief The D-Bus data signature of the data contained in #value - * - * @see TQT_DBusData::buildDBusSignature() - */ - TQString signature; - - /** - * @brief The D-Bus data type to transport as a variant - */ - TQT_DBusData value; -}; - -#endif - -- cgit v1.2.1