1/*
2    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
3
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the License, or (at your option) any later version.
8
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public License
15    along with this library; see the file COPYING.LIB.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17    Boston, MA 02110-1301, USA.
18*/
19
20#include "config.h"
21
22#include "qscriptvalue.h"
23
24#include "qscriptengine.h"
25#include "qscriptengine_p.h"
26#include "qscriptvalue_p.h"
27#include <QtCore/qdebug.h>
28
29/*!
30    Constructs an invalid value.
31*/
32QScriptValue::QScriptValue()
33    : d_ptr(new QScriptValuePrivate())
34{
35}
36
37/*!
38  Constructs a new QScriptValue with a boolean \a value.
39*/
40QScriptValue::QScriptValue(bool value)
41    : d_ptr(new QScriptValuePrivate(value))
42{
43}
44
45/*!
46  Constructs a new QScriptValue with a number \a value.
47*/
48QScriptValue::QScriptValue(int value)
49    : d_ptr(new QScriptValuePrivate(value))
50{
51}
52
53/*!
54  Constructs a new QScriptValue with a number \a value.
55*/
56QScriptValue::QScriptValue(uint value)
57    : d_ptr(new QScriptValuePrivate(value))
58{
59}
60
61/*!
62  Constructs a new QScriptValue with a number \a value.
63*/
64QScriptValue::QScriptValue(qsreal value)
65    : d_ptr(new QScriptValuePrivate(value))
66{
67}
68
69/*!
70  Constructs a new QScriptValue with a string \a value.
71*/
72QScriptValue::QScriptValue(const QString& value)
73    : d_ptr(new QScriptValuePrivate(value))
74{
75}
76
77/*!
78  Constructs a new QScriptValue with a special \a value.
79*/
80QScriptValue::QScriptValue(SpecialValue value)
81    : d_ptr(new QScriptValuePrivate(value))
82{
83}
84
85/*!
86  Constructs a new QScriptValue with a string \a value.
87*/
88QScriptValue::QScriptValue(const char* value)
89    : d_ptr(new QScriptValuePrivate(QString::fromUtf8(value)))
90{
91}
92
93/*!
94    Block automatic convertion to bool
95    \internal
96*/
97QScriptValue::QScriptValue(void* d)
98{
99    Q_ASSERT(false);
100}
101
102/*!
103    Constructs a new QScriptValue from private
104    \internal
105*/
106QScriptValue::QScriptValue(QScriptValuePrivate* d)
107    : d_ptr(d)
108{
109}
110
111/*!
112  \obsolete
113
114  Constructs a new QScriptValue with the boolean \a value and
115  registers it with the script \a engine.
116*/
117QScriptValue::QScriptValue(QScriptEngine* engine, bool value)
118    : d_ptr(new QScriptValuePrivate(engine, value))
119{
120}
121
122/*!
123  \obsolete
124
125  Constructs a new QScriptValue with the integer \a value and
126  registers it with the script \a engine.
127*/
128QScriptValue::QScriptValue(QScriptEngine* engine, int value)
129    : d_ptr(new QScriptValuePrivate(engine, value))
130{
131}
132
133/*!
134  \obsolete
135
136  Constructs a new QScriptValue with the unsigned integer \a value and
137  registers it with the script \a engine.
138 */
139QScriptValue::QScriptValue(QScriptEngine* engine, uint value)
140    : d_ptr(new QScriptValuePrivate(engine, value))
141{
142}
143
144/*!
145  \obsolete
146
147  Constructs a new QScriptValue with the qsreal \a value and
148  registers it with the script \a engine.
149*/
150QScriptValue::QScriptValue(QScriptEngine* engine, qsreal value)
151    : d_ptr(new QScriptValuePrivate(engine, value))
152{
153}
154
155/*!
156  \obsolete
157
158  Constructs a new QScriptValue with the string \a value and
159  registers it with the script \a engine.
160*/
161QScriptValue::QScriptValue(QScriptEngine* engine, const QString& value)
162    : d_ptr(new QScriptValuePrivate(engine, value))
163{
164}
165
166/*!
167  \obsolete
168
169  Constructs a new QScriptValue with the string \a value and
170  registers it with the script \a engine.
171*/
172QScriptValue::QScriptValue(QScriptEngine* engine, const char* value)
173    : d_ptr(new QScriptValuePrivate(engine, QString::fromUtf8(value)))
174{
175}
176
177/*!
178  \obsolete
179
180  Constructs a new QScriptValue with the special \a value and
181  registers it with the script \a engine.
182*/
183QScriptValue::QScriptValue(QScriptEngine* engine, SpecialValue value)
184    : d_ptr(new QScriptValuePrivate(engine, value))
185{
186}
187
188/*!
189  Constructs a new QScriptValue that is a copy of \a other.
190
191  Note that if \a other is an object (i.e., isObject() would return
192  true), then only a reference to the underlying object is copied into
193  the new script value (i.e., the object itself is not copied).
194*/
195QScriptValue::QScriptValue(const QScriptValue& other)
196    : d_ptr(other.d_ptr)
197{
198}
199
200/*!
201    Destroys this QScriptValue.
202*/
203QScriptValue::~QScriptValue()
204{
205}
206
207/*!
208  Returns true if this QScriptValue is valid; otherwise returns
209  false.
210*/
211bool QScriptValue::isValid() const
212{
213    return d_ptr->isValid();
214}
215
216/*!
217  Returns true if this QScriptValue is of the primitive type Boolean;
218  otherwise returns false.
219
220  \sa toBool()
221*/
222bool QScriptValue::isBool() const
223{
224    return d_ptr->isBool();
225}
226
227/*!
228  \obsolete
229
230  Use isBool() instead.
231  Returns true if this QScriptValue is of the primitive type Boolean;
232  otherwise returns false.
233*/
234bool QScriptValue::isBoolean() const
235{
236    return d_ptr->isBool();
237}
238
239/*!
240  Returns true if this QScriptValue is of the primitive type Number;
241  otherwise returns false.
242
243  \sa toNumber()
244*/
245bool QScriptValue::isNumber() const
246{
247    return d_ptr->isNumber();
248}
249
250/*!
251  Returns true if this QScriptValue is of the primitive type Null;
252  otherwise returns false.
253
254  \sa QScriptEngine::nullValue()
255*/
256bool QScriptValue::isNull() const
257{
258    return d_ptr->isNull();
259}
260
261/*!
262  Returns true if this QScriptValue is of the primitive type String;
263  otherwise returns false.
264
265  \sa toString()
266*/
267bool QScriptValue::isString() const
268{
269    return d_ptr->isString();
270}
271
272/*!
273  Returns true if this QScriptValue is of the primitive type Undefined;
274  otherwise returns false.
275
276  \sa QScriptEngine::undefinedValue()
277*/
278bool QScriptValue::isUndefined() const
279{
280    return d_ptr->isUndefined();
281}
282
283/*!
284  Returns true if this QScriptValue is an object of the Error class;
285  otherwise returns false.
286
287  \sa QScriptContext::throwError()
288*/
289bool QScriptValue::isError() const
290{
291    return d_ptr->isError();
292}
293
294/*!
295  Returns true if this QScriptValue is of the Object type; otherwise
296  returns false.
297
298  Note that function values, variant values, and QObject values are
299  objects, so this function returns true for such values.
300
301  \sa toObject(), QScriptEngine::newObject()
302*/
303bool QScriptValue::isObject() const
304{
305    return d_ptr->isObject();
306}
307
308/*!
309  Returns true if this QScriptValue is a function; otherwise returns
310  false.
311
312  \sa call()
313*/
314bool QScriptValue::isFunction() const
315{
316    return d_ptr->isFunction();
317}
318
319/*!
320  Returns the string value of this QScriptValue, as defined in
321  \l{ECMA-262} section 9.8, "ToString".
322
323  Note that if this QScriptValue is an object, calling this function
324  has side effects on the script engine, since the engine will call
325  the object's toString() function (and possibly valueOf()) in an
326  attempt to convert the object to a primitive value (possibly
327  resulting in an uncaught script exception).
328
329  \sa isString()
330*/
331QString QScriptValue::toString() const
332{
333    return d_ptr->toString();
334}
335
336/*!
337  Returns the number value of this QScriptValue, as defined in
338  \l{ECMA-262} section 9.3, "ToNumber".
339
340  Note that if this QScriptValue is an object, calling this function
341  has side effects on the script engine, since the engine will call
342  the object's valueOf() function (and possibly toString()) in an
343  attempt to convert the object to a primitive value (possibly
344  resulting in an uncaught script exception).
345
346  \sa isNumber(), toInteger(), toInt32(), toUInt32(), toUInt16()
347*/
348qsreal QScriptValue::toNumber() const
349{
350    return d_ptr->toNumber();
351}
352
353/*!
354  Returns the boolean value of this QScriptValue, using the conversion
355  rules described in \l{ECMA-262} section 9.2, "ToBoolean".
356
357  Note that if this QScriptValue is an object, calling this function
358  has side effects on the script engine, since the engine will call
359  the object's valueOf() function (and possibly toString()) in an
360  attempt to convert the object to a primitive value (possibly
361  resulting in an uncaught script exception).
362
363  \sa isBool()
364*/
365bool QScriptValue::toBool() const
366{
367    return d_ptr->toBool();
368}
369
370/*!
371  \obsolete
372
373  Use toBool() instead.
374*/
375bool QScriptValue::toBoolean() const
376{
377    return d_ptr->toBool();
378}
379
380/*!
381  Returns the integer value of this QScriptValue, using the conversion
382  rules described in \l{ECMA-262} section 9.4, "ToInteger".
383
384  Note that if this QScriptValue is an object, calling this function
385  has side effects on the script engine, since the engine will call
386  the object's valueOf() function (and possibly toString()) in an
387  attempt to convert the object to a primitive value (possibly
388  resulting in an uncaught script exception).
389
390  \sa toNumber()
391*/
392qsreal QScriptValue::toInteger() const
393{
394    return d_ptr->toInteger();
395}
396
397/*!
398  Returns the signed 32-bit integer value of this QScriptValue, using
399  the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32".
400
401  Note that if this QScriptValue is an object, calling this function
402  has side effects on the script engine, since the engine will call
403  the object's valueOf() function (and possibly toString()) in an
404  attempt to convert the object to a primitive value (possibly
405  resulting in an uncaught script exception).
406
407  \sa toNumber(), toUInt32()
408*/
409qint32 QScriptValue::toInt32() const
410{
411    return d_ptr->toInt32();
412}
413
414/*!
415  Returns the unsigned 32-bit integer value of this QScriptValue, using
416  the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32".
417
418  Note that if this QScriptValue is an object, calling this function
419  has side effects on the script engine, since the engine will call
420  the object's valueOf() function (and possibly toString()) in an
421  attempt to convert the object to a primitive value (possibly
422  resulting in an uncaught script exception).
423
424  \sa toNumber(), toInt32()
425*/
426quint32 QScriptValue::toUInt32() const
427{
428    return d_ptr->toUInt32();
429}
430
431/*!
432  Returns the unsigned 16-bit integer value of this QScriptValue, using
433  the conversion rules described in \l{ECMA-262} section 9.7, "ToUint16".
434
435  Note that if this QScriptValue is an object, calling this function
436  has side effects on the script engine, since the engine will call
437  the object's valueOf() function (and possibly toString()) in an
438  attempt to convert the object to a primitive value (possibly
439  resulting in an uncaught script exception).
440
441  \sa toNumber()
442*/
443quint16 QScriptValue::toUInt16() const
444{
445    return d_ptr->toUInt16();
446}
447
448/*!
449  Calls this QScriptValue as a function, using \a thisObject as
450  the `this' object in the function call, and passing \a args
451  as arguments to the function. Returns the value returned from
452  the function.
453
454  If this QScriptValue is not a function, call() does nothing
455  and returns an invalid QScriptValue.
456
457  Note that if \a thisObject is not an object, the global object
458  (see \l{QScriptEngine::globalObject()}) will be used as the
459  `this' object.
460
461  Calling call() can cause an exception to occur in the script engine;
462  in that case, call() returns the value that was thrown (typically an
463  \c{Error} object). You can call
464  QScriptEngine::hasUncaughtException() to determine if an exception
465  occurred.
466
467  \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2
468
469  \sa construct()
470*/
471QScriptValue QScriptValue::call(const QScriptValue& thisObject, const QScriptValueList& args)
472{
473    return d_ptr->call(thisObject.d_ptr.data(), args);
474}
475
476/*!
477  Returns the QScriptEngine that created this QScriptValue,
478  or 0 if this QScriptValue is invalid or the value is not
479  associated with a particular engine.
480*/
481QScriptEngine* QScriptValue::engine() const
482{
483    QScriptEnginePrivate* engine = d_ptr->engine();
484    if (engine)
485        return QScriptEnginePrivate::get(engine);
486    return 0;
487}
488
489/*!
490  Assigns the \a other value to this QScriptValue.
491
492  Note that if \a other is an object (isObject() returns true),
493  only a reference to the underlying object will be assigned;
494  the object itself will not be copied.
495*/
496QScriptValue& QScriptValue::operator=(const QScriptValue& other)
497{
498    d_ptr = other.d_ptr;
499    return *this;
500}
501
502/*!
503  Returns true if this QScriptValue is equal to \a other, otherwise
504  returns false. The comparison follows the behavior described in
505  \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison
506  Algorithm".
507
508  This function can return true even if the type of this QScriptValue
509  is different from the type of the \a other value; i.e. the
510  comparison is not strict.  For example, comparing the number 9 to
511  the string "9" returns true; comparing an undefined value to a null
512  value returns true; comparing a \c{Number} object whose primitive
513  value is 6 to a \c{String} object whose primitive value is "6"
514  returns true; and comparing the number 1 to the boolean value
515  \c{true} returns true. If you want to perform a comparison
516  without such implicit value conversion, use strictlyEquals().
517
518  Note that if this QScriptValue or the \a other value are objects,
519  calling this function has side effects on the script engine, since
520  the engine will call the object's valueOf() function (and possibly
521  toString()) in an attempt to convert the object to a primitive value
522  (possibly resulting in an uncaught script exception).
523
524  \sa strictlyEquals(), lessThan()
525*/
526bool QScriptValue::equals(const QScriptValue& other) const
527{
528    return d_ptr == other.d_ptr || d_ptr->equals(QScriptValuePrivate::get(other));
529}
530
531/*!
532  Returns true if this QScriptValue is equal to \a other using strict
533  comparison (no conversion), otherwise returns false. The comparison
534  follows the behavior described in \l{ECMA-262} section 11.9.6, "The
535  Strict Equality Comparison Algorithm".
536
537  If the type of this QScriptValue is different from the type of the
538  \a other value, this function returns false. If the types are equal,
539  the result depends on the type, as shown in the following table:
540
541    \table
542    \header \o Type \o Result
543    \row    \o Undefined  \o true
544    \row    \o Null       \o true
545    \row    \o Boolean    \o true if both values are true, false otherwise
546    \row    \o Number     \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise
547    \row    \o String     \o true if both values are exactly the same sequence of characters, false otherwise
548    \row    \o Object     \o true if both values refer to the same object, false otherwise
549    \endtable
550
551  \sa equals()
552*/
553bool QScriptValue::strictlyEquals(const QScriptValue& other) const
554{
555    return d_ptr == other.d_ptr || d_ptr->strictlyEquals(QScriptValuePrivate::get(other));
556}
557