File indexing completed on 2024-12-22 04:57:01

0001 /*
0002     SPDX-FileCopyrightText: 2015-2017 Krzysztof Nowicki <krissn@op.pl>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "ewsid.h"
0008 
0009 #include <QDebug>
0010 #include <QXmlStreamReader>
0011 #include <QXmlStreamWriter>
0012 
0013 #include "ewsclient.h"
0014 #include "ewsclient_debug.h"
0015 
0016 static const QString distinguishedIdNames[] = {
0017     QStringLiteral("calendar"),
0018     QStringLiteral("contacts"),
0019     QStringLiteral("deleteditems"),
0020     QStringLiteral("drafts"),
0021     QStringLiteral("inbox"),
0022     QStringLiteral("journal"),
0023     QStringLiteral("notes"),
0024     QStringLiteral("outbox"),
0025     QStringLiteral("sentitems"),
0026     QStringLiteral("tasks"),
0027     QStringLiteral("msgfolderroot"),
0028     QStringLiteral("root"),
0029     QStringLiteral("junkemail"),
0030     QStringLiteral("searchfolders"),
0031     QStringLiteral("voicemail"),
0032     QStringLiteral("recoverableitemsroot"),
0033     QStringLiteral("recoverableitemsdeletions"),
0034     QStringLiteral("recoverableitemsversions"),
0035     QStringLiteral("recoverableitemspurges"),
0036     QStringLiteral("archiveroot"),
0037     QStringLiteral("archivemsgfolderroot"),
0038     QStringLiteral("archivedeleteditems"),
0039     QStringLiteral("archiverecoverableitemsroot"),
0040     QStringLiteral("archiverecoverableitemsdeletions"),
0041     QStringLiteral("archiverecoverableitemsversions"),
0042     QStringLiteral("archiverecoverableitemspurges"),
0043 };
0044 
0045 EwsId::EwsId(QXmlStreamReader &reader)
0046     : mDid(EwsDIdCalendar)
0047 {
0048     // Don't check for this element's name as a folder id may be contained in several elements
0049     // such as "FolderId" or "ParentFolderId".
0050     const QXmlStreamAttributes &attrs = reader.attributes();
0051 
0052     QStringView idRef = attrs.value(QStringLiteral("Id"));
0053     QStringView changeKeyRef = attrs.value(QStringLiteral("ChangeKey"));
0054 
0055     if (idRef.isNull()) {
0056         return;
0057     }
0058 
0059     mId = idRef.toString();
0060     if (!changeKeyRef.isNull()) {
0061         mChangeKey = changeKeyRef.toString();
0062     }
0063     mType = Real;
0064 }
0065 
0066 EwsId::EwsId(const QString &id, const QString &changeKey)
0067     : mType(Real)
0068     , mId(id)
0069     , mChangeKey(changeKey)
0070     , mDid(EwsDIdCalendar)
0071 {
0072 }
0073 
0074 EwsId &EwsId::operator=(const EwsId &other)
0075 {
0076     mType = other.mType;
0077     if (mType == Distinguished) {
0078         mDid = other.mDid;
0079     } else if (mType == Real) {
0080         mId = other.mId;
0081         mChangeKey = other.mChangeKey;
0082     }
0083     return *this;
0084 }
0085 
0086 EwsId &EwsId::operator=(EwsId &&other)
0087 {
0088     mType = other.mType;
0089     if (mType == Distinguished) {
0090         mDid = other.mDid;
0091     } else if (mType == Real) {
0092         mId = std::move(other.mId);
0093         mChangeKey = std::move(other.mChangeKey);
0094     }
0095     return *this;
0096 }
0097 
0098 bool EwsId::operator==(const EwsId &other) const
0099 {
0100     if (mType != other.mType) {
0101         return false;
0102     }
0103 
0104     if (mType == Distinguished) {
0105         return mDid == other.mDid;
0106     } else if (mType == Real) {
0107         return mId == other.mId && mChangeKey == other.mChangeKey;
0108     }
0109     return true;
0110 }
0111 
0112 bool EwsId::operator<(const EwsId &other) const
0113 {
0114     if (mType != other.mType) {
0115         return mType < other.mType;
0116     }
0117 
0118     if (mType == Distinguished) {
0119         return mDid < other.mDid;
0120     } else if (mType == Real) {
0121         return mId < other.mId && mChangeKey < other.mChangeKey;
0122     }
0123     return false;
0124 }
0125 
0126 void EwsId::writeFolderIds(QXmlStreamWriter &writer) const
0127 {
0128     if (mType == Distinguished) {
0129         writer.writeStartElement(ewsTypeNsUri, QStringLiteral("DistinguishedFolderId"));
0130         writer.writeAttribute(QStringLiteral("Id"), distinguishedIdNames[mDid]);
0131         writer.writeEndElement();
0132     } else if (mType == Real) {
0133         writer.writeStartElement(ewsTypeNsUri, QStringLiteral("FolderId"));
0134         writer.writeAttribute(QStringLiteral("Id"), mId);
0135         if (!mChangeKey.isEmpty()) {
0136             writer.writeAttribute(QStringLiteral("ChangeKey"), mChangeKey);
0137         }
0138         writer.writeEndElement();
0139     }
0140 }
0141 
0142 void EwsId::writeItemIds(QXmlStreamWriter &writer) const
0143 {
0144     if (mType == Real) {
0145         writer.writeStartElement(ewsTypeNsUri, QStringLiteral("ItemId"));
0146         writer.writeAttribute(QStringLiteral("Id"), mId);
0147         if (!mChangeKey.isEmpty()) {
0148             writer.writeAttribute(QStringLiteral("ChangeKey"), mChangeKey);
0149         }
0150         writer.writeEndElement();
0151     }
0152 }
0153 
0154 void EwsId::writeAttributes(QXmlStreamWriter &writer) const
0155 {
0156     if (mType == Real) {
0157         writer.writeAttribute(QStringLiteral("Id"), mId);
0158         if (!mChangeKey.isEmpty()) {
0159             writer.writeAttribute(QStringLiteral("ChangeKey"), mChangeKey);
0160         }
0161     }
0162 }
0163 
0164 QDebug operator<<(QDebug debug, const EwsId &id)
0165 {
0166     QDebugStateSaver saver(debug);
0167     QDebug d = debug.nospace().noquote();
0168     d << QStringLiteral("EwsId(");
0169 
0170     switch (id.mType) {
0171     case EwsId::Distinguished:
0172         d << QStringLiteral("Distinguished: ") << distinguishedIdNames[id.mDid];
0173         break;
0174     case EwsId::Real: {
0175         QString name = EwsClient::folderHash.value(id.mId, ewsHash(id.mId));
0176         d << name << QStringLiteral(", ") << ewsHash(id.mChangeKey);
0177         break;
0178     }
0179     default:
0180         break;
0181     }
0182     d << ')';
0183     return debug;
0184 }
0185 
0186 uint qHash(const EwsId &id, uint seed)
0187 {
0188     return qHash(id.id(), seed) ^ qHash(id.changeKey(), seed) ^ static_cast<uint>(id.type());
0189 }