📄 qscriptecmaarray.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtScript module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.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 GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qscriptecmaarray_p.h"#ifndef QT_NO_SCRIPT#include "qscriptengine_p.h"#include "qscriptvalueimpl_p.h"#include "qscriptcontext_p.h"#include "qscriptmember_p.h"#include "qscriptobject_p.h"#include <QtCore/QtDebug>namespace QScript { namespace Ecma {Array::ArrayClassData::ArrayClassData(QScriptClassInfo *classInfo): m_classInfo(classInfo){}Array::ArrayClassData::~ArrayClassData(){}void Array::ArrayClassData::mark(const QScriptValueImpl &object, int generation){ Instance *instance = Instance::get(object, classInfo()); if (! instance) return; instance->value.mark(generation);}bool Array::ArrayClassData::resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, QScript::Member *member, QScriptValueImpl *base){ QScriptEngine *eng = object.engine(); QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(eng); if (Instance::get(object, classInfo())) { if (nameId == eng_p->idTable()->id_length) { member->native(nameId, /*id=*/ 0, QScriptValue::Undeletable); *base = object; return true; } QString propertyName = eng_p->toString(nameId); bool isNumber; quint32 pos = propertyName.toUInt(&isNumber); if (isNumber && (QScriptValue(eng, pos).toString() == propertyName)) { // ### improve me member->native(0, pos, QScriptValue::Undeletable); *base = object; return true; } } return false;}bool Array::ArrayClassData::get(const QScriptValueImpl &object, const QScript::Member &member, QScriptValueImpl *result){ Q_ASSERT(member.isValid()); if (! member.isNativeProperty()) return false; QScriptEnginePrivate *eng = QScriptEnginePrivate::get(object.engine()); Instance *instance = Instance::get(object, classInfo()); if (! instance) return false; if (member.nameId() == eng->idTable()->id_length) eng->newNumber(result, instance->value.count()); else { quint32 pos = quint32 (member.id()); if (pos < instance->value.count()) *result = instance->value.at(pos); else eng->newUndefined(result); } return true;}bool Array::ArrayClassData::put(QScriptValueImpl *object, const QScript::Member &member, const QScriptValueImpl &value){ Q_ASSERT(object != 0); Q_ASSERT(member.isValid()); if (! member.isNativeProperty()) return false; Instance *instance = Instance::get(*object, classInfo()); if (! instance) return false; QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(object->engine()); if (member.nameId() == eng_p->idTable()->id_length) { qsreal length = value.toNumber(); quint32 len = eng_p->toUint32(length); instance->value.resize(len); } else if (member.nameId() == 0) { quint32 pos = quint32 (member.id()); instance->value.assign(pos, value); } return true;}int Array::ArrayClassData::extraMemberCount(const QScriptValueImpl &object){ if (Instance *instance = Instance::get(object, classInfo())) { return instance->value.count(); } return 0;}bool Array::ArrayClassData::extraMember(const QScriptValueImpl &object, int index, QScript::Member *member){ if (Instance::get(object, classInfo())) { member->native(/*nameId=*/ 0, index, QScriptValue::Undeletable); return true; } return false;}Array::Array(QScriptEnginePrivate *eng): Core(eng){ m_classInfo = eng->registerClass(QLatin1String("Array")); QExplicitlySharedDataPointer<QScriptClassData> data(new ArrayClassData(m_classInfo)); m_classInfo->setData(data); publicPrototype.invalidate(); newArray(&publicPrototype); eng->newConstructor(&ctor, this, publicPrototype); QScriptValue::PropertyFlags flags = QScriptValue::SkipInEnumeration; publicPrototype.setProperty(QLatin1String("toString"), eng->createFunction(method_toString, 0, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("toLocaleString"), eng->createFunction(method_toLocaleString, 0, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("concat"), eng->createFunction(method_concat, 0, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("join"), eng->createFunction(method_join, 1, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("pop"), eng->createFunction(method_pop, 0, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("push"), eng->createFunction(method_push, 1, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("reverse"), eng->createFunction(method_reverse, 0, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("shift"), eng->createFunction(method_shift, 0, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("slice"), eng->createFunction(method_slice, 0, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("sort"), eng->createFunction(method_sort, 1, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("splice"), eng->createFunction(method_splice, 1, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("unshift"), eng->createFunction(method_unshift, 1, m_classInfo), flags);}Array::~Array(){}void Array::execute(QScriptContextPrivate *context){ QScript::Array value; if (context->argumentCount() == 1 && context->argument(0).isNumber()) { qsreal size = context->argument(0).toNumber(); quint32 isize = QScriptEnginePrivate::toUint32(size); if (size != qsreal(isize)) { context->throwError(QScriptContext::RangeError, QLatin1String("invalid array length")); return; } value.resize(isize); } else { for (int i = 0; i < context->argumentCount(); ++i) { value.assign(i, context->argument(i)); } } newArray(&context->m_result, value);}void Array::newArray(QScriptValueImpl *result, const QScript::Array &value){ Instance *instance = new Instance(); instance->value = value; engine()->newObject(result, publicPrototype, classInfo()); result->setObjectData(QExplicitlySharedDataPointer<QScriptObjectData>(instance));}QScriptValueImpl Array::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo){ return method_join(context, eng, classInfo); // ### fixme}QScriptValueImpl Array::method_toLocaleString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo){ return method_toString(context, eng, classInfo);}QScriptValueImpl Array::method_concat(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo){ QScript::Array result; if (Instance *instance = Instance::get(context->thisObject(), classInfo)) result = instance->value; else { QString v = context->thisObject().toString(); result.assign(0, QScriptValueImpl(eng, v)); } for (int i = 0; i < context->argumentCount(); ++i) { quint32 k = result.size(); QScriptValueImpl arg = context->argument(i); if (Instance *elt = Instance::get(arg, classInfo)) result.concat(elt->value); else result.assign(k, QScriptValueImpl(eng, arg.toString())); } return eng->newArray(result);}QScriptValueImpl Array::method_join(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *){ QScriptValueImpl arg = context->argument(0); QString r4; if (arg.isUndefined()) r4 = QLatin1String(","); else r4 = arg.toString(); QScriptValueImpl self = context->thisObject(); QScriptNameIdImpl *id_length = eng->idTable()->id_length; QScriptValueImpl length = self.property(id_length); qsreal r1 = length.isValid() ? length.toNumber() : 0; quint32 r2 = QScriptEnginePrivate::toUint32(r1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -