1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#ifndef QV4DATEOBJECT_P_H
4#define QV4DATEOBJECT_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include "qv4object_p.h"
18#include "qv4functionobject_p.h"
19#include "qv4referenceobject_p.h"
20#include <QtCore/private/qnumeric_p.h>
21#include <QtCore/qdatetime.h>
22
23QT_BEGIN_NAMESPACE
24
25class QDateTime;
26
27namespace QV4 {
28
29struct Date
30{
31 static constexpr quint64 MaxDateVal = 8.64e15;
32
33 void init() { storage = InvalidDateVal; }
34 void init(double value);
35 void init(const QDateTime &dateTime);
36 void init(QDate date);
37 void init(QTime time, ExecutionEngine *engine);
38
39 Date &operator=(double value)
40 {
41 storage = (storage & (HasQDate | HasQTime)) | encode(value);
42 return *this;
43 }
44
45 operator double() const
46 {
47 const quint64 raw = (storage & ~(HasQDate | HasQTime));
48 if (raw == 0)
49 return qt_qnan();
50
51 if (raw > MaxDateVal)
52 return double(raw - MaxDateVal - Extra);
53
54 return double(raw) - double(MaxDateVal) - double(Extra);
55 }
56
57 QDate toQDate() const;
58 QTime toQTime() const;
59 QDateTime toQDateTime() const;
60 QVariant toVariant() const;
61
62 template<typename Function>
63 bool withStoragePointer(Function function)
64 {
65 switch (storage & (HasQDate | HasQTime)) {
66 case HasQDate: {
67 QDate date = toQDate();
68 return function(&date);
69 }
70 case HasQTime: {
71 QTime time = toQTime();
72 return function(&time);
73 }
74 case (HasQTime | HasQDate): {
75 QDateTime dateTime = toQDateTime();
76 return function(&dateTime);
77 }
78 default:
79 return false;
80 }
81 }
82
83private:
84 static constexpr quint64 InvalidDateVal = 0;
85 static constexpr quint64 Extra = 1;
86 static constexpr quint64 HasQDate = 1ull << 63;
87 static constexpr quint64 HasQTime = 1ull << 62;
88
89 // Make all our dates fit into quint64, leaving space for the flags
90 static_assert(((MaxDateVal * 2 + Extra) & (HasQDate | HasQTime)) == 0ull);
91
92 static quint64 encode(double value);
93 static quint64 encode(const QDateTime &dateTime);
94
95 quint64 storage;
96};
97
98namespace Heap {
99
100#define DateObjectMembers(class, Member)
101DECLARE_HEAP_OBJECT(DateObject, ReferenceObject) {
102 DECLARE_MARKOBJECTS(DateObject);
103
104 void doSetLocation()
105 {
106 if (CppStackFrame *frame = internalClass->engine->currentStackFrame)
107 setLocation(function: frame->v4Function, statement: frame->statementNumber());
108 }
109
110 void init()
111 {
112 ReferenceObject::init(object: nullptr, property: -1, flags: {});
113 m_date.init();
114 }
115
116 void init(double dateTime)
117 {
118 ReferenceObject::init(object: nullptr, property: -1, flags: {});
119 m_date.init(value: dateTime);
120 }
121
122 void init(const QDateTime &dateTime)
123 {
124 ReferenceObject::init(object: nullptr, property: -1, flags: {});
125 m_date.init(dateTime);
126 }
127
128 void init(const QDateTime &dateTime, Heap::Object *parent, int property, Flags flags)
129 {
130 ReferenceObject::init(object: parent, property, flags: flags | EnforcesLocation);
131 doSetLocation();
132 m_date.init(dateTime);
133 };
134
135 void init(QDate date, Heap::Object *parent, int property, Flags flags)
136 {
137 ReferenceObject::init(object: parent, property, flags: flags | EnforcesLocation);
138 doSetLocation();
139 m_date.init(date);
140 };
141
142 void init(QTime time, Heap::Object *parent, int property, Flags flags)
143 {
144 ReferenceObject::init(object: parent, property, flags: flags | EnforcesLocation);
145 doSetLocation();
146 m_date.init(time, engine: internalClass->engine);
147 };
148
149 void setDate(double newDate)
150 {
151 m_date = newDate;
152 if (isAttachedToProperty())
153 writeBack();
154 }
155
156 double date() const
157 {
158 return m_date;
159 }
160
161 QVariant toVariant() const { return m_date.toVariant(); }
162 QDateTime toQDateTime() const { return m_date.toQDateTime(); }
163
164private:
165 bool writeBack()
166 {
167 if (!object() || !canWriteBack())
168 return false;
169
170 QV4::Scope scope(internalClass->engine);
171 QV4::ScopedObject o(scope, object());
172
173 int flags = 0;
174 int status = -1;
175 if (isVariant()) {
176 QVariant variant = toVariant();
177 void *a[] = { &variant, nullptr, &status, &flags };
178 return o->metacall(call: QMetaObject::WriteProperty, index: property(), a);
179 }
180
181 return m_date.withStoragePointer(function: [&](void *storagePointer) {
182 void *a[] = { storagePointer, nullptr, &status, &flags };
183 return o->metacall(call: QMetaObject::WriteProperty, index: property(), a);
184 });
185 }
186
187 Date m_date;
188};
189
190
191struct DateCtor : FunctionObject {
192 void init(QV4::ExecutionContext *scope);
193};
194
195}
196
197struct DateObject: ReferenceObject {
198 V4_OBJECT2(DateObject, ReferenceObject)
199 Q_MANAGED_TYPE(DateObject)
200 V4_PROTOTYPE(datePrototype)
201
202 void setDate(double date) { d()->setDate(date); }
203 double date() const { return d()->date(); }
204
205 Q_QML_PRIVATE_EXPORT QDateTime toQDateTime() const;
206 QString toString() const;
207
208 static QString dateTimeToString(const QDateTime &dateTime, ExecutionEngine *engine);
209 static QDate dateTimeToDate(const QDateTime &dateTime);
210 static QDateTime stringToDateTime(const QString &string, ExecutionEngine *engine);
211};
212
213template<>
214inline const DateObject *Value::as() const {
215 return isManaged() && m()->internalClass->vtable->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : nullptr;
216}
217
218struct DateCtor: FunctionObject
219{
220 V4_OBJECT2(DateCtor, FunctionObject)
221
222 static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *);
223 static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int);
224};
225
226struct DatePrototype: Object
227{
228 V4_PROTOTYPE(objectPrototype)
229
230 void init(ExecutionEngine *engine, Object *ctor);
231
232 static double getThisDate(ExecutionEngine *v4, const Value *thisObject);
233
234 static ReturnedValue method_parse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
235 static ReturnedValue method_UTC(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
236 static ReturnedValue method_now(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
237
238 static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
239 static ReturnedValue method_toDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
240 static ReturnedValue method_toTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
241 static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
242 static ReturnedValue method_toLocaleDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
243 static ReturnedValue method_toLocaleTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
244 static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
245 static ReturnedValue method_getTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
246 static ReturnedValue method_getYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
247 static ReturnedValue method_getFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
248 static ReturnedValue method_getUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
249 static ReturnedValue method_getMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
250 static ReturnedValue method_getUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
251 static ReturnedValue method_getDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
252 static ReturnedValue method_getUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
253 static ReturnedValue method_getDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
254 static ReturnedValue method_getUTCDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
255 static ReturnedValue method_getHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
256 static ReturnedValue method_getUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
257 static ReturnedValue method_getMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
258 static ReturnedValue method_getUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
259 static ReturnedValue method_getSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
260 static ReturnedValue method_getUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
261 static ReturnedValue method_getMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
262 static ReturnedValue method_getUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
263 static ReturnedValue method_getTimezoneOffset(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
264 static ReturnedValue method_setTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
265 static ReturnedValue method_setMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
266 static ReturnedValue method_setUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
267 static ReturnedValue method_setSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
268 static ReturnedValue method_setUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
269 static ReturnedValue method_setMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
270 static ReturnedValue method_setUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
271 static ReturnedValue method_setHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
272 static ReturnedValue method_setUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
273 static ReturnedValue method_setDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
274 static ReturnedValue method_setUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
275 static ReturnedValue method_setMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
276 static ReturnedValue method_setUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
277 static ReturnedValue method_setYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
278 static ReturnedValue method_setFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
279 static ReturnedValue method_setUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
280 static ReturnedValue method_toUTCString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
281 static ReturnedValue method_toISOString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
282 static ReturnedValue method_toJSON(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
283 static ReturnedValue method_symbolToPrimitive(const FunctionObject *f, const Value *thisObject, const Value *, int);
284
285 static void timezoneUpdated(ExecutionEngine *e);
286};
287
288}
289
290QT_END_NAMESPACE
291
292#endif // QV4ECMAOBJECTS_P_H
293

source code of qtdeclarative/src/qml/jsruntime/qv4dateobject_p.h