diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bfb0e4..29c869e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,8 @@ install( FILES tqdbuserror.h tqdbusmessage.h tqdbusconnection.h tqdbusvariant.h tqdbusobject.h tqdbusproxy.h tqdbusmacros.h tqdbusdata.h tqdbusdatalist.h - tqdbusdatamap.h tqdbusobjectpath.h tqdbusdataconverter.h + tqdbusdatamap.h tqdbusobjectpath.h tqdbusunixfd.h + tqdbusdataconverter.h DESTINATION ${INCLUDE_INSTALL_DIR} ) @@ -84,7 +85,8 @@ tde_add_library( dbus-1-tqt SHARED AUTOMOC tqdbusconnection.cpp tqdbuserror.cpp tqdbusintegrator.cpp tqdbusmarshall.cpp tqdbusmessage.cpp tqdbusserver.cpp tqdbusproxy.cpp tqdbusdata.cpp tqdbusdatalist.cpp - tqdbusobjectpath.cpp tqdbusdataconverter.cpp + tqdbusobjectpath.cpp tqdbusunixfd.cpp + tqdbusdataconverter.cpp VERSION 0.0.0 LINK ${TQT_LIBRARIES} ${DBUS_LIBRARIES} DESTINATION ${LIB_INSTALL_DIR} diff --git a/tools/dbusxml2qt3/methodgen.cpp b/tools/dbusxml2qt3/methodgen.cpp index 8fe0741..ad3bc47 100644 --- a/tools/dbusxml2qt3/methodgen.cpp +++ b/tools/dbusxml2qt3/methodgen.cpp @@ -105,6 +105,15 @@ static bool parseDBusSignature(const TQString& signature, Argument& argument) argument.forwardDeclarations.append("class TQT_DBusObjectPath"); argument.sourceIncludes["tqdbus"].append(""); } + else if (signature == "h") + { + argument.signature = "TQT_DBuxUnixFd"; + argument.accessor = "UnixFd"; + argument.isPrimitive = false; + + argument.forwardDeclarations.append("class TQT_DBusUnixFd"); + argument.sourceIncludes["tqdbus"].append(""); + } else if (signature == "v") { argument.signature = "TQT_DBusVariant"; diff --git a/tqdbusdata.cpp b/tqdbusdata.cpp index 26ca154..5a6cfa9 100644 --- a/tqdbusdata.cpp +++ b/tqdbusdata.cpp @@ -27,6 +27,7 @@ #include "tqdbusdatalist.h" #include "tqdbusdatamap.h" #include "tqdbusobjectpath.h" +#include "tqdbusunixfd.h" #include "tqdbusvariant.h" #include @@ -50,6 +51,10 @@ public: 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; @@ -101,6 +106,10 @@ public: 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)); @@ -208,6 +217,9 @@ bool TQT_DBusData::operator==(const TQT_DBusData& other) const case TQT_DBusData::ObjectPath: return toObjectPath() == other.toObjectPath(); + case TQT_DBusData::UnixFd: + return toUnixFd() == other.toUnixFd(); + case TQT_DBusData::List: return toList() == other.toList(); @@ -257,6 +269,10 @@ bool TQT_DBusData::operator==(const TQT_DBusData& other) const toObjectPathKeyMap() == other.toObjectPathKeyMap(); break; + case TQT_DBusData::UnixFd: + toUnixFdKeyMap() == other.toUnixFdKeyMap(); + break; + default: tqFatal("TQT_DBusData operator== unhandled map key type %d(%s)", d->keyType, TQT_DBusData::typeName(d->keyType)); @@ -303,6 +319,7 @@ const char* TQT_DBusData::typeName(Type type) 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"; @@ -568,6 +585,32 @@ TQT_DBusObjectPath TQT_DBusData::toObjectPath(bool* ok) const 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; @@ -885,6 +928,31 @@ TQT_DBusDataMap TQT_DBusData::toObjectPathKeyMap(bool* ok) c 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) @@ -913,6 +981,8 @@ static const char* qDBusTypeForTQT_DBusType(TQT_DBusData::Type type) 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: @@ -1008,6 +1078,10 @@ TQCString TQT_DBusData::buildDBusSignature() const signature += qDBusSignatureForMapValue( *((TQT_DBusDataMap*) d->value.pointer)); break; + case TQT_DBusData::UnixFd: + signature += qDBusSignatureForMapValue( + *((TQT_DBusDataMap*) d->value.pointer)); + break; default: break; } @@ -1052,3 +1126,6 @@ const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::St template <> const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::ObjectPath; + +template <> +const TQT_DBusData::Type TQT_DBusDataMap::m_keyType = TQT_DBusData::UnixFd; diff --git a/tqdbusdata.h b/tqdbusdata.h index b3f5927..ae64706 100644 --- a/tqdbusdata.h +++ b/tqdbusdata.h @@ -31,6 +31,7 @@ class TQCString; class TQT_DBusDataList; class TQT_DBusVariant; class TQT_DBusObjectPath; +class TQT_DBusUnixFd; class TQString; template class TQValueList; @@ -171,6 +172,13 @@ public: */ ObjectPath, + /** + * Type when encapsulating a D-Bus unix file handle. + * + * @see fromUnixFd(), toUnixFd() + */ + UnixFd, + /** * Type when encapsulating a list of values. * @@ -254,6 +262,7 @@ public: * - #UInt64 * - #String * - #ObjectPath + * - #UnixFd * * All values need to be of the same type. * @@ -266,6 +275,7 @@ public: * @see fromUInt64KeyMap(), toUInt64KeyMap() * @see fromStringKeyMap(), toStringKeyMap() * @see fromObjectPathKeyMap(), toObjectPathKeyMap() + * @see fromUnixFdKeyMap(), toUnixFdKeyMap() */ Map }; @@ -684,6 +694,34 @@ public: */ 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 * @@ -1128,6 +1166,41 @@ public: */ 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 * diff --git a/tqdbusdatalist.cpp b/tqdbusdatalist.cpp index ccf9a39..23f60a5 100644 --- a/tqdbusdatalist.cpp +++ b/tqdbusdatalist.cpp @@ -23,6 +23,7 @@ #include "tqdbusdatalist.h" #include "tqdbusobjectpath.h" +#include "tqdbusunixfd.h" #include "tqdbusvariant.h" #include @@ -281,6 +282,21 @@ TQT_DBusDataList::TQT_DBusDataList(const TQValueList& other) } } +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; @@ -725,6 +741,28 @@ TQValueList TQT_DBusDataList::toObjectPathList(bool* ok) con 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) diff --git a/tqdbusdatalist.h b/tqdbusdatalist.h index 7b0432c..b04df0b 100644 --- a/tqdbusdatalist.h +++ b/tqdbusdatalist.h @@ -29,6 +29,7 @@ template class TQValueList; class TQT_DBusObjectPath; class TQT_DBusVariant; +class TQT_DBuxUnixFd; class TQString; class TQStringList; @@ -298,6 +299,20 @@ public: */ 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 */ @@ -717,6 +732,24 @@ public: */ 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_DBuxUnixFd elements or an empty list when converting fails + * + * @see TQT_DBusData::toUnixFd() + */ + TQValueList toUnixFdList(bool* ok = 0) const; + private: class Private; Private* d; diff --git a/tqdbusdatamap.h b/tqdbusdatamap.h index 24908c8..ecb06d2 100644 --- a/tqdbusdatamap.h +++ b/tqdbusdatamap.h @@ -29,6 +29,7 @@ class TQT_DBusData; class TQT_DBusObjectPath; +class TQT_DBusUnixFd; class TQT_DBusVariant; /** @@ -438,6 +439,29 @@ public: } } + /** + * @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 * @@ -1174,6 +1198,41 @@ public: 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 * diff --git a/tqdbusmarshall.cpp b/tqdbusmarshall.cpp index 330e5ac..f4aa5f7 100644 --- a/tqdbusmarshall.cpp +++ b/tqdbusmarshall.cpp @@ -27,6 +27,7 @@ #include "tqdbusdatalist.h" #include "tqdbusdatamap.h" #include "tqdbusobjectpath.h" +#include "tqdbusunixfd.h" #include "tqdbusvariant.h" #include @@ -62,6 +63,7 @@ static TQT_DBusData::Type qSingleTypeForDBusSignature(char signature) 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; @@ -133,6 +135,10 @@ static TQValueList parseSignature(TQCString& signature) 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", @@ -186,6 +192,10 @@ static TQValueList parseSignature(TQCString& signature) 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", @@ -273,6 +283,10 @@ static TQValueList parseSignature(TQCString& signature) 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 " @@ -585,6 +599,8 @@ static TQT_DBusData qFetchParameter(DBusMessageIter *it) return TQT_DBusData::fromStruct(memberList); } + case DBUS_TYPE_UNIX_FD: + return TQT_DBusData::fromUnixFd(TQT_DBusUnixFd(qIterGet(it))); #if 0 case DBUS_TYPE_INVALID: // TODO: check if there is better way to detect empty arrays @@ -627,6 +643,12 @@ static void tqAppendToMessage(DBusMessageIter *it, const TQT_DBusObjectPath &pat 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) @@ -678,6 +700,9 @@ static const char* qDBusTypeForTQT_DBusType(TQT_DBusData::Type type) case TQT_DBusData::Map: return DBUS_TYPE_DICT_ENTRY_AS_STRING; + + case TQT_DBusData::UnixFd: + return DBUS_TYPE_UNIX_FD_AS_STRING; } return 0; } @@ -991,6 +1016,40 @@ static void qDBusObjectPathKeyMapToIterator(DBusMessageIter* it, 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()) @@ -1048,6 +1107,10 @@ static void qDBusDataToIterator(DBusMessageIter* it, const TQT_DBusData& var) 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(); @@ -1100,6 +1163,9 @@ static void qDBusDataToIterator(DBusMessageIter* it, const TQT_DBusData& var) 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", diff --git a/tqdbusunixfd.cpp b/tqdbusunixfd.cpp new file mode 100644 index 0000000..ba7a06c --- /dev/null +++ b/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) +{ + 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 new file mode 100644 index 0000000..f38efc8 --- /dev/null +++ b/tqdbusunixfd.h @@ -0,0 +1,149 @@ +/* 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 + + +#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 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