diff options
Diffstat (limited to 'src/script/qscriptecmaglobal.cpp')
-rw-r--r-- | src/script/qscriptecmaglobal.cpp | 571 |
1 files changed, 0 insertions, 571 deletions
diff --git a/src/script/qscriptecmaglobal.cpp b/src/script/qscriptecmaglobal.cpp deleted file mode 100644 index 10d3343..0000000 --- a/src/script/qscriptecmaglobal.cpp +++ /dev/null @@ -1,571 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// for strtoll -#include <qplatformdefs.h> - -#ifndef QT_NO_SCRIPT - -#include "qscriptecmaglobal_p.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QVarLengthArray> -#include <QtCore/qnumeric.h> - -QT_BEGIN_NAMESPACE - -extern double qstrtod(const char *s00, char const **se, bool *ok); - -namespace QScript { - -extern qsreal integerFromString(const QString &str, int radix); - -static inline char toHex(char c) -{ - static const char hexnumbers[] = "0123456789ABCDEF"; - return hexnumbers[c & 0xf]; -} - -static int fromHex(char c) -{ - if ((c >= '0') && (c <= '9')) - return c - '0'; - if ((c >= 'A') && (c <= 'F')) - return c - 'A' + 10; - if ((c >= 'a') && (c <= 'f')) - return c - 'a' + 10; - return -1; -} - -static QByteArray escape(const QString &input) -{ - QVarLengthArray<char> output; - output.reserve(input.size() * 3); - const int length = input.length(); - for (int i = 0; i < length; ++i) { - ushort uc = input.at(i).unicode(); - if (uc < 0x100) { - if ( (uc > 0x60 && uc < 0x7B) - || (uc > 0x3F && uc < 0x5B) - || (uc > 0x2C && uc < 0x3A) - || (uc == 0x2A) - || (uc == 0x2B) - || (uc == 0x5F)) { - output.append(char(uc)); - } else { - output.append('%'); - output.append(toHex(uc >> 4)); - output.append(toHex(uc)); - } - } else { - output.append('%'); - output.append('u'); - output.append(toHex(uc >> 12)); - output.append(toHex(uc >> 8)); - output.append(toHex(uc >> 4)); - output.append(toHex(uc)); - } - } - return QByteArray(output.constData(), output.size()); -} - -static QString unescape(const QByteArray &input) -{ - QString result; - int i = 0; - const int length = input.length(); - while (i < length) { - char c = input.at(i++); - if ((c == '%') && (i + 1 < length)) { - char a = input.at(i); - if ((a == 'u') && (i + 4 < length)) { - int d3 = fromHex(input.at(i+1)); - int d2 = fromHex(input.at(i+2)); - int d1 = fromHex(input.at(i+3)); - int d0 = fromHex(input.at(i+4)); - if ((d3 != -1) && (d2 != -1) && (d1 != -1) && (d0 != -1)) { - ushort uc = ushort((d3 << 12) | (d2 << 8) | (d1 << 4) | d0); - result.append(QChar(uc)); - i += 5; - } else { - result.append(QLatin1Char(c)); - } - } else { - int d1 = fromHex(a); - int d0 = fromHex(input.at(i+1)); - if ((d1 != -1) && (d0 != -1)) { - c = (d1 << 4) | d0; - i += 2; - } - result.append(QLatin1Char(c)); - } - } else { - result.append(QLatin1Char(c)); - } - } - return result; -} - -static const char uriReserved[] = ";/?:@&=+$,"; -static const char uriUnescaped[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'()"; - -static QString encode(const QString &input, const QString &unescapedSet, bool *ok) -{ - QString output; - const int length = input.length(); - int i = 0; - while (i < length) { - const QChar c = input.at(i); - if (!unescapedSet.contains(c)) { - ushort uc = c.unicode(); - if ((uc >= 0xDC00) && (uc <= 0xDFFF)) { - // URIError - break; - } - if (!((uc < 0xD800) || (uc > 0xDBFF))) { - ++i; - if (i == length) { - // URIError - break; - } - const ushort uc2 = input.at(i).unicode(); - if ((uc < 0xDC00) || (uc > 0xDFFF)) { - // URIError - break; - } - uc = ((uc - 0xD800) * 0x400) + (uc2 - 0xDC00) + 0x10000; - } - QString tmp(1, QChar(uc)); - QByteArray octets = tmp.toUtf8(); - for (int j = 0; j < octets.length(); ++j) { - output.append(QLatin1Char('%')); - output.append(QLatin1Char(toHex(octets.at(j) >> 4))); - output.append(QLatin1Char(toHex(octets.at(j)))); - } - } else { - output.append(c); - } - ++i; - } - *ok = (i == length); - return output; -} - -static QString decode(const QString &input, const QString &reservedSet, bool *ok) -{ - QString output; - const int length = input.length(); - int i = 0; - const QChar percent = QLatin1Char('%'); - while (i < length) { - const QChar c = input.at(i); - if (c == percent) { - int start = i; - if (i + 2 >= length) { - // URIError - break; - } - int d1 = fromHex(input.at(i+1).toLatin1()); - int d0 = fromHex(input.at(i+2).toLatin1()); - if ((d1 == -1) || (d0 == -1)) { - // URIError - break; - } - int b = (d1 << 4) | d0; - i += 2; - if (b & 0x80) { - int n = -1; - while ((b << ++n) & 0x80) ; - if ((n == 1) || (n > 4)) { - // URIError - break; - } - QByteArray octets; - octets.append(b); - if (i + (3 * (n - 1)) >= length) { - // URIError - break; - } - for (int j = 1; j < n; ++j) { - ++i; - if (input.at(i) != percent) { - // URIError - break; - } - d1 = fromHex(input.at(i+1).toLatin1()); - d0 = fromHex(input.at(i+2).toLatin1()); - if ((d1 == -1) || (d0 == -1)) { - // URIError - break; - } - b = (d1 << 4) | d0; - if ((b & 0xC0) != 0x80) { - // URIError - break; - } - i += 2; - octets.append(b); - } - QString tmp = QString::fromUtf8(octets); - Q_ASSERT(tmp.length() == 1); - uint v = tmp.at(0).unicode(); // ### need 32-bit value - if (v < 0x10000) { - QChar z = QChar(ushort(v)); - if (!reservedSet.contains(z)) { - output.append(z); - } else { - output.append(input.mid(start, i - start + 1)); - } - } else { - if (v > 0x10FFFF) { - // URIError - break; - } - ushort l = ushort(((v - 0x10000) & 0x3FF) + 0xDC00); - ushort h = ushort((((v - 0x10000) >> 10) & 0x3FF) + 0xD800); - output.append(QChar(l)); - output.append(QChar(h)); - } - } else { - output.append(ushort(b)); - } - } else { - output.append(c); - } - ++i; - } - *ok = (i == length); - return output; -} - -class PrintFunction : public QScriptFunction -{ -public: - PrintFunction() {} - - virtual ~PrintFunction() {} - - virtual void execute(QScriptContextPrivate *context) - { - QScriptEnginePrivate *eng = context->engine(); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng->notifyFunctionEntry(context); -#endif - QString result; - for (int i = 0; i < context->argumentCount(); ++i) { - if (i != 0) - result.append(QLatin1Char(' ')); - - QString s = context->argument(i).toString(); - if (context->state() == QScriptContext::ExceptionState) - break; - result.append(s); - } - - if (context->state() != QScriptContext::ExceptionState) { - qDebug(qPrintable(result)); - context->setReturnValue(eng->undefinedValue()); - } -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng->notifyFunctionExit(context); -#endif - } - - QString functionName() const - { - return QLatin1String("print"); - } -}; - -} // anonumous - -namespace QScript { namespace Ecma { - -Global::Global(QScriptEnginePrivate *engine, QScriptClassInfo *classInfo) - : m_engine(engine), m_classInfo(classInfo) -{ -} - -Global::~Global() -{ -} - -void Global::construct(QScriptValueImpl *object, QScriptEnginePrivate *eng) -{ - QScriptClassInfo *classInfo = eng->registerClass(QLatin1String("global"), - QScriptClassInfo::ActivationType); - - // create with prototype null, since Object.prototype doesn't exist at this point - eng->newObject(object, eng->nullValue(), classInfo); - - Global *instance = new Global(eng, classInfo); - object->setObjectData(instance); -} - -void Global::initialize(QScriptValueImpl *object, QScriptEnginePrivate *eng) -{ - // set the real prototype - object->setPrototype(eng->objectConstructor->publicPrototype); - - const QScriptValue::PropertyFlags flags = QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration; - - object->setProperty(QLatin1String("NaN"), QScriptValueImpl(qSNaN()), flags); - object->setProperty(QLatin1String("Infinity"), QScriptValueImpl(qInf()), flags); - object->setProperty(QLatin1String("undefined"), eng->undefinedValue(), flags); - - object->setProperty(QLatin1String("print"), - eng->createFunction(new PrintFunction()), flags); - addFunction(*object, QLatin1String("parseInt"), method_parseInt, 2, flags); - addFunction(*object, QLatin1String("parseFloat"), method_parseFloat, 1, flags); - addFunction(*object, QLatin1String("isNaN"), method_isNaN, 1, flags); - addFunction(*object, QLatin1String("isFinite"), method_isFinite, 1, flags); - addFunction(*object, QLatin1String("decodeURI"), method_decodeURI, 1, flags); - addFunction(*object, QLatin1String("decodeURIComponent"), method_decodeURIComponent, 1, flags); - addFunction(*object, QLatin1String("encodeURI"), method_encodeURI, 1, flags); - addFunction(*object, QLatin1String("encodeURIComponent"), method_encodeURIComponent, 1, flags); - addFunction(*object, QLatin1String("escape"), method_escape, 1, flags); - addFunction(*object, QLatin1String("unescape"), method_unescape, 1, flags); - addFunction(*object, QLatin1String("version"), method_version, 0, flags); - addFunction(*object, QLatin1String("gc"), method_gc, 0, flags); -} - -QScriptValueImpl Global::method_parseInt(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - if (context->argumentCount() == 0) - return qSNaN(); - - qsreal radix = 0; - if (context->argumentCount() > 1) { - radix = context->argument(1).toInteger(); - if (qIsNaN(radix) || (radix && (radix < 2 || radix > 36))) { - return qSNaN(); - } - } - - return QScript::integerFromString(context->argument(0).toString(), static_cast<int>(radix)); -} - -QScriptValueImpl Global::method_parseFloat(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - if (context->argumentCount() == 0) - return QScriptValueImpl(qSNaN()); - QString str = context->argument(0).toString().trimmed(); - QByteArray latin1 = str.toLatin1(); - const char *data = latin1.constData(); - const char *eptr = 0; - qsreal result = qstrtod(data, &eptr, 0); - if (eptr == data) { - if (str == QLatin1String("Infinity")) - result = +qInf(); - else if (str == QLatin1String("+Infinity")) - result = +qInf(); - else if (str == QLatin1String("-Infinity")) - result = -qInf(); - else - result = qSNaN(); - } - return result; -} - -QScriptValueImpl Global::method_isNaN(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = qSNaN(); - if (context->argumentCount() > 0) - v = context->argument(0).toNumber(); - return (QScriptValueImpl(qIsNaN(v))); -} - -QScriptValueImpl Global::method_isFinite(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = qInf(); - if (context->argumentCount() > 0) - v = context->argument(0).toNumber(); - return (QScriptValueImpl(qIsFinite(v))); -} - -QScriptValueImpl Global::method_decodeURI(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl result; - - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - bool ok; - QString out = decode(str, QString::fromUtf8(uriReserved) + QString::fromUtf8("#"), &ok); - if (ok) - return QScriptValueImpl(eng, out); - else - return context->throwError(QScriptContext::URIError, - QLatin1String("malformed URI sequence")); - } - - return eng->undefinedValue(); -} - -QScriptValueImpl Global::method_decodeURIComponent(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - bool ok; - QString out = decode(str, QString::fromUtf8(""), &ok); - if (ok) - result = QScriptValueImpl(eng, out); - else - result = context->throwError(QScriptContext::URIError, - QLatin1String("malformed URI sequence")); - } else { - result = eng->undefinedValue(); - } - return result; -} - -QScriptValueImpl Global::method_encodeURI(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - bool ok; - QString out = encode(str, - QLatin1String(uriReserved) - + QLatin1String(uriUnescaped) - + QString::fromUtf8("#"), - &ok); - if (ok) - result = QScriptValueImpl(eng, out); - else - result = context->throwError(QScriptContext::URIError, - QLatin1String("malformed URI sequence")); - } else { - result = eng->undefinedValue(); - } - return result; -} - -QScriptValueImpl Global::method_encodeURIComponent(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - bool ok; - QString out = encode(str, QLatin1String(uriUnescaped), &ok); - if (ok) - result = QScriptValueImpl(eng, out); - else - result = context->throwError(QScriptContext::URIError, - QLatin1String("malformed URI sequence")); - } else { - result = eng->undefinedValue(); - } - return result; -} - -QScriptValueImpl Global::method_escape(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - return QScriptValueImpl(eng, QLatin1String(escape(str))); - } - return QScriptValueImpl(eng, QLatin1String("undefined")); -} - -QScriptValueImpl Global::method_unescape(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - if (context->argumentCount() > 0) { - QByteArray data = context->argument(0).toString().toLatin1(); - return QScriptValueImpl(eng, unescape(data)); - } - return QScriptValueImpl(eng, QLatin1String("undefined")); -} - -QScriptValueImpl Global::method_version(QScriptContextPrivate *, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - return (QScriptValueImpl(1)); -} - -QScriptValueImpl Global::method_gc(QScriptContextPrivate *, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - eng->gc(); - return QScriptValueImpl(eng->objectAllocator.freeBlocks()); -} - -void Global::addFunction(QScriptValueImpl &object, const QString &name, - QScriptInternalFunctionSignature fun, int length, - const QScriptValue::PropertyFlags flags) -{ - QScriptEnginePrivate *eng_p = object.engine(); - QScriptValueImpl val = eng_p->createFunction(fun, length, object.classInfo(), name); - object.setProperty(name, val, flags); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT |