17 #include <QXmlStreamReader>
19 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
20 #define QStringView QStringRef
23 static QStringView
namespaceForPrefix(
const QXmlStreamNamespaceDeclarations &decls,
const QString &prefix)
25 for (
const QXmlStreamNamespaceDeclaration &decl : qAsConst(decls)) {
26 if (decl.prefix() == prefix) {
27 return decl.namespaceUri();
40 } s_types[] = {{
"string", QVariant::String},
41 {
"base64Binary", QVariant::ByteArray},
42 {
"int", QVariant::Int},
43 {
"unsignedInt", QVariant::ULongLong},
44 {
"boolean", QVariant::Bool},
45 {
"float", QMetaType::Float},
46 {
"double", QVariant::Double},
47 {
"time", QVariant::Time},
48 {
"date", QVariant::Date}};
50 for (
const auto &type : s_types) {
51 if (xmlType == QLatin1String(type.xml)) {
52 return type.metaTypeId;
55 if (xmlType == QLatin1String(
"dateTime")) {
56 return qMetaTypeId<KDDateTime>();
66 const QXmlStreamNamespaceDeclarations combinedNamespaceDeclarations = envNsDecls + reader.
namespaceDeclarations();
67 const QString name = reader.name().toString();
73 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
74 QVariant::Type metaTypeId = QVariant::Invalid;
76 QMetaType::Type metaTypeId = QMetaType::UnknownType;
78 const auto invalidType = metaTypeId;
80 const QXmlStreamAttributes attributes = reader.attributes();
81 for (
const QXmlStreamAttribute &attribute : attributes) {
82 const QStringView name = attribute.name();
83 const QStringView ns = attribute.namespaceUri();
84 const QStringView attrValue = attribute.value();
88 if (name == QLatin1String(
"type")) {
90 const QString type = attrValue.toString();
91 const int pos = type.indexOf(QLatin1Char(
':'));
92 const QString dataType = type.mid(pos + 1);
105 while (reader.readNext() != QXmlStreamReader::Invalid) {
106 if (reader.isEndElement()) {
109 if (reader.isCharacters()) {
110 text = reader.text().toString();
112 }
else if (reader.isStartElement()) {
118 if (!text.isEmpty()) {
119 QVariant variant(text);
123 if (metaTypeId != invalidType) {
124 QVariant copy = variant;
125 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
126 if (!variant.convert(metaTypeId)) {
128 if (!variant.convert(QMetaType(metaTypeId))) {
130 variant = std::move(copy);
145 int symbol = charRef.indexOf(
'x');
146 int end = charRef.indexOf(
';');
148 if (symbol == -1 || end == -1) {
152 uint val = charRef.mid(symbol + 1, end - symbol - 1).toInt(&ok, 16);
158 if (val != 0x9 && val != 0xa && val != 0xd && (val <= 0x20)) {
167 qint64 i = offset - 1;
168 QByteArray dataCleanedUp;
169 QByteArray originalSequence;
171 while (i >= 0 && data.at(i) !=
'&') {
172 if (data.at(i) ==
'<') {
173 return dataCleanedUp;
176 originalSequence.prepend(data.at(i));
181 qWarning() <<
"found an invalid character sequence to remove:" << QLatin1String(originalSequence.prepend(
'&').constData());
182 dataCleanedUp = data;
183 dataCleanedUp = dataCleanedUp.replace(originalSequence,
"?");
185 return dataCleanedUp;
192 QXmlStreamReader reader(data);
193 if (reader.readNextStartElement()) {
194 if (reader.name() == QLatin1String(
"Envelope")
197 const QXmlStreamNamespaceDeclarations envNsDecls = reader.namespaceDeclarations();
198 if (reader.readNextStartElement()) {
199 if (reader.name() == QLatin1String(
"Header")
203 while (reader.readNextStartElement()) {
206 messageAddressingProperties.readMessageAddressingProperty(value);
210 pRequestHeaders->append(header);
214 reader.readNextStartElement();
216 if (reader.name() == QLatin1String(
"Body")
219 if (reader.readNextStartElement()) {
221 if (pMessageNamespace) {
224 if (pMsg->
name() == QLatin1String(
"Fault")
232 reader.raiseError(QObject::tr(
"Invalid SOAP Message, Body expected"));
235 reader.raiseError(QObject::tr(
"Invalid SOAP Message, empty Envelope"));
238 reader.raiseError(QObject::tr(
"Invalid SOAP Message, Envelope expected"));
241 if (reader.hasError()) {
242 if (reader.error() == QXmlStreamReader::NotWellFormedError) {
243 qWarning() <<
"Handling a Not well Formed Error";
245 if (!dataCleanedUp.isEmpty()) {
246 return xmlToMessage(dataCleanedUp, pMsg, pMessageNamespace, pRequestHeaders, soapVersion);
249 QString faultText = QString::fromLatin1(
"XML error: [%1:%2] %3")
250 .arg(QString::number(reader.lineNumber()), QString::number(reader.columnNumber()), reader.errorString());
static QStringView namespaceForPrefix(const QXmlStreamNamespaceDeclarations &decls, const QString &prefix)
static QByteArray handleNotWellFormedError(const QByteArray &data, qint64 offset)
static KDSoapValue parseElement(QXmlStreamReader &reader, const QXmlStreamNamespaceDeclarations &envNsDecls)
static int xmlTypeToMetaType(const QString &xmlType)
static bool isInvalidCharRef(const QByteArray &charRef)
static bool isWSAddressingNamespace(const QString &namespaceUri)
XmlError xmlToMessage(const QByteArray &data, KDSoapMessage *pParsedMessage, QString *pMessageNamespace, KDSoapHeaders *pRequestHeaders, KDSoap::SoapVersion soapVersion) const
@ PrematureEndOfDocumentError
void setMessageAddressingProperties(const KDSoapMessageAddressingProperties &map)
void createFaultMessage(const QString &faultCode, const QString &faultText, KDSoap::SoapVersion soapVersion)
void setFault(bool fault)
static QString soapEncoding()
static QString soapEnvelope()
static QString xmlSchemaInstance1999()
static QString xmlSchemaInstance2001()
static QString soapEnvelope200305()
static QString soapEncoding200305()
QList< KDSoapValue > & attributes()
KDSoapValueList & childValues() const
QXmlStreamNamespaceDeclarations namespaceDeclarations() const
void setNamespaceUri(const QString &ns)
QString namespaceUri() const
void setType(const QString &nameSpace, const QString &type)
void setNamespaceDeclarations(const QXmlStreamNamespaceDeclarations &namespaceDeclarations)
void setValue(const QVariant &value)
void setEnvironmentNamespaceDeclarations(const QXmlStreamNamespaceDeclarations &environmentNamespaceDeclarations)