diff options
author | Matt Vogt <matthew.vogt@jollamobile.com> | 2014-12-23 08:06:04 +1000 |
---|---|---|
committer | Matthew Vogt <matthew.vogt@qinetic.com.au> | 2015-01-05 04:56:51 +0100 |
commit | 6aa227bcf2d34acff67cebf656df40e308221da8 (patch) | |
tree | 7a9b3b74b5921ed76777d0f6c08df86474dc1157 | |
parent | f922e68d080136eafb51f760633d84cd5aedf71d (diff) |
PIM ID local components do not need to be human-readable
The PIM ID objects compose two elements: the URI of the manager that
owns them, and a local component meaningful only to that manager. The
URI is composed from human-readable elements and benefits from a
string representation, but the local element has no requirement on
readability, and can consume less storage by using a binary
representation.
Change-Id: I56d553f6d9debf0486310688006b0be8728c1c90
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Christopher Adams <chris.adams@jollamobile.com>
27 files changed, 461 insertions, 213 deletions
diff --git a/src/contacts/qcontactid.cpp b/src/contacts/qcontactid.cpp index c5ff4bf50..0551de4bf 100644 --- a/src/contacts/qcontactid.cpp +++ b/src/contacts/qcontactid.cpp @@ -73,11 +73,11 @@ QT_BEGIN_NAMESPACE_CONTACTS // TODO: Document and remove internal once the correct signature has been determined /*! - \fn QContactId::QContactId(const QString &managerUri, const QString &localId) + \fn QContactId::QContactId(const QString &managerUri, const QByteArray &localId) \internal Constructs an ID from the supplied manager URI \a managerUri and the engine - specific \a localId string. + specific \a localId value. */ /*! @@ -145,7 +145,7 @@ QT_BEGIN_NAMESPACE_CONTACTS */ /*! - \fn QString QContactId::localId() const + \fn QByteArray QContactId::localId() const Returns the contact's engine specific ID part. @@ -154,14 +154,18 @@ QT_BEGIN_NAMESPACE_CONTACTS /*! Serializes the contact ID to a string. The format of the string will be: - "qtcontacts:managerName:constructionParams:engineLocalItemId". + "qtcontacts:managerName:params:locaId", where localId is encoded binary data + formatted as hexadecimal to ensure it is in a printable form. - \sa fromString() + \sa fromString(), toByteArray() */ QString QContactId::toString() const { - if (!isNull() && QContactManagerData::parseIdString(m_managerUri, 0, 0)) - return QContactManagerData::buildIdString(m_managerUri, m_localId); + if (!isNull()) { + // Ensure the localId component has a valid string representation by hex encoding + const QByteArray encodedLocalId(m_localId.toHex()); + return QString::fromUtf8(QContactManagerData::buildIdData(m_managerUri, encodedLocalId)); + } return QString(); } @@ -170,15 +174,47 @@ QString QContactId::toString() const Deserializes the given \a idString. Returns a default-constructed (null) contact ID if the given \a idString is not a valid, serialized contact ID. - \sa toString() + \sa toString(), fromByteArray() */ QContactId QContactId::fromString(const QString &idString) { QString managerUri; - QString engineIdString; + QByteArray localId; - if (QContactManagerData::parseIdString(idString, 0, 0, &managerUri, &engineIdString)) - return QContactId(managerUri, engineIdString); + if (QContactManagerData::parseIdData(idString.toUtf8(), 0, 0, &managerUri, &localId)) { + // The localId component must be decoded from hex + return QContactId(managerUri, QByteArray::fromHex(localId)); + } + + return QContactId(); +} + +/*! + Serializes the contact ID to a byte array. + + \sa fromByteArray(), toString() +*/ +QByteArray QContactId::toByteArray() const +{ + if (!isNull()) + return QContactManagerData::buildIdData(m_managerUri, m_localId); + + return QByteArray(); +} + +/*! + Deserializes the given \a idData. Returns a default-constructed (null) + contact ID if the given \a idData does not contain a valid, serialized contact ID. + + \sa toByteArray(), fromString() +*/ +QContactId QContactId::fromByteArray(const QByteArray &idData) +{ + QString managerUri; + QByteArray localId; + + if (QContactManagerData::parseIdData(idData, 0, 0, &managerUri, &localId)) + return QContactId(managerUri, localId); return QContactId(); } @@ -190,7 +226,7 @@ QContactId QContactId::fromString(const QString &idString) */ QDebug operator<<(QDebug dbg, const QContactId &id) { - dbg.nospace() << "QContactId(" << id.toString() << ")"; + dbg.nospace() << "QContactId(" << id.toString().toUtf8().constData() << ")"; return dbg.maybeSpace(); } #endif // QT_NO_DEBUG_STREAM @@ -202,7 +238,7 @@ QDebug operator<<(QDebug dbg, const QContactId &id) */ QDataStream& operator<<(QDataStream &out, const QContactId &id) { - out << id.toString(); + out << id.toByteArray(); return out; } @@ -212,9 +248,9 @@ QDataStream& operator<<(QDataStream &out, const QContactId &id) */ QDataStream& operator>>(QDataStream &in, QContactId &id) { - QString idString; - in >> idString; - id = QContactId::fromString(idString); + QByteArray idData; + in >> idData; + id = QContactId::fromByteArray(idData); return in; } #endif // QT_NO_DATASTREAM diff --git a/src/contacts/qcontactid.h b/src/contacts/qcontactid.h index e75ff2e54..c581c374e 100644 --- a/src/contacts/qcontactid.h +++ b/src/contacts/qcontactid.h @@ -54,9 +54,9 @@ class Q_CONTACTS_EXPORT QContactId { public: inline QContactId() {} - inline QContactId(const QString &managerUri, const QString &localId) + inline QContactId(const QString &managerUri, const QByteArray &localId) : m_managerUri(localId.isEmpty() ? QString() : managerUri), - m_localId(m_managerUri.isEmpty() ? QString() : localId) + m_localId(m_managerUri.isEmpty() ? QByteArray() : localId) {} // compiler-generated dtor and copy/move ctors/assignment operators are fine! @@ -68,14 +68,17 @@ public: inline bool isNull() const { return m_localId.isEmpty(); } inline QString managerUri() const { return m_managerUri; } - inline QString localId() const { return m_localId; } + inline QByteArray localId() const { return m_localId; } QString toString() const; static QContactId fromString(const QString &idString); + QByteArray toByteArray() const; + static QContactId fromByteArray(const QByteArray &idData); + private: QString m_managerUri; - QString m_localId; + QByteArray m_localId; }; inline bool operator<(const QContactId &id1, const QContactId &id2) diff --git a/src/contacts/qcontactmanager.cpp b/src/contacts/qcontactmanager.cpp index 88348b445..805d4203f 100644 --- a/src/contacts/qcontactmanager.cpp +++ b/src/contacts/qcontactmanager.cpp @@ -165,7 +165,7 @@ QStringList QContactManager::availableManagers() */ bool QContactManager::parseUri(const QString &uri, QString *managerName, QMap<QString, QString> *params) { - return QContactManagerData::parseIdString(uri, managerName, params); + return QContactManagerData::parseUri(uri, managerName, params, false); } /*! @@ -174,7 +174,7 @@ bool QContactManager::parseUri(const QString &uri, QString *managerName, QMap<QS */ QString QContactManager::buildUri(const QString &managerName, const QMap<QString, QString> ¶ms) { - return QContactManagerData::buildIdString(managerName, params); + return QContactManagerData::buildUri(managerName, params); } /*! diff --git a/src/contacts/qcontactmanager_p.cpp b/src/contacts/qcontactmanager_p.cpp index 4f42e0ac3..51ba5b345 100644 --- a/src/contacts/qcontactmanager_p.cpp +++ b/src/contacts/qcontactmanager_p.cpp @@ -362,6 +362,24 @@ static inline QString escapeParam(const QString ¶m) return ret; } +static inline QByteArray escapeColon(const QByteArray ¶m) +{ + QByteArray ret; + const int len = param.length(); + ret.reserve(len + (len >> 3)); + for (QByteArray::const_iterator it = param.begin(), end = param.end(); it != end; ++it) { + switch (*it) { + case ':': + ret += ":"; + break; + default: + ret += *it; + break; + } + } + return ret; +} + static inline QString unescapeParam(const QString ¶m) { QString ret(param); @@ -373,19 +391,32 @@ static inline QString unescapeParam(const QString ¶m) return ret; } +static inline QByteArray unescapeColon(const QByteArray ¶m) +{ + QByteArray ret(param); + int index = 0; + while ((index = ret.indexOf('&', index)) != -1) { + const QByteArray partial(ret.mid(index, 5)); + if (partial == ":") + ret.replace(index, 5, ":"); + ++index; + } + return ret; +} + /*! - Parses the individual components of the given \a idString and fills the - \a managerName, \a params, \a managerUri and \a engineIdString. + Parses the individual components of the given \a uriString and fills the + \a managerName, \a params and \a managerUri and \a localId. Returns true if the parts could be parsed successfully, false otherwise. */ -bool QContactManagerData::parseIdString(const QString &idString, QString *managerName, QMap<QString, QString> *params, QString *managerUri, QString *engineIdString) +bool QContactManagerData::parseUri(const QString &uriString, QString *managerName, QMap<QString, QString> *params, bool strict) { - // Format: qtcontacts:<managerid>:<key>=<value>&<key>=<value>:<engineIdString> - // we assume that the prefix, managerid, params, and engineIdString cannot contain `:', `=', or `&' - // similarly, that neither param keys nor param values can contain these characters + // Format: qtcontacts:<managerid>:<key>=<value>&<key>=<value> + // we assume that the prefix, managerid, and params cannot contain `:', `=', or `&' + // similarly, that neither param keys nor param values can contain these characters. - const QStringList colonSplit = idString.split(QLatin1Char(':'), QString::KeepEmptyParts); - if (colonSplit.size() < 2 || (engineIdString && colonSplit.size() != 4)) + const QStringList colonSplit = uriString.split(QLatin1Char(':'), QString::KeepEmptyParts); + if ((colonSplit.size() != 3) && (strict || colonSplit.size() != 2)) return false; const QString prefix = colonSplit.at(0); @@ -424,12 +455,54 @@ bool QContactManagerData::parseIdString(const QString &idString, QString *manage if (managerName) *managerName = unescapeParam(mgrName); - if (managerUri) - *managerUri = cachedUri(prefix + QLatin1Char(':') + mgrName + QLatin1Char(':') + paramString); + return true; +} + +/*! + Returns an ID string that describes a manager name and parameters with which to instantiate + a manager object, from the given \a managerName and \a params. + If \a localId is non-null, the generated ID string is suitable for + passing to QContactId::fromString(). +*/ +QString QContactManagerData::buildUri(const QString &managerName, const QMap<QString, QString> ¶ms) +{ + // Format: qtcontacts:<managerid>:<key>=<value>&<key>=<value> + // if the prefix, managerid, param keys, or param values contain `:', `=', or `&', + // we escape them to `:', `&equ;', and `&', respectively. + + QString paramString; + QMap<QString, QString>::const_iterator it = params.constBegin(); + for ( ; it != params.constEnd(); ++it) { + if (it.key().isEmpty()) + continue; + if (!paramString.isEmpty()) + paramString += QLatin1Char('&'); + paramString += escapeParam(it.key()) + QLatin1Char('=') + escapeParam(it.value()); + } + + return QStringLiteral("qtcontacts:") + escapeParam(managerName) + QLatin1Char(':') + paramString; +} - // and unescape the engine id string - if (engineIdString) - *engineIdString = unescapeParam(colonSplit.at(3)); +/*! + Parses the individual components of the given \a idData and fills the + \a managerName, \a params, \a managerUri and \a localId. + Returns true if the parts could be parsed successfully, false otherwise. +*/ +bool QContactManagerData::parseIdData(const QByteArray &idData, QString *managerName, QMap<QString, QString> *params, QString *managerUri, QByteArray *localId) +{ + // Format: <managerUri>:<localId> + int splitIndex = idData.lastIndexOf(':'); + if (splitIndex == -1) + return false; + + const QString uriString(QString::fromUtf8(idData.mid(0, splitIndex))); + if (!parseUri(uriString, managerName, params)) + return false; + + if (managerUri) + *managerUri = uriString; + if (localId) + *localId = unescapeColon(idData.mid(splitIndex + 1)); return true; } @@ -437,46 +510,28 @@ bool QContactManagerData::parseIdString(const QString &idString, QString *manage /*! Returns an ID string that describes a manager name and parameters with which to instantiate a manager object, from the given \a managerUri. - If \a engineIdString is non-null, the generated ID string is suitable for + If \a localId is non-null, the generated ID string is suitable for passing to QContactId::fromString(). */ -QString QContactManagerData::buildIdString(const QString &managerUri, const QString &engineIdString) +QByteArray QContactManagerData::buildIdData(const QString &managerUri, const QByteArray &localId) { - if (!engineIdString.isNull()) - return managerUri + QLatin1Char(':') + escapeParam(engineIdString); - - return managerUri; + // Format: <managerUri>:<localId> + // localId cannot contain ':' so it must be escaped + QByteArray rv = managerUri.toUtf8(); + if (!localId.isEmpty()) + rv.append(':').append(escapeColon(localId)); + return rv; } /*! Returns an ID string that describes a manager name and parameters with which to instantiate a manager object, from the given \a managerName and \a params. - If \a engineIdString is non-null, the generated ID string is suitable for + If \a localId is non-null, the generated ID string is suitable for passing to QContactId::fromString(). */ -QString QContactManagerData::buildIdString(const QString &managerName, const QMap<QString, QString> ¶ms, const QString &engineIdString) +QByteArray QContactManagerData::buildIdData(const QString &managerName, const QMap<QString, QString> ¶ms, const QByteArray &localId) { - // Format: qtcontacts:<managerid>:<key>=<value>&<key>=<value>:<engineIdString> - // if the prefix, managerid, param keys, param values, or engineIdString contain `:', `=', or `&', - // we escape them to `:', `&equ;', and `&', respectively - - QString idString; - - // we have to escape each param - QMap<QString, QString>::const_iterator it = params.constBegin(); - for ( ; it != params.constEnd(); ++it) { - if (it.key().isEmpty()) - continue; - if (!idString.isEmpty()) - idString += QLatin1Char('&'); - idString += escapeParam(it.key()) + QLatin1Char('=') + escapeParam(it.value()); - } - - idString = QStringLiteral("qtcontacts:") + escapeParam(managerName) + QLatin1Char(':') + idString; - if (!engineIdString.isNull()) - idString += QLatin1Char(':') + escapeParam(engineIdString); - - return idString; + return buildIdData(buildUri(managerName, params), localId); } /*! diff --git a/src/contacts/qcontactmanager_p.h b/src/contacts/qcontactmanager_p.h index 457ee158b..30467f78b 100644 --- a/src/contacts/qcontactmanager_p.h +++ b/src/contacts/qcontactmanager_p.h @@ -85,10 +85,13 @@ public: } // helpers - static bool parseIdString(const QString &idString, QString *managerName, QMap<QString, QString> *params, QString *managerUri = 0, QString *engineIdString = 0); + static bool parseUri(const QString &uriString, QString *managerName, QMap<QString, QString> *params, bool strict = true); + static QString buildUri(const QString &managerName, const QMap<QString, QString> ¶ms); - static QString buildIdString(const QString &managerUri, const QString &engineIdString = QString()); - static QString buildIdString(const QString &managerName, const QMap<QString, QString> ¶ms, const QString &engineIdString = QString()); + static bool parseIdData(const QByteArray &idData, QString *managerName, QMap<QString, QString> *params, QString *managerUri = 0, QByteArray *localId = 0); + + static QByteArray buildIdData(const QString &managerUri, const QByteArray &localId = QByteArray()); + static QByteArray buildIdData(const QString &managerName, const QMap<QString, QString> ¶ms, const QByteArray &localId = QByteArray()); static QString cachedUri(const QString &managerUri); diff --git a/src/contacts/qcontactmanagerengine.h b/src/contacts/qcontactmanagerengine.h index 6e993f8df..c438772d7 100644 --- a/src/contacts/qcontactmanagerengine.h +++ b/src/contacts/qcontactmanagerengine.h @@ -75,7 +75,7 @@ public: inline QString managerUri() const { if (m_uri.isNull()) m_uri = QContactManager::buildUri(managerName(), idInterpretationParameters()); return m_uri; } - inline QContactId contactId(const QString &localId) const + inline QContactId contactId(const QByteArray &localId) const { return QContactId(managerUri(), localId); } /* Filtering */ diff --git a/src/organizer/qorganizercollectionid.cpp b/src/organizer/qorganizercollectionid.cpp index b12374ebb..aeed2210a 100644 --- a/src/organizer/qorganizercollectionid.cpp +++ b/src/organizer/qorganizercollectionid.cpp @@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE_ORGANIZER // TODO: Document and remove internal once the correct signature has been determined /*! - \fn QOrganizerCollectionId::QOrganizerCollectionId(const QString &managerUri, const QString &localId) + \fn QOrganizerCollectionId::QOrganizerCollectionId(const QString &managerUri, const QByteArray &localId) \internal Constructs an ID from the supplied manager URI \a managerUri and the engine @@ -145,7 +145,7 @@ QT_BEGIN_NAMESPACE_ORGANIZER */ /*! - \fn QString QOrganizerCollectionId::localId() const + \fn QByteArray QOrganizerCollectionId::localId() const Returns the collection's engine specific ID part. @@ -154,14 +154,18 @@ QT_BEGIN_NAMESPACE_ORGANIZER /*! Serializes the collection ID to a string. The format of the string will be: - "qtorganizer:managerName:constructionParams:engineLocalCollectionId". + "qtorganizer:managerName:params:localId", where localId is encoded binary data + formatted as hexadecimal to ensure it is in a printable form. - \sa fromString() + \sa fromString(), toByteArray() */ QString QOrganizerCollectionId::toString() const { - if (!isNull() && QOrganizerManagerData::parseIdString(m_managerUri, 0, 0)) - return QOrganizerManagerData::buildIdString(m_managerUri, m_localId); + if (!isNull()) { + // Ensure the localId component has a valid string representation by hex encoding + const QByteArray encodedLocalId(m_localId.toHex()); + return QString::fromUtf8(QOrganizerManagerData::buildIdData(m_managerUri, encodedLocalId)); + } return QString(); } @@ -170,15 +174,47 @@ QString QOrganizerCollectionId::toString() const Deserializes the given \a idString. Returns a default-constructed (null) collection ID if the given \a idString is not a valid, serialized collection ID. - \sa toString() + \sa toString(), fromByteArray() */ QOrganizerCollectionId QOrganizerCollectionId::fromString(const QString &idString) { QString managerUri; - QString engineIdString; + QByteArray localId; - if (QOrganizerManagerData::parseIdString(idString, 0, 0, &managerUri, &engineIdString)) - return QOrganizerCollectionId(managerUri, engineIdString); + if (QOrganizerManagerData::parseIdData(idString.toUtf8(), 0, 0, &managerUri, &localId)) { + // The localId component must be decoded from hex + return QOrganizerCollectionId(managerUri, QByteArray::fromHex(localId)); + } + + return QOrganizerCollectionId(); +} + +/*! + Serializes the collection ID to a byte array. + + \sa fromByteArray(), toString() +*/ +QByteArray QOrganizerCollectionId::toByteArray() const +{ + if (!isNull()) + return QOrganizerManagerData::buildIdData(m_managerUri, m_localId); + + return QByteArray(); +} + +/*! + Deserializes the given \a idData. Returns a default-constructed (null) + collection ID if the given \a idData does not contain a valid, serialized collection ID. + + \sa toByteArray(), fromString() +*/ +QOrganizerCollectionId QOrganizerCollectionId::fromByteArray(const QByteArray &idData) +{ + QString managerUri; + QByteArray localId; + + if (QOrganizerManagerData::parseIdData(idData, 0, 0, &managerUri, &localId)) + return QOrganizerCollectionId(managerUri, localId); return QOrganizerCollectionId(); } @@ -190,7 +226,7 @@ QOrganizerCollectionId QOrganizerCollectionId::fromString(const QString &idStrin */ QDebug operator<<(QDebug dbg, const QOrganizerCollectionId &id) { - dbg.nospace() << "QOrganizerCollectionId(" << id.toString() << ")"; + dbg.nospace() << "QOrganizerCollectionId(" << id.toString().toUtf8().constData() << ")"; return dbg.maybeSpace(); } #endif // QT_NO_DEBUG_STREAM @@ -202,7 +238,7 @@ QDebug operator<<(QDebug dbg, const QOrganizerCollectionId &id) */ QDataStream &operator<<(QDataStream &out, const QOrganizerCollectionId &id) { - out << id.toString(); + out << id.toByteArray(); return out; } @@ -212,9 +248,9 @@ QDataStream &operator<<(QDataStream &out, const QOrganizerCollectionId &id) */ QDataStream &operator>>(QDataStream &in, QOrganizerCollectionId &id) { - QString idString; - in >> idString; - id = QOrganizerCollectionId::fromString(idString); + QByteArray idData; + in >> idData; + id = QOrganizerCollectionId::fromByteArray(idData); return in; } #endif // QT_NO_DATASTREAM diff --git a/src/organizer/qorganizercollectionid.h b/src/organizer/qorganizercollectionid.h index 3b4bfd5e8..a9718fa27 100644 --- a/src/organizer/qorganizercollectionid.h +++ b/src/organizer/qorganizercollectionid.h @@ -54,9 +54,9 @@ class Q_ORGANIZER_EXPORT QOrganizerCollectionId { public: inline QOrganizerCollectionId() {} - inline QOrganizerCollectionId(const QString &managerUri, const QString &localId) + inline QOrganizerCollectionId(const QString &managerUri, const QByteArray &localId) : m_managerUri(localId.isEmpty() ? QString() : managerUri), - m_localId(m_managerUri.isEmpty() ? QString() : localId) + m_localId(m_managerUri.isEmpty() ? QByteArray() : localId) {} // compiler-generated dtor and copy/move ctors/assignment operators are fine! @@ -68,14 +68,17 @@ public: inline bool isNull() const { return m_localId.isEmpty(); } inline QString managerUri() const { return m_managerUri; } - inline QString localId() const { return m_localId; } + inline QByteArray localId() const { return m_localId; } QString toString() const; static QOrganizerCollectionId fromString(const QString &idString); + QByteArray toByteArray() const; + static QOrganizerCollectionId fromByteArray(const QByteArray &idData); + private: QString m_managerUri; - QString m_localId; + QByteArray m_localId; }; inline bool operator<(const QOrganizerCollectionId &id1, const QOrganizerCollectionId &id2) diff --git a/src/organizer/qorganizeritemid.cpp b/src/organizer/qorganizeritemid.cpp index 20e780612..e299650a5 100644 --- a/src/organizer/qorganizeritemid.cpp +++ b/src/organizer/qorganizeritemid.cpp @@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE_ORGANIZER // TODO: Document and remove internal once the correct signature has been determined /*! - \fn QOrganizerItemId::QOrganizerItemId(const QString &managerUri, const QString &localId) + \fn QOrganizerItemId::QOrganizerItemId(const QString &managerUri, const QByteArray &localId) \internal Constructs an ID from the supplied manager URI \a managerUri and the engine @@ -145,7 +145,7 @@ QT_BEGIN_NAMESPACE_ORGANIZER */ /*! - \fn QString QOrganizerItemId::localId() const + \fn QByteArray QOrganizerItemId::localId() const Returns the organizer item's engine specific ID part. @@ -154,31 +154,67 @@ QT_BEGIN_NAMESPACE_ORGANIZER /*! Serializes the organizer item ID to a string. The format of the string will be: - "qtorganizer:managerName:constructionParams:engineLocalItemId". + "qtorganizer:managerName:params:localId", where localId is encoded binary data + formatted as hexadecimal to ensure it is in a printable form. - \sa fromString() + \sa fromString(), toByteArray() */ QString QOrganizerItemId::toString() const { - if (!isNull() && QOrganizerManagerData::parseIdString(m_managerUri, 0, 0)) - return QOrganizerManagerData::buildIdString(m_managerUri, m_localId); + if (!isNull()) { + // Ensure the localId component has a valid string representation by hex encoding + const QByteArray encodedLocalId(m_localId.toHex()); + return QString::fromUtf8(QOrganizerManagerData::buildIdData(m_managerUri, encodedLocalId)); + } return QString(); } /*! Deserializes the given \a idString. Returns a default-constructed (null) - organizer item ID if the given \a idString is not a valid, serialized organizer item ID. + item ID if the given \a idString is not a valid, serialized item ID. - \sa toString() + \sa toString(), fromByteArray() */ QOrganizerItemId QOrganizerItemId::fromString(const QString &idString) { QString managerUri; - QString engineIdString; + QByteArray localId; - if (QOrganizerManagerData::parseIdString(idString, 0, 0, &managerUri, &engineIdString)) - return QOrganizerItemId(managerUri, engineIdString); + if (QOrganizerManagerData::parseIdData(idString.toUtf8(), 0, 0, &managerUri, &localId)) { + // The localId component must be decoded from hex + return QOrganizerItemId(managerUri, QByteArray::fromHex(localId)); + } + + return QOrganizerItemId(); +} + +/*! + Serializes the organizer item ID to a byte array. + + \sa fromByteArray(), toString() +*/ +QByteArray QOrganizerItemId::toByteArray() const +{ + if (!isNull()) + return QOrganizerManagerData::buildIdData(m_managerUri, m_localId); + + return QByteArray(); +} + +/*! + Deserializes the given \a idData. Returns a default-constructed (null) + item ID if the given \a idData does not contain a valid, serialized item ID. + + \sa toByteArray(), fromString() +*/ +QOrganizerItemId QOrganizerItemId::fromByteArray(const QByteArray &idData) +{ + QString managerUri; + QByteArray localId; + + if (QOrganizerManagerData::parseIdData(idData, 0, 0, &managerUri, &localId)) + return QOrganizerItemId(managerUri, localId); return QOrganizerItemId(); } @@ -190,7 +226,7 @@ QOrganizerItemId QOrganizerItemId::fromString(const QString &idString) */ Q_ORGANIZER_EXPORT QDebug operator<<(QDebug dbg, const QOrganizerItemId &id) { - dbg.nospace() << "QOrganizerItemId(" << id.toString() << ")"; + dbg.nospace() << "QOrganizerItemId(" << qPrintable(id.toString()) << ")"; return dbg.maybeSpace(); } #endif // QT_NO_DEBUG_STREAM @@ -202,7 +238,7 @@ Q_ORGANIZER_EXPORT QDebug operator<<(QDebug dbg, const QOrganizerItemId &id) */ Q_ORGANIZER_EXPORT QDataStream &operator<<(QDataStream &out, const QOrganizerItemId &id) { - out << id.toString(); + out << id.toByteArray(); return out; } @@ -212,9 +248,9 @@ Q_ORGANIZER_EXPORT QDataStream &operator<<(QDataStream &out, const QOrganizerIte */ Q_ORGANIZER_EXPORT QDataStream &operator>>(QDataStream &in, QOrganizerItemId &id) { - QString idString; - in >> idString; - id = QOrganizerItemId::fromString(idString); + QByteArray idData; + in >> idData; + id = QOrganizerItemId::fromByteArray(idData); return in; } #endif // QT_NO_DATASTREAM diff --git a/src/organizer/qorganizeritemid.h b/src/organizer/qorganizeritemid.h index 8a632758a..f7beb9091 100644 --- a/src/organizer/qorganizeritemid.h +++ b/src/organizer/qorganizeritemid.h @@ -54,9 +54,9 @@ class Q_ORGANIZER_EXPORT QOrganizerItemId { public: inline QOrganizerItemId() {} - inline QOrganizerItemId(const QString &managerUri, const QString &localId) + inline QOrganizerItemId(const QString &managerUri, const QByteArray &localId) : m_managerUri(localId.isEmpty() ? QString() : managerUri), - m_localId(m_managerUri.isEmpty() ? QString() : localId) + m_localId(m_managerUri.isEmpty() ? QByteArray() : localId) {} // compiler-generated dtor and copy/move ctors/assignment operators are fine! @@ -68,14 +68,17 @@ public: inline bool isNull() const { return m_localId.isEmpty(); } inline QString managerUri() const { return m_managerUri; } - inline QString localId() const { return m_localId; } + inline QByteArray localId() const { return m_localId; } QString toString() const; static QOrganizerItemId fromString(const QString &idString); + QByteArray toByteArray() const; + static QOrganizerItemId fromByteArray(const QByteArray &idData); + private: QString m_managerUri; - QString m_localId; + QByteArray m_localId; }; inline bool operator<(const QOrganizerItemId &id1, const QOrganizerItemId &id2) diff --git a/src/organizer/qorganizermanager.cpp b/src/organizer/qorganizermanager.cpp index c9b9ccdf1..79752ed70 100644 --- a/src/organizer/qorganizermanager.cpp +++ b/src/organizer/qorganizermanager.cpp @@ -221,7 +221,7 @@ QStringList QOrganizerManager::availableManagers() */ bool QOrganizerManager::parseUri(const QString &uri, QString *managerName, QMap<QString, QString> *params) { - return QOrganizerManagerData::parseIdString(uri, managerName, params); + return QOrganizerManagerData::parseUri(uri, managerName, params, false); } /*! @@ -230,7 +230,7 @@ bool QOrganizerManager::parseUri(const QString &uri, QString *managerName, QMap< */ QString QOrganizerManager::buildUri(const QString &managerName, const QMap<QString, QString> ¶ms) { - return QOrganizerManagerData::buildIdString(managerName, params); + return QOrganizerManagerData::buildUri(managerName, params); } /*! diff --git a/src/organizer/qorganizermanager_p.cpp b/src/organizer/qorganizermanager_p.cpp index d4cd966ca..5fd9af31d 100644 --- a/src/organizer/qorganizermanager_p.cpp +++ b/src/organizer/qorganizermanager_p.cpp @@ -261,6 +261,24 @@ static inline QString escapeParam(const QString ¶m) return ret; } +static inline QByteArray escapeColon(const QByteArray ¶m) +{ + QByteArray ret; + const int len = param.length(); + ret.reserve(len + (len >> 3)); + for (QByteArray::const_iterator it = param.begin(), end = param.end(); it != end; ++it) { + switch (*it) { + case ':': + ret += ":"; + break; + default: + ret += *it; + break; + } + } + return ret; +} + static inline QString unescapeParam(const QString ¶m) { QString ret(param); @@ -272,19 +290,32 @@ static inline QString unescapeParam(const QString ¶m) return ret; } +static inline QByteArray unescapeColon(const QByteArray ¶m) +{ + QByteArray ret(param); + int index = 0; + while ((index = ret.indexOf('&', index)) != -1) { + const QByteArray partial(ret.mid(index, 5)); + if (partial == ":") + ret.replace(index, 5, ":"); + ++index; + } + return ret; +} + /*! - Parses the individual components of the given \a idString and fills the - \a managerName, \a params, \a managerUri and \a engineIdString. + Parses the individual components of the given \a uriString and fills the + \a managerName, \a params and \a managerUri and \a localId. Returns true if the parts could be parsed successfully, false otherwise. */ -bool QOrganizerManagerData::parseIdString(const QString &idString, QString *managerName, QMap<QString, QString> *params, QString *managerUri, QString *engineIdString) +bool QOrganizerManagerData::parseUri(const QString &uriString, QString *managerName, QMap<QString, QString> *params, bool strict) { - // Format: qtorganizer:<managerid>:<key>=<value>&<key>=<value>:<engineIdString> - // we assume that the prefix, managerid, params, and engineIdString cannot contain `:', `=', or `&' - // similarly, that neither param keys nor param values can contain these characters + // Format: qtorganizer:<managerid>:<key>=<value>&<key>=<value> + // we assume that the prefix, managerid, and params cannot contain `:', `=', or `&' + // similarly, that neither param keys nor param values can contain these characters. - const QStringList colonSplit = idString.split(QLatin1Char(':'), QString::KeepEmptyParts); - if (colonSplit.size() < 2 || (engineIdString && colonSplit.size() != 4)) + const QStringList colonSplit = uriString.split(QLatin1Char(':'), QString::KeepEmptyParts); + if ((colonSplit.size() != 3) && (strict || colonSplit.size() != 2)) return false; const QString prefix = colonSplit.at(0); @@ -323,59 +354,83 @@ bool QOrganizerManagerData::parseIdString(const QString &idString, QString *mana if (managerName) *managerName = unescapeParam(mgrName); - if (managerUri) - *managerUri = cachedUri(prefix + QLatin1Char(':') + mgrName + QLatin1Char(':') + paramString); - - // and unescape the engine id string - if (engineIdString) - *engineIdString = unescapeParam(colonSplit.at(3)); - return true; } /*! Returns an ID string that describes a manager name and parameters with which to instantiate - a manager object, from the given \a managerUri. - If \a engineIdString is non-null, the generated ID string is suitable for + a manager object, from the given \a managerName and \a params. + If \a localId is non-null, the generated ID string is suitable for passing to QOrganizerCollectionId::fromString() or QOrganizerItemId::fromString(). */ -QString QOrganizerManagerData::buildIdString(const QString &managerUri, const QString &engineIdString) +QString QOrganizerManagerData::buildUri(const QString &managerName, const QMap<QString, QString> ¶ms) { - if (!engineIdString.isNull()) - return managerUri + QLatin1Char(':') + escapeParam(engineIdString); + // Format: qtorganizer:<managerid>:<key>=<value>&<key>=<value> + // if the prefix, managerid, param keys, or param values contain `:', `=', or `&', + // we escape them to `:', `&equ;', and `&', respectively. - return managerUri; + QString paramString; + QMap<QString, QString>::const_iterator it = params.constBegin(); + for ( ; it != params.constEnd(); ++it) { + if (it.key().isEmpty()) + continue; + if (!paramString.isEmpty()) + paramString += QLatin1Char('&'); + paramString += escapeParam(it.key()) + QLatin1Char('=') + escapeParam(it.value()); + } + + return QStringLiteral("qtorganizer:") + escapeParam(managerName) + QLatin1Char(':') + paramString; } /*! - Returns a ID string that describes a manager name and parameters with which to instantiate - a manager object, from the given \a managerName and \a params. - If \a engineIdString is non-null, the generated ID string is suitable for - passing to QOrganizerCollectionId::fromString() or QOrganizerItemId::fromString(). + Parses the individual components of the given \a idData and fills the + \a managerName, \a params, \a managerUri and \a localId. + Returns true if the parts could be parsed successfully, false otherwise. */ -QString QOrganizerManagerData::buildIdString(const QString &managerName, const QMap<QString, QString> ¶ms, const QString &engineIdString) +bool QOrganizerManagerData::parseIdData(const QByteArray &idData, QString *managerName, QMap<QString, QString> *params, QString *managerUri, QByteArray *localId) { - // Format: qtorganizer:<managerid>:<key>=<value>&<key>=<value>:<engineIdString> - // if the prefix, managerid, param keys, param values, or engineIdString contain `:', `=', or `&', - // we escape them to `:', `&equ;', and `&', respectively + // Format: <managerUri>:<localId> + int splitIndex = idData.lastIndexOf(':'); + if (splitIndex == -1) + return false; - QString idString; + const QString uriString(QString::fromUtf8(idData.mid(0, splitIndex))); + if (!parseUri(uriString, managerName, params)) + return false; - // we have to escape each param - QMap<QString, QString>::const_iterator it = params.constBegin(); - for ( ; it != params.constEnd(); ++it) { - if (it.key().isEmpty()) - continue; - if (!idString.isEmpty()) - idString += QLatin1Char('&'); - idString += escapeParam(it.key()) + QLatin1Char('=') + escapeParam(it.value()); - } + if (managerUri) + *managerUri = uriString; + if (localId) + *localId = unescapeColon(idData.mid(splitIndex + 1)); - idString = QStringLiteral("qtorganizer:") + escapeParam(managerName) + QLatin1Char(':') + idString; - if (!engineIdString.isNull()) - idString += QLatin1Char(':') + escapeParam(engineIdString); + return true; +} - return idString; +/*! + Returns an ID string that describes a manager name and parameters with which to instantiate + a manager object, from the given \a managerUri. + If \a localId is non-null, the generated ID string is suitable for + passing to QOrganizerCollectionId::fromString() or QOrganizerItemId::fromString(). +*/ +QByteArray QOrganizerManagerData::buildIdData(const QString &managerUri, const QByteArray &localId) +{ + // Format: <managerUri>:<localId> + // localId cannot contain ':' so it must be escaped + QByteArray rv = managerUri.toUtf8(); + if (!localId.isEmpty()) + rv.append(':').append(escapeColon(localId)); + return rv; +} + +/*! + Returns an ID string that describes a manager name and parameters with which to instantiate + a manager object, from the given \a managerName and \a params. + If \a localId is non-null, the generated ID string is suitable for + passing to QOrganizerCollectionId::fromString() or QOrganizerItemId::fromString(). +*/ +QByteArray QOrganizerManagerData::buildIdData(const QString &managerName, const QMap<QString, QString> ¶ms, const QByteArray &localId) +{ + return buildIdData(buildUri(managerName, params), localId); } /*! diff --git a/src/organizer/qorganizermanager_p.h b/src/organizer/qorganizermanager_p.h index 87010375e..5d5cf5fd4 100644 --- a/src/organizer/qorganizermanager_p.h +++ b/src/organizer/qorganizermanager_p.h @@ -80,10 +80,13 @@ public: } // helpers - static bool parseIdString(const QString &idString, QString *managerName, QMap<QString, QString> *params, QString *managerUri = 0, QString *engineIdString = 0); + static bool parseUri(const QString &uriString, QString *managerName, QMap<QString, QString> *params, bool strict = true); + static QString buildUri(const QString &managerName, const QMap<QString, QString> ¶ms); - static QString buildIdString(const QString &managerUri, const QString &engineIdString = QString()); - static QString buildIdString(const QString &managerName, const QMap<QString, QString> ¶ms, const QString &engineIdString = QString()); + static bool parseIdData(const QByteArray &idData, QString *managerName, QMap<QString, QString> *params, QString *managerUri = 0, QByteArray *localId = 0); + + static QByteArray buildIdData(const QString &managerUri, const QByteArray &localId = QByteArray()); + static QByteArray buildIdData(const QString &managerName, const QMap<QString, QString> ¶ms, const QByteArray &localId = QByteArray()); static QString cachedUri(const QString &managerUri); diff --git a/src/organizer/qorganizermanagerengine.cpp b/src/organizer/qorganizermanagerengine.cpp index 32bd476d8..704835412 100644 --- a/src/organizer/qorganizermanagerengine.cpp +++ b/src/organizer/qorganizermanagerengine.cpp @@ -240,14 +240,14 @@ QMap<QString, QString> QOrganizerManagerEngine::idInterpretationParameters() con */ /*! - \fn QOrganizerItemId QOrganizerManagerEngine::itemId(const QString &localId) const + \fn QOrganizerItemId QOrganizerManagerEngine::itemId(const QByteArray &localId) const Returns the organizer item ID for this managerUri() and the given engine specific ID part \a localId. */ /*! - \fn QOrganizerCollectionId QOrganizerManagerEngine::collectionId(const QString &localId) const + \fn QOrganizerCollectionId QOrganizerManagerEngine::collectionId(const QByteArray &localId) const Returns the organizer collection ID for this managerUri() and the given engine specific ID part \a localId. diff --git a/src/organizer/qorganizermanagerengine.h b/src/organizer/qorganizermanagerengine.h index ea4ca6a87..acffaa65b 100644 --- a/src/organizer/qorganizermanagerengine.h +++ b/src/organizer/qorganizermanagerengine.h @@ -74,9 +74,9 @@ public: inline QString managerUri() const { if (m_uri.isNull()) m_uri = QOrganizerManager::buildUri(managerName(), idInterpretationParameters()); return m_uri; } - inline QOrganizerItemId itemId(const QString &localId) const + inline QOrganizerItemId itemId(const QByteArray &localId) const { return QOrganizerItemId(managerUri(), localId); } - inline QOrganizerCollectionId collectionId(const QString &localId) const + inline QOrganizerCollectionId collectionId(const QByteArray &localId) const { return QOrganizerCollectionId(managerUri(), localId); } // items diff --git a/src/plugins/contacts/memory/qcontactmemorybackend.cpp b/src/plugins/contacts/memory/qcontactmemorybackend.cpp index ed13f27cb..d8e698c1d 100644 --- a/src/plugins/contacts/memory/qcontactmemorybackend.cpp +++ b/src/plugins/contacts/memory/qcontactmemorybackend.cpp @@ -908,7 +908,8 @@ bool QContactMemoryEngine::saveContact(QContact *theContact, QContactChangeSet & theContact->saveDetail(&ts); // update the contact item - set its ID - QContactId newContactId = contactId(QString::number(d->m_nextContactId++)); + QContactId newContactId = contactId(QByteArray(reinterpret_cast<const char *>(&d->m_nextContactId), sizeof(quint32))); + ++(d->m_nextContactId); theContact->setId(newContactId); // finally, add the contact to our internal lists and return diff --git a/src/plugins/organizer/memory/qorganizeritemmemorybackend.cpp b/src/plugins/organizer/memory/qorganizeritemmemorybackend.cpp index 622f46d2b..15f2c84a2 100644 --- a/src/plugins/organizer/memory/qorganizeritemmemorybackend.cpp +++ b/src/plugins/organizer/memory/qorganizeritemmemorybackend.cpp @@ -652,7 +652,8 @@ bool QOrganizerItemMemoryEngine::storeItem(QOrganizerItem* theOrganizerItem, QOr targetCollectionId = defaultCollectionId(); // update the organizer item - set its ID - theOrganizerItemId = this->itemId(QString::number(d->m_nextOrganizerItemId++)); + theOrganizerItemId = itemId(QByteArray(reinterpret_cast<const char *>(&d->m_nextOrganizerItemId), sizeof(quint32))); + ++(d->m_nextOrganizerItemId); theOrganizerItem->setId(theOrganizerItemId); // finally, add the organizer item to our internal lists and return theOrganizerItem->setCollectionId(targetCollectionId); @@ -1095,7 +1096,8 @@ bool QOrganizerItemMemoryEngine::saveCollection(QOrganizerCollection* collection } // this is a new collection with a null id; create a new id, add it to our list. - collectionId = this->collectionId(QString::number(d->m_nextOrganizerCollectionId++)); + collectionId = this->collectionId(QByteArray(reinterpret_cast<const char *>(&d->m_nextOrganizerCollectionId), sizeof(quint32))); + ++(d->m_nextOrganizerCollectionId); collection->setId(collectionId); cs.insertAddedCollection(collectionId); } diff --git a/src/plugins/organizer/memory/qorganizeritemmemorybackend_p.h b/src/plugins/organizer/memory/qorganizeritemmemorybackend_p.h index 12320348e..ad1c8ac42 100644 --- a/src/plugins/organizer/memory/qorganizeritemmemorybackend_p.h +++ b/src/plugins/organizer/memory/qorganizeritemmemorybackend_p.h @@ -123,7 +123,7 @@ public: QMap<QString, QString> idInterpretationParameters() const; inline QOrganizerCollectionId defaultCollectionId() const - { return collectionId(QString::number(QOrganizerItemMemoryEngineData::DefaultCollectionLocalId)); } + { const uint id(QOrganizerItemMemoryEngineData::DefaultCollectionLocalId); return collectionId(QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } // items QList<QOrganizerItem> items(const QList<QOrganizerItemId> &itemIds, const QOrganizerItemFetchHint &fetchHint, diff --git a/tests/auto/contacts/qcontact/tst_qcontact.cpp b/tests/auto/contacts/qcontact/tst_qcontact.cpp index 4dd1dd2fc..a19a9d875 100644 --- a/tests/auto/contacts/qcontact/tst_qcontact.cpp +++ b/tests/auto/contacts/qcontact/tst_qcontact.cpp @@ -49,7 +49,7 @@ QTCONTACTS_USE_NAMESPACE static inline QContactId makeId(const QString &managerName, uint id) { - return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QString::number(id)); + return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } diff --git a/tests/auto/contacts/qcontactasync/unittest/tst_qcontactasync.cpp b/tests/auto/contacts/qcontactasync/unittest/tst_qcontactasync.cpp index bdd2f9a37..59a584f83 100644 --- a/tests/auto/contacts/qcontactasync/unittest/tst_qcontactasync.cpp +++ b/tests/auto/contacts/qcontactasync/unittest/tst_qcontactasync.cpp @@ -167,7 +167,7 @@ private: static inline QContactId makeId(const QString &managerName, uint id) { - return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QString::number(id)); + return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } diff --git a/tests/auto/contacts/qcontactfilter/tst_qcontactfilter.cpp b/tests/auto/contacts/qcontactfilter/tst_qcontactfilter.cpp index 14f04bedb..e347c3fdd 100644 --- a/tests/auto/contacts/qcontactfilter/tst_qcontactfilter.cpp +++ b/tests/auto/contacts/qcontactfilter/tst_qcontactfilter.cpp @@ -52,7 +52,7 @@ Q_DECLARE_METATYPE(QContactFilter) static inline QContactId makeId(const QString &managerName, uint id) { - return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QString::number(id)); + return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } class tst_QContactFilter : public QObject diff --git a/tests/auto/contacts/qcontactmanager/tst_qcontactmanager.cpp b/tests/auto/contacts/qcontactmanager/tst_qcontactmanager.cpp index 43fa8eff1..7e7f8d0a0 100644 --- a/tests/auto/contacts/qcontactmanager/tst_qcontactmanager.cpp +++ b/tests/auto/contacts/qcontactmanager/tst_qcontactmanager.cpp @@ -290,7 +290,7 @@ QContactManagerEngine* LazyEngineFactory::engine(const QMap<QString, QString>& p static inline QContactId makeId(const QString &managerName, uint id) { - return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QString::number(id)); + return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } tst_QContactManager::tst_QContactManager() diff --git a/tests/auto/contacts/qcontactrelationship/tst_qcontactrelationship.cpp b/tests/auto/contacts/qcontactrelationship/tst_qcontactrelationship.cpp index de59f88ff..bdeabd465 100644 --- a/tests/auto/contacts/qcontactrelationship/tst_qcontactrelationship.cpp +++ b/tests/auto/contacts/qcontactrelationship/tst_qcontactrelationship.cpp @@ -49,7 +49,7 @@ QTCONTACTS_USE_NAMESPACE static inline QContactId makeId(const QString &managerName, uint id) { - return QContactId(QStringLiteral("qtcontacts:%1:").arg(managerName), QString::number(id)); + return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } diff --git a/tests/auto/organizer/qorganizercollection/tst_qorganizercollection.cpp b/tests/auto/organizer/qorganizercollection/tst_qorganizercollection.cpp index 61b3b225a..00fa2e9c8 100644 --- a/tests/auto/organizer/qorganizercollection/tst_qorganizercollection.cpp +++ b/tests/auto/organizer/qorganizercollection/tst_qorganizercollection.cpp @@ -52,7 +52,7 @@ QTORGANIZER_USE_NAMESPACE static inline QOrganizerCollectionId makeId(const QString &managerName, uint id) { - return QOrganizerCollectionId(QStringLiteral("qtorganizer:basic%1:").arg(managerName), QString::number(id)); + return QOrganizerCollectionId(QStringLiteral("qtorganizer:%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } @@ -149,7 +149,7 @@ void tst_QOrganizerCollection::idComparison() QOrganizerCollectionId id6; QOrganizerCollectionId id7(QString(), "1"); QOrganizerCollectionId id8(QString(), "2"); - QOrganizerCollectionId id9(QStringLiteral("qtorganizer:basic:"), ""); + QOrganizerCollectionId id9(QStringLiteral("qtorganizer:basic:"), QByteArray()); QVERIFY(id6.isNull()); QVERIFY(id7.isNull()); QVERIFY(id8.isNull()); @@ -220,27 +220,33 @@ void tst_QOrganizerCollection::idStringFunctions() QVERIFY(id3.toString() != id4.toString()); // this should "work" -- string of the correct format - QString prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString("::") + QString::number(2); + const uint numericId2 = 2u; + const QByteArray localId2 = QByteArray(reinterpret_cast<const char *>(&numericId2), sizeof(uint)); + QString prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString("::") + localId2.toHex(); QOrganizerCollectionId rebuiltid = QOrganizerCollectionId::fromString(prebuiltidstring); - // QVERIFY(rebuiltid == id4); // -- this requires a working backend. + QVERIFY(rebuiltid == id4); + QVERIFY(rebuiltid.localId() == id4.localId()); // this string has the right format and one parameter, but requires a working backend - prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value") + QString(":") + QString::number(2); + prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value") + QString(":") + localId2.toHex(); rebuiltid = QOrganizerCollectionId::fromString(prebuiltidstring); - // QVERIFY(rebuiltid == id4); // -- this requires a working backend. + QVERIFY(rebuiltid != id4); + QVERIFY(rebuiltid.localId() == id4.localId()); // this string has the right format and some parameters, but requires a working backend - prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=value2") + QString(":") + QString::number(2); + prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=value2") + QString(":") + localId2.toHex(); rebuiltid = QOrganizerCollectionId::fromString(prebuiltidstring); - // QVERIFY(rebuiltid == id4); // -- this requires a working backend. + QVERIFY(rebuiltid != id4); + QVERIFY(rebuiltid.localId() == id4.localId()); // this string has the right format but misses the value for a parameter - prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=") + QString(":") + QString::number(2); + prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=") + QString(":") + localId2.toHex(); rebuiltid = QOrganizerCollectionId::fromString(prebuiltidstring); - // QVERIFY(rebuiltid == id4); // -- this requires a working backend. + QVERIFY(rebuiltid != id4); + QVERIFY(rebuiltid.localId() == id4.localId()); // this string misses a field (the parameters) - prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString::number(2); + prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + localId2.toHex(); rebuiltid = QOrganizerCollectionId::fromString(prebuiltidstring); QVERIFY(rebuiltid == QOrganizerCollectionId()); // invalid so should be null. @@ -250,12 +256,12 @@ void tst_QOrganizerCollection::idStringFunctions() QVERIFY(rebuiltid == QOrganizerCollectionId()); // invalid so should be null. // this string misses the prefix (qtorganizer) - prebuiltidstring = QString("notorganizer") + QString(":") + QString("a") + QString("::") + QString::number(2); + prebuiltidstring = QString("notorganizer") + QString(":") + QString("a") + QString("::") + localId2.toHex(); rebuiltid = QOrganizerCollectionId::fromString(prebuiltidstring); QVERIFY(rebuiltid == QOrganizerCollectionId()); // invalid so should be null. // this string misses the manager uri - prebuiltidstring = QString("notorganizer") + QString(":::") + QString::number(2); + prebuiltidstring = QString("notorganizer") + QString(":::") + localId2.toHex(); rebuiltid = QOrganizerCollectionId::fromString(prebuiltidstring); QVERIFY(rebuiltid == QOrganizerCollectionId()); // invalid so should be null. } diff --git a/tests/auto/organizer/qorganizeritem/tst_qorganizeritem.cpp b/tests/auto/organizer/qorganizeritem/tst_qorganizeritem.cpp index 54f5ef387..980989a34 100644 --- a/tests/auto/organizer/qorganizeritem/tst_qorganizeritem.cpp +++ b/tests/auto/organizer/qorganizeritem/tst_qorganizeritem.cpp @@ -52,7 +52,7 @@ QTORGANIZER_USE_NAMESPACE static inline QOrganizerItemId makeId(const QString &managerName, uint id) { - return QOrganizerItemId(QStringLiteral("qtorganizer:basic%1:").arg(managerName), QString::number(id)); + return QOrganizerItemId(QStringLiteral("qtorganizer:%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } @@ -653,42 +653,48 @@ void tst_QOrganizerItem::idStringFunctions() QVERIFY(id3.toString() != id4.toString()); // this should "work" -- string of the correct format - QString prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString("::") + QString::number(2); + const uint numericId2 = 2u; + const QByteArray localId2 = QByteArray(reinterpret_cast<const char *>(&numericId2), sizeof(uint)); + QString prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString("::") + localId2.toHex(); QOrganizerItemId rebuiltid = QOrganizerItemId::fromString(prebuiltidstring); - // QVERIFY(rebuiltid == id4); // -- this requires a working backend. + QVERIFY(rebuiltid == id4); + QVERIFY(rebuiltid.localId() == id4.localId()); // this string has the right format and one parameter, but requires a working backend - prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value") + QString(":") + QString::number(2); + prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value") + QString(":") + localId2.toHex(); rebuiltid = QOrganizerItemId::fromString(prebuiltidstring); - // QVERIFY(rebuiltid == id4); // -- this requires a working backend. + QVERIFY(rebuiltid != id4); + QVERIFY(rebuiltid.localId() == id4.localId()); // this string has the right format and some parameters, but requires a working backend - prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=value2") + QString(":") + QString::number(2); + prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=value2") + QString(":") + localId2.toHex(); rebuiltid = QOrganizerItemId::fromString(prebuiltidstring); - // QVERIFY(rebuiltid == id4); // -- this requires a working backend. + QVERIFY(rebuiltid != id4); + QVERIFY(rebuiltid.localId() == id4.localId()); // this string has the right format but misses the value for a parameter - prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=") + QString(":") + QString::number(2); + prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=") + QString(":") + localId2.toHex(); rebuiltid = QOrganizerItemId::fromString(prebuiltidstring); - // QVERIFY(rebuiltid == id4); // -- this requires a working backend. + QVERIFY(rebuiltid != id4); + QVERIFY(rebuiltid.localId() == id4.localId()); // this string misses a field (the parameters) - prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString::number(2); + prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + localId2.toHex(); rebuiltid = QOrganizerItemId::fromString(prebuiltidstring); QVERIFY(rebuiltid == QOrganizerItemId()); // invalid so should be null. // this string misses two fields (params plus manager uri) - prebuiltidstring = QString("qtorganizer") + QString(":") + QString::number(2); + prebuiltidstring = QString("qtorganizer") + QString(":") + localId2.toHex(); rebuiltid = QOrganizerItemId::fromString(prebuiltidstring); QVERIFY(rebuiltid == QOrganizerItemId()); // invalid so should be null. // this string misses the prefix (qtorganizer) - prebuiltidstring = QString("notorganizer") + QString(":") + QString("a") + QString("::") + QString::number(2); + prebuiltidstring = QString("notorganizer") + QString(":") + QString("a") + QString("::") + localId2.toHex(); rebuiltid = QOrganizerItemId::fromString(prebuiltidstring); QVERIFY(rebuiltid == QOrganizerItemId()); // invalid so should be null. // this string misses the manager uri - prebuiltidstring = QString("notorganizer") + QString(":::") + QString::number(2); + prebuiltidstring = QString("notorganizer") + QString(":::") + localId2.toHex(); rebuiltid = QOrganizerItemId::fromString(prebuiltidstring); QVERIFY(rebuiltid == QOrganizerItemId()); // invalid so should be null. } diff --git a/tests/auto/organizer/qorganizeritemfilter/tst_qorganizeritemfilter.cpp b/tests/auto/organizer/qorganizeritemfilter/tst_qorganizeritemfilter.cpp index 037e05c35..41120061c 100644 --- a/tests/auto/organizer/qorganizeritemfilter/tst_qorganizeritemfilter.cpp +++ b/tests/auto/organizer/qorganizeritemfilter/tst_qorganizeritemfilter.cpp @@ -53,12 +53,12 @@ Q_DECLARE_METATYPE(QOrganizerItemDetailFieldFilter) static inline QOrganizerItemId makeItemId(uint id) { - return QOrganizerItemId(QStringLiteral("qtorganizer:basic:"), QString::number(id)); + return QOrganizerItemId(QStringLiteral("qtorganizer:basic:"), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } static inline QOrganizerCollectionId makeCollectionId(uint id) { - return QOrganizerCollectionId(QStringLiteral("qtorganizer:basic:"), QString::number(id)); + return QOrganizerCollectionId(QStringLiteral("qtorganizer:basic:"), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } @@ -1180,31 +1180,31 @@ void tst_QOrganizerItemFilter::testDebugStreamOut_data() ids << id1 << id2 << id3; filter.setCollectionIds(ids); // Testing method setCollectionIds - QTest::newRow("collection") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(\"qtorganizer:basic::5\"), QOrganizerCollectionId(\"qtorganizer:basic::6\"), QOrganizerCollectionId(\"qtorganizer:basic::7\"))))"; + QTest::newRow("collection") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(qtorganizer:basic::05000000), QOrganizerCollectionId(qtorganizer:basic::06000000), QOrganizerCollectionId(qtorganizer:basic::07000000))))"; filter.setCollectionId(id2); // Testing method setCollectionId (and the related clearing of the collection) - QTest::newRow("collection") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(\"qtorganizer:basic::6\"))))"; + QTest::newRow("collection") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(qtorganizer:basic::06000000))))"; filter.setCollectionId(id4); // Testing again method setCollectionId (and the related clearing of the collection) - QTest::newRow("collection") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(\"qtorganizer:basic::12\"))))"; + QTest::newRow("collection") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(qtorganizer:basic::0c000000))))"; ids.clear(); ids << id4; // Testing again method setCollectionIds - QTest::newRow("collection") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(\"qtorganizer:basic::12\"))))"; + QTest::newRow("collection") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(qtorganizer:basic::0c000000))))"; QOrganizerItemCollectionFilter filter2; filter2 = filter; // Testing again method setCollectionIds on the copied filter - QTest::newRow("collection") << (QOrganizerItemFilter)filter2 << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(\"qtorganizer:basic::12\"))))"; + QTest::newRow("collection") << (QOrganizerItemFilter)filter2 << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(qtorganizer:basic::0c000000))))"; QOrganizerItemFilter fil; fil = filter; // Testing that the assignment/conversion went fine - QTest::newRow("collection") << (QOrganizerItemFilter)fil << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(\"qtorganizer:basic::12\"))))"; + QTest::newRow("collection") << (QOrganizerItemFilter)fil << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(qtorganizer:basic::0c000000))))"; QOrganizerItemCollectionFilter filter3(fil); - QTest::newRow("collection") << (QOrganizerItemFilter)filter3 << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(\"qtorganizer:basic::12\"))))"; + QTest::newRow("collection") << (QOrganizerItemFilter)filter3 << "QOrganizerItemFilter(QOrganizerItemCollectionFilter(collectionIds=(QOrganizerCollectionId(qtorganizer:basic::0c000000))))"; } { @@ -1288,7 +1288,7 @@ void tst_QOrganizerItemFilter::testDebugStreamOut_data() QList<QOrganizerItemId> ids; ids << makeItemId(5) << makeItemId(6) << makeItemId(17); filter.setIds(ids); - QTest::newRow("Id") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(\"qtorganizer:basic::5\"), QOrganizerItemId(\"qtorganizer:basic::6\"), QOrganizerItemId(\"qtorganizer:basic::17\"))))"; + QTest::newRow("Id") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(qtorganizer:basic::05000000), QOrganizerItemId(qtorganizer:basic::06000000), QOrganizerItemId(qtorganizer:basic::11000000))))"; // Resetting the list of Ids filter.setIds(QList<QOrganizerItemId>()); @@ -1297,7 +1297,7 @@ void tst_QOrganizerItemFilter::testDebugStreamOut_data() // Testing the method insert QOrganizerItemId singleId = makeItemId(12); filter.insert(singleId); - QTest::newRow("Id") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(\"qtorganizer:basic::12\"))))"; + QTest::newRow("Id") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(qtorganizer:basic::0c000000))))"; // Testing the method remove filter.remove(singleId); @@ -1312,28 +1312,28 @@ void tst_QOrganizerItemFilter::testDebugStreamOut_data() // Test op= filter.setIds(ids); QOrganizerItemFilter f = filter; - QTest::newRow("Id") << (QOrganizerItemFilter)f << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(\"qtorganizer:basic::5\"), QOrganizerItemId(\"qtorganizer:basic::6\"), QOrganizerItemId(\"qtorganizer:basic::17\"))))"; + QTest::newRow("Id") << (QOrganizerItemFilter)f << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(qtorganizer:basic::05000000), QOrganizerItemId(qtorganizer:basic::06000000), QOrganizerItemId(qtorganizer:basic::11000000))))"; QOrganizerItemIdFilter filter2 = f; - QTest::newRow("Id") << (QOrganizerItemFilter)filter2 << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(\"qtorganizer:basic::5\"), QOrganizerItemId(\"qtorganizer:basic::6\"), QOrganizerItemId(\"qtorganizer:basic::17\"))))"; + QTest::newRow("Id") << (QOrganizerItemFilter)filter2 << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(qtorganizer:basic::05000000), QOrganizerItemId(qtorganizer:basic::06000000), QOrganizerItemId(qtorganizer:basic::11000000))))"; filter2 = filter; - QTest::newRow("Id") << (QOrganizerItemFilter)filter2 << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(\"qtorganizer:basic::5\"), QOrganizerItemId(\"qtorganizer:basic::6\"), QOrganizerItemId(\"qtorganizer:basic::17\"))))"; + QTest::newRow("Id") << (QOrganizerItemFilter)filter2 << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(qtorganizer:basic::05000000), QOrganizerItemId(qtorganizer:basic::06000000), QOrganizerItemId(qtorganizer:basic::11000000))))"; // Self assignment should do nothing filter2 = filter2; - QTest::newRow("Id") << (QOrganizerItemFilter)filter2 << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(\"qtorganizer:basic::5\"), QOrganizerItemId(\"qtorganizer:basic::6\"), QOrganizerItemId(\"qtorganizer:basic::17\"))))"; + QTest::newRow("Id") << (QOrganizerItemFilter)filter2 << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(qtorganizer:basic::05000000), QOrganizerItemId(qtorganizer:basic::06000000), QOrganizerItemId(qtorganizer:basic::11000000))))"; QOrganizerItemDetailFieldFilter dfil; QOrganizerItemIdFilter filter3(dfil); QTest::newRow("Id") << (QOrganizerItemFilter)filter3 << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=()))"; QOrganizerItemIdFilter filter4(filter); - QTest::newRow("Id") << (QOrganizerItemFilter)filter4 << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(\"qtorganizer:basic::5\"), QOrganizerItemId(\"qtorganizer:basic::6\"), QOrganizerItemId(\"qtorganizer:basic::17\"))))"; + QTest::newRow("Id") << (QOrganizerItemFilter)filter4 << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(qtorganizer:basic::05000000), QOrganizerItemId(qtorganizer:basic::06000000), QOrganizerItemId(qtorganizer:basic::11000000))))"; filter = dfil; // now assign. QTest::newRow("Id") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=()))"; QTest::newRow("Id") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=()))"; filter = filter3; filter.setIds(ids); // force a detach - QTest::newRow("Id") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(\"qtorganizer:basic::5\"), QOrganizerItemId(\"qtorganizer:basic::6\"), QOrganizerItemId(\"qtorganizer:basic::17\"))))"; + QTest::newRow("Id") << (QOrganizerItemFilter)filter << "QOrganizerItemFilter(QOrganizerItemIdFilter(ids=(QOrganizerItemId(qtorganizer:basic::05000000), QOrganizerItemId(qtorganizer:basic::06000000), QOrganizerItemId(qtorganizer:basic::11000000))))"; } { diff --git a/tests/auto/organizer/qorganizermanager/tst_qorganizermanager.cpp b/tests/auto/organizer/qorganizermanager/tst_qorganizermanager.cpp index b74ac72fb..e9a0c0635 100644 --- a/tests/auto/organizer/qorganizermanager/tst_qorganizermanager.cpp +++ b/tests/auto/organizer/qorganizermanager/tst_qorganizermanager.cpp @@ -70,12 +70,12 @@ Q_DECLARE_METATYPE(QList<QOrganizerItemDetail::DetailType>); static inline QOrganizerItemId makeItemId(uint id) { - return QOrganizerItemId(QStringLiteral("qtorganizer:basic:"), QString::number(id)); + return QOrganizerItemId(QStringLiteral("qtorganizer:basic:"), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } static inline QOrganizerCollectionId makeCollectionId(uint id) { - return QOrganizerCollectionId(QStringLiteral("qtorganizer:basic:"), QString::number(id)); + return QOrganizerCollectionId(QStringLiteral("qtorganizer:basic:"), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); } |