1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include <QVariant>
41
42#include "qabstractdatetime_p.h"
43#include "qabstractfloat_p.h"
44#include "qatomicstring_p.h"
45#include "qatomictype_p.h"
46#include "qboolean_p.h"
47#include "qbuiltintypes_p.h"
48#include "qdate_p.h"
49#include "qschemadatetime_p.h"
50#include "qderivedinteger_p.h"
51#include "qdynamiccontext_p.h"
52#include "qgenericsequencetype_p.h"
53#include "qhexbinary_p.h"
54#include "qinteger_p.h"
55#include "qpatternistlocale_p.h"
56#include "qqnamevalue_p.h"
57#include "qschematime_p.h"
58#include "qvalidationerror_p.h"
59
60#include "qitem_p.h"
61
62QT_BEGIN_NAMESPACE
63
64/**
65 * @file
66 * @short Contains the implementation for AtomicValue. The definition is in qitem_p.h.
67 */
68
69using namespace QPatternist;
70
71AtomicValue::~AtomicValue()
72{
73}
74
75bool AtomicValue::evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &context) const
76{
77 context->error(message: QtXmlPatterns::tr(sourceText: "A value of type %1 cannot have an "
78 "Effective Boolean Value.")
79 .arg(a: formatType(np: context->namePool(), type: type())),
80 errorCode: ReportContext::FORG0006,
81 sourceLocation: QSourceLocation());
82 return false; /* Silence GCC warning. */
83}
84
85bool AtomicValue::hasError() const
86{
87 return false;
88}
89
90QVariant AtomicValue::toQt(const AtomicValue *const value)
91{
92 Q_ASSERT_X(value, Q_FUNC_INFO,
93 "Internal error, a null pointer cannot be passed.");
94
95 const ItemType::Ptr t(value->type());
96
97 if(BuiltinTypes::xsString->xdtTypeMatches(other: t)
98 || BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(other: t)
99 || BuiltinTypes::xsAnyURI->xdtTypeMatches(other: t))
100 return value->stringValue();
101 /* Note, this occurs before the xsInteger test, since xs:unsignedLong
102 * is a subtype of it. */
103 else if(*BuiltinTypes::xsUnsignedLong == *t)
104 return QVariant(value->as<DerivedInteger<TypeUnsignedLong> >()->storedValue());
105 else if(BuiltinTypes::xsInteger->xdtTypeMatches(other: t))
106 return QVariant(value->as<Numeric>()->toInteger());
107 else if(BuiltinTypes::xsFloat->xdtTypeMatches(other: t)
108 || BuiltinTypes::xsDouble->xdtTypeMatches(other: t)
109 || BuiltinTypes::xsDecimal->xdtTypeMatches(other: t))
110 return QVariant(value->as<Numeric>()->toDouble());
111 /* We currently does not support xs:time. */
112 else if(BuiltinTypes::xsDateTime->xdtTypeMatches(other: t))
113 return QVariant(value->as<AbstractDateTime>()->toDateTime());
114 else if(BuiltinTypes::xsDate->xdtTypeMatches(other: t))
115 return QVariant(value->as<AbstractDateTime>()->toDateTime().toUTC().date());
116 else if(BuiltinTypes::xsBoolean->xdtTypeMatches(other: t))
117 return QVariant(value->as<Boolean>()->value());
118 else if(BuiltinTypes::xsBase64Binary->xdtTypeMatches(other: t)
119 || BuiltinTypes::xsHexBinary->xdtTypeMatches(other: t))
120 return QVariant(value->as<Base64Binary>()->asByteArray());
121 else if(BuiltinTypes::xsQName->xdtTypeMatches(other: t))
122 return QVariant::fromValue(value: value->as<QNameValue>()->qName());
123 else
124 {
125 /* A type we don't support in Qt. Includes xs:time currently. */
126 return QVariant();
127 }
128}
129
130Item AtomicValue::toXDM(const QVariant &value)
131{
132 Q_ASSERT_X(value.isValid(), Q_FUNC_INFO,
133 "QVariants sent to Patternist must be valid.");
134
135 switch(value.userType())
136 {
137 case QVariant::Char:
138 /* A single codepoint is a string in XQuery. */
139 Q_FALLTHROUGH();
140 case QVariant::String:
141 return AtomicString::fromValue(value: value.toString());
142 case QVariant::Url:
143 {
144 /* QUrl doesn't follow the spec properly, so we
145 * have to let it be an xs:string. Calling QVariant::toString()
146 * on a QVariant that contains a QUrl returns, surprisingly,
147 * an empty string. */
148 return AtomicString::fromValue(value: QString::fromLatin1(str: value.toUrl().toEncoded()));
149 }
150 case QVariant::ByteArray:
151 return HexBinary::fromValue(data: value.toByteArray());
152 case QVariant::Int:
153 case QVariant::LongLong:
154 case QVariant::UInt:
155 return Integer::fromValue(num: value.toLongLong());
156 case QVariant::ULongLong:
157 return DerivedInteger<TypeUnsignedLong>::fromValueUnchecked(num: value.toULongLong());
158 case QVariant::Bool:
159 return Boolean::fromValue(value: value.toBool());
160 case QVariant::Time:
161 return SchemaTime::fromDateTime(dt: value.toDateTime());
162 case QVariant::Date:
163 return Date::fromDateTime(date: QDateTime(value.toDate(), QTime(), Qt::UTC));
164 case QVariant::DateTime:
165 return DateTime::fromDateTime(dt: value.toDateTime());
166 case QMetaType::Float:
167 return Item(Double::fromValue(num: value.toFloat()));
168 case QVariant::Double:
169 return Item(Double::fromValue(num: value.toDouble()));
170 default:
171 {
172 if (value.userType() == qMetaTypeId<float>())
173 {
174 return Item(Float::fromValue(num: value.value<float>()));
175 }
176 else {
177 Q_ASSERT_X(false,
178 Q_FUNC_INFO,
179 qPrintable(QString::fromLatin1(
180 "QVariants of type %1 are not supported in "
181 "Patternist, see the documentation")
182 .arg(QLatin1String(value.typeName()))));
183 return AtomicValue::Ptr();
184 }
185 }
186 }
187}
188
189ItemType::Ptr AtomicValue::qtToXDMType(const QXmlItem &item)
190{
191 Q_ASSERT(!item.isNull());
192
193 if(item.isNull())
194 return ItemType::Ptr();
195
196 if(item.isNode())
197 return BuiltinTypes::node;
198
199 Q_ASSERT(item.isAtomicValue());
200 const QVariant v(item.toAtomicValue());
201
202 switch(int(v.type()))
203 {
204 case QVariant::Char:
205 case QVariant::String:
206 case QVariant::Url:
207 return BuiltinTypes::xsString;
208 case QVariant::Bool:
209 return BuiltinTypes::xsBoolean;
210 case QVariant::ByteArray:
211 return BuiltinTypes::xsBase64Binary;
212 case QVariant::Int:
213 case QVariant::LongLong:
214 return BuiltinTypes::xsInteger;
215 case QVariant::ULongLong:
216 return BuiltinTypes::xsUnsignedLong;
217 case QVariant::Date:
218 return BuiltinTypes::xsDate;
219 case QVariant::DateTime:
220 case QVariant::Time:
221 return BuiltinTypes::xsDateTime;
222 case QMetaType::Float:
223 return BuiltinTypes::xsFloat;
224 case QVariant::Double:
225 return BuiltinTypes::xsDouble;
226 default:
227 return ItemType::Ptr();
228 }
229}
230
231QT_END_NAMESPACE
232

source code of qtxmlpatterns/src/xmlpatterns/data/qatomicvalue.cpp