File indexing completed on 2024-12-22 04:57:04
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 "ewsxml.h" 0008 0009 #include <QDateTime> 0010 0011 #include "ewsfolder.h" 0012 #include "ewsid.h" 0013 #include "ewsitem.h" 0014 0015 static const QList<QString> messageSensitivityNames = { 0016 QStringLiteral("Normal"), 0017 QStringLiteral("Personal"), 0018 QStringLiteral("Private"), 0019 QStringLiteral("Confidential"), 0020 }; 0021 0022 static const QList<QString> messageImportanceNames = {QStringLiteral("Low"), QStringLiteral("Normal"), QStringLiteral("High")}; 0023 0024 static const QList<QString> calendarItemTypeNames = { 0025 QStringLiteral("Single"), 0026 QStringLiteral("Occurrence"), 0027 QStringLiteral("Exception"), 0028 QStringLiteral("RecurringMaster"), 0029 }; 0030 0031 static const QList<QString> legacyFreeBusyStatusNames = { 0032 QStringLiteral("Free"), 0033 QStringLiteral("Tentative"), 0034 QStringLiteral("Busy"), 0035 QStringLiteral("OOF"), 0036 QStringLiteral("NoData"), 0037 }; 0038 0039 static const QList<QString> responseTypeNames = { 0040 QStringLiteral("Unknown"), 0041 QStringLiteral("Organizer"), 0042 QStringLiteral("Tentative"), 0043 QStringLiteral("Accept"), 0044 QStringLiteral("Decline"), 0045 QStringLiteral("NoResponseReceived"), 0046 }; 0047 0048 bool ewsXmlBoolReader(QXmlStreamReader &reader, QVariant &val) 0049 { 0050 const QString elmText = reader.readElementText(); 0051 if (reader.error() != QXmlStreamReader::NoError) { 0052 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Error reading %1 element").arg(reader.name().toString()); 0053 reader.skipCurrentElement(); 0054 return false; 0055 } 0056 if (elmText == QLatin1StringView("true")) { 0057 val = true; 0058 } else if (elmText == QLatin1StringView("false")) { 0059 val = false; 0060 } else { 0061 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unexpected invalid boolean value in %1 element:").arg(reader.name().toString()) << elmText; 0062 return false; 0063 } 0064 0065 return true; 0066 } 0067 0068 bool ewsXmlBoolWriter(QXmlStreamWriter &writer, const QVariant &val) 0069 { 0070 writer.writeCharacters(val.toBool() ? QStringLiteral("true") : QStringLiteral("false")); 0071 0072 return true; 0073 } 0074 0075 bool ewsXmlBase64Reader(QXmlStreamReader &reader, QVariant &val) 0076 { 0077 QString elmName = reader.name().toString(); 0078 val = QByteArray::fromBase64(reader.readElementText().toLatin1()); 0079 if (reader.error() != QXmlStreamReader::NoError) { 0080 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid content.").arg(elmName); 0081 reader.skipCurrentElement(); 0082 return false; 0083 } 0084 0085 return true; 0086 } 0087 0088 bool ewsXmlBase64Writer(QXmlStreamWriter &writer, const QVariant &val) 0089 { 0090 writer.writeCharacters(QString::fromLatin1(val.toByteArray().toBase64())); 0091 0092 return true; 0093 } 0094 0095 bool ewsXmlIdReader(QXmlStreamReader &reader, QVariant &val) 0096 { 0097 QString elmName = reader.name().toString(); 0098 EwsId id = EwsId(reader); 0099 if (id.type() == EwsId::Unspecified) { 0100 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid content.").arg(elmName); 0101 reader.skipCurrentElement(); 0102 return false; 0103 } 0104 val = QVariant::fromValue(id); 0105 reader.skipCurrentElement(); 0106 return true; 0107 } 0108 0109 bool ewsXmlIdWriter(QXmlStreamWriter &writer, const QVariant &val) 0110 { 0111 EwsId id = val.value<EwsId>(); 0112 if (id.type() == EwsId::Unspecified) { 0113 return false; 0114 } 0115 0116 id.writeAttributes(writer); 0117 0118 return true; 0119 } 0120 0121 bool ewsXmlTextReader(QXmlStreamReader &reader, QVariant &val) 0122 { 0123 QString elmName = reader.name().toString(); 0124 val = reader.readElementText(); 0125 if (reader.error() != QXmlStreamReader::NoError) { 0126 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid content.").arg(elmName); 0127 reader.skipCurrentElement(); 0128 return false; 0129 } 0130 return true; 0131 } 0132 0133 bool ewsXmlTextWriter(QXmlStreamWriter &writer, const QVariant &val) 0134 { 0135 writer.writeCharacters(val.toString()); 0136 0137 return true; 0138 } 0139 0140 bool ewsXmlUIntReader(QXmlStreamReader &reader, QVariant &val) 0141 { 0142 QString elmName = reader.name().toString(); 0143 bool ok; 0144 val = reader.readElementText().toUInt(&ok); 0145 if (reader.error() != QXmlStreamReader::NoError || !ok) { 0146 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid content.").arg(elmName); 0147 return false; 0148 } 0149 return true; 0150 } 0151 0152 bool ewsXmlUIntWriter(QXmlStreamWriter &writer, const QVariant &val) 0153 { 0154 writer.writeCharacters(QString::number(val.toUInt())); 0155 0156 return true; 0157 } 0158 0159 bool ewsXmlDateTimeReader(QXmlStreamReader &reader, QVariant &val) 0160 { 0161 QString elmName = reader.name().toString(); 0162 QDateTime dt = QDateTime::fromString(reader.readElementText(), Qt::ISODate); 0163 if (reader.error() != QXmlStreamReader::NoError || !dt.isValid()) { 0164 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid content.").arg(elmName); 0165 return false; 0166 } 0167 val = QVariant::fromValue<QDateTime>(dt); 0168 return true; 0169 } 0170 0171 bool ewsXmlItemReader(QXmlStreamReader &reader, QVariant &val) 0172 { 0173 QString elmName = reader.name().toString(); 0174 EwsItem item = EwsItem(reader); 0175 if (!item.isValid()) { 0176 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid content.").arg(elmName); 0177 reader.skipCurrentElement(); 0178 return false; 0179 } 0180 val = QVariant::fromValue(item); 0181 return true; 0182 } 0183 0184 bool ewsXmlFolderReader(QXmlStreamReader &reader, QVariant &val) 0185 { 0186 const QString elmName = reader.name().toString(); 0187 EwsFolder folder = EwsFolder(reader); 0188 if (!folder.isValid()) { 0189 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid content.").arg(elmName); 0190 reader.skipCurrentElement(); 0191 return false; 0192 } 0193 val = QVariant::fromValue(folder); 0194 return true; 0195 } 0196 0197 bool ewsXmlEnumReader(QXmlStreamReader &reader, QVariant &val, const QList<QString> &items) 0198 { 0199 const QString elmName = reader.name().toString(); 0200 QString text = reader.readElementText(); 0201 if (reader.error() != QXmlStreamReader::NoError) { 0202 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid content.").arg(elmName); 0203 reader.skipCurrentElement(); 0204 return false; 0205 } 0206 int i = 0; 0207 QList<QString>::const_iterator it; 0208 for (it = items.cbegin(); it != items.cend(); ++it, i++) { 0209 if (text == *it) { 0210 val = i; 0211 break; 0212 } 0213 } 0214 0215 if (it == items.cend()) { 0216 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - unknown value %2.").arg(elmName, text); 0217 return false; 0218 } 0219 return true; 0220 } 0221 0222 bool ewsXmlSensitivityReader(QXmlStreamReader &reader, QVariant &val) 0223 { 0224 return ewsXmlEnumReader(reader, val, messageSensitivityNames); 0225 } 0226 0227 bool ewsXmlImportanceReader(QXmlStreamReader &reader, QVariant &val) 0228 { 0229 return ewsXmlEnumReader(reader, val, messageImportanceNames); 0230 } 0231 0232 bool ewsXmlCalendarItemTypeReader(QXmlStreamReader &reader, QVariant &val) 0233 { 0234 return ewsXmlEnumReader(reader, val, calendarItemTypeNames); 0235 } 0236 0237 bool ewsXmlLegacyFreeBusyStatusReader(QXmlStreamReader &reader, QVariant &val) 0238 { 0239 return ewsXmlEnumReader(reader, val, legacyFreeBusyStatusNames); 0240 } 0241 0242 bool ewsXmlResponseTypeReader(QXmlStreamReader &reader, QVariant &val) 0243 { 0244 return ewsXmlEnumReader(reader, val, responseTypeNames); 0245 } 0246 0247 template<> 0248 QString readXmlElementValue(QXmlStreamReader &reader, bool &ok, const QString &parentElement) 0249 { 0250 ok = true; 0251 const QStringView elmName = reader.name(); 0252 QString val = reader.readElementText(); 0253 if (reader.error() != QXmlStreamReader::NoError) { 0254 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid %2 element.").arg(parentElement, elmName.toString()); 0255 reader.skipCurrentElement(); 0256 val.clear(); 0257 ok = false; 0258 } 0259 0260 return val; 0261 } 0262 0263 template<> 0264 int readXmlElementValue(QXmlStreamReader &reader, bool &ok, const QString &parentElement) 0265 { 0266 const QStringView elmName = reader.name(); 0267 QString valStr = readXmlElementValue<QString>(reader, ok, parentElement); 0268 int val = 0; 0269 if (ok) { 0270 val = valStr.toInt(&ok); 0271 if (!ok) { 0272 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid %2 element.").arg(parentElement, elmName.toString()); 0273 } 0274 } 0275 0276 return val; 0277 } 0278 0279 template<> 0280 long readXmlElementValue(QXmlStreamReader &reader, bool &ok, const QString &parentElement) 0281 { 0282 const QStringView elmName = reader.name(); 0283 QString valStr = readXmlElementValue<QString>(reader, ok, parentElement); 0284 long val = 0; 0285 if (ok) { 0286 val = valStr.toLong(&ok); 0287 if (!ok) { 0288 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid %2 element.").arg(parentElement, elmName.toString()); 0289 } 0290 } 0291 0292 return val; 0293 } 0294 0295 template<> 0296 QDateTime readXmlElementValue(QXmlStreamReader &reader, bool &ok, const QString &parentElement) 0297 { 0298 const QStringView elmName = reader.name(); 0299 QString valStr = readXmlElementValue<QString>(reader, ok, parentElement); 0300 QDateTime val; 0301 if (ok) { 0302 val = QDateTime::fromString(valStr, Qt::ISODate); 0303 if (!val.isValid()) { 0304 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid %2 element.").arg(parentElement, elmName.toString()); 0305 ok = false; 0306 } 0307 } 0308 0309 return val; 0310 } 0311 0312 template<> 0313 bool readXmlElementValue(QXmlStreamReader &reader, bool &ok, const QString &parentElement) 0314 { 0315 const QStringView elmName = reader.name(); 0316 QString valStr = readXmlElementValue<QString>(reader, ok, parentElement); 0317 bool val = false; 0318 if (ok) { 0319 if (valStr == QLatin1StringView("true")) { 0320 val = true; 0321 } else if (valStr == QLatin1StringView("false")) { 0322 val = false; 0323 } else { 0324 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid %2 element.").arg(parentElement, elmName.toString()); 0325 ok = false; 0326 } 0327 } 0328 0329 return val; 0330 } 0331 0332 template<> 0333 QByteArray readXmlElementValue(QXmlStreamReader &reader, bool &ok, const QString &parentElement) 0334 { 0335 QString valStr = readXmlElementValue<QString>(reader, ok, parentElement); 0336 QByteArray val; 0337 if (ok) { 0338 /* QByteArray::fromBase64() does not perform any input validity checks 0339 and skips invalid input characters */ 0340 val = QByteArray::fromBase64(valStr.toLatin1()); 0341 } 0342 0343 return val; 0344 }