string_object.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 661 行 · 第 1/2 页
CPP
661 行
// -*- c-basic-offset: 2 -*-/* * This file is part of the KDE libraries * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */#include "value.h"#include "object.h"#include "types.h"#include "interpreter.h"#include "operations.h"#include "regexp.h"#include "regexp_object.h"#include "string_object.h"#include "error_object.h"#include <stdio.h>#include "string_object.lut.h"#ifdef HAVE_STDINT_H#include <stdint.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_SYS_BITYPES_H#include <sys/bitypes.h> /* For uintXX_t on Tru64 */#endifusing namespace KJS;// ------------------------------ StringInstanceImp ----------------------------const ClassInfo StringInstanceImp::info = {"String", 0, 0, 0};StringInstanceImp::StringInstanceImp(ObjectImp *proto) : ObjectImp(proto){ setInternalValue(String(""));}StringInstanceImp::StringInstanceImp(ObjectImp *proto, const UString &string) : ObjectImp(proto){ setInternalValue(String(string));}Value StringInstanceImp::get(ExecState *exec, const Identifier &propertyName) const{ if (propertyName == lengthPropertyName) return Number(internalValue().toString(exec).size()); bool ok; const unsigned index = propertyName.toArrayIndex(&ok); if (ok) { const UString s = internalValue().toString(exec); const unsigned length = s.size(); if (index < length) { const UChar c = s[index]; return String(UString(&c, 1)); } } return ObjectImp::get(exec, propertyName);}void StringInstanceImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr){ if (propertyName == lengthPropertyName) return; ObjectImp::put(exec, propertyName, value, attr);}bool StringInstanceImp::hasProperty(ExecState *exec, const Identifier &propertyName) const{ if (propertyName == lengthPropertyName) return true; bool ok; unsigned index = propertyName.toULong(&ok); if (ok && index < (unsigned)internalValue().toString(exec).size()) return true; return ObjectImp::hasProperty(exec, propertyName);}bool StringInstanceImp::deleteProperty(ExecState *exec, const Identifier &propertyName){ if (propertyName == lengthPropertyName) return false; bool ok; unsigned index = propertyName.toULong(&ok); if (ok && index < (unsigned)internalValue().toString(exec).size()) return false; return ObjectImp::deleteProperty(exec, propertyName);}ReferenceList StringInstanceImp::propList(ExecState *exec, bool recursive){ ReferenceList properties = ObjectImp::propList(exec,recursive); UString str = internalValue().toString(exec); for (int i = 0; i < str.size(); i++) if (!ObjectImp::hasProperty(exec,Identifier::from(i))) properties.append(Reference(this, i)); return properties;}// ------------------------------ StringPrototypeImp ---------------------------const ClassInfo StringPrototypeImp::info = {"String", &StringInstanceImp::info, &stringTable, 0};/* Source for string_object.lut.h@begin stringTable 28 toString StringProtoFuncImp::ToString DontEnum|Function 0 valueOf StringProtoFuncImp::ValueOf DontEnum|Function 0 charAt StringProtoFuncImp::CharAt DontEnum|Function 1 charCodeAt StringProtoFuncImp::CharCodeAt DontEnum|Function 1 concat StringProtoFuncImp::Concat DontEnum|Function 1 indexOf StringProtoFuncImp::IndexOf DontEnum|Function 1 lastIndexOf StringProtoFuncImp::LastIndexOf DontEnum|Function 1 match StringProtoFuncImp::Match DontEnum|Function 1 replace StringProtoFuncImp::Replace DontEnum|Function 2 search StringProtoFuncImp::Search DontEnum|Function 1 slice StringProtoFuncImp::Slice DontEnum|Function 2 split StringProtoFuncImp::Split DontEnum|Function 2 substr StringProtoFuncImp::Substr DontEnum|Function 2 substring StringProtoFuncImp::Substring DontEnum|Function 2 toLowerCase StringProtoFuncImp::ToLowerCase DontEnum|Function 0 toUpperCase StringProtoFuncImp::ToUpperCase DontEnum|Function 0 toLocaleLowerCase StringProtoFuncImp::ToLocaleLowerCase DontEnum|Function 0 toLocaleUpperCase StringProtoFuncImp::ToLocaleUpperCase DontEnum|Function 0## Under here: html extension, should only exist if KJS_PURE_ECMA is not defined# I guess we need to generate two hashtables in the .lut.h file, and use #ifdef# to select the right one... TODO. ##### big StringProtoFuncImp::Big DontEnum|Function 0 small StringProtoFuncImp::Small DontEnum|Function 0 blink StringProtoFuncImp::Blink DontEnum|Function 0 bold StringProtoFuncImp::Bold DontEnum|Function 0 fixed StringProtoFuncImp::Fixed DontEnum|Function 0 italics StringProtoFuncImp::Italics DontEnum|Function 0 strike StringProtoFuncImp::Strike DontEnum|Function 0 sub StringProtoFuncImp::Sub DontEnum|Function 0 sup StringProtoFuncImp::Sup DontEnum|Function 0 fontcolor StringProtoFuncImp::Fontcolor DontEnum|Function 1 fontsize StringProtoFuncImp::Fontsize DontEnum|Function 1 anchor StringProtoFuncImp::Anchor DontEnum|Function 1 link StringProtoFuncImp::Link DontEnum|Function 1@end*/// ECMA 15.5.4StringPrototypeImp::StringPrototypeImp(ExecState * /*exec*/, ObjectPrototypeImp *objProto) : StringInstanceImp(objProto){ Value protect(this); // The constructor will be added later, after StringObjectImp has been built putDirect(lengthPropertyName, NumberImp::zero(), DontDelete|ReadOnly|DontEnum);}Value StringPrototypeImp::get(ExecState *exec, const Identifier &propertyName) const{ return lookupGetFunction<StringProtoFuncImp, StringInstanceImp>( exec, propertyName, &stringTable, this );}// ------------------------------ StringProtoFuncImp ---------------------------StringProtoFuncImp::StringProtoFuncImp(ExecState *exec, int i, int len) : InternalFunctionImp( static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp()) ), id(i){ Value protect(this); putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);}bool StringProtoFuncImp::implementsCall() const{ return true;}// ECMA 15.5.4.2 - 15.5.4.20Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args){ Value result; // toString and valueOf are no generic functions. if (id == ToString || id == ValueOf) { KJS_CHECK_THIS( StringInstanceImp, thisObj ); return String(thisObj.internalValue().toString(exec)); } int n, m; UString u2, u3; double dpos; int pos, p0, i; double d = 0.0; UString s = thisObj.toString(exec); int len = s.size(); Value a0 = args[0]; Value a1 = args[1]; switch (id) { case ToString: case ValueOf: // handled above break; case CharAt: pos = a0.type() == UndefinedType ? 0 : a0.toInteger(exec); if (pos < 0 || pos >= len) s = ""; else s = s.substr(pos, 1); result = String(s); break; case CharCodeAt: pos = a0.type() == UndefinedType ? 0 : a0.toInteger(exec); if (pos < 0 || pos >= len) d = NaN; else { UChar c = s[pos]; d = (c.high() << 8) + c.low(); } result = Number(d); break; case Concat: { ListIterator it = args.begin(); for ( ; it != args.end() ; ++it) { s += it->dispatchToString(exec); } result = String(s); break; } case IndexOf: u2 = a0.toString(exec); if (a1.type() == UndefinedType) pos = 0; else pos = a1.toInteger(exec); d = s.find(u2, pos); result = Number(d); break; case LastIndexOf: u2 = a0.toString(exec); d = a1.toNumber(exec); if (a1.type() == UndefinedType || KJS::isNaN(d)) dpos = len; else { dpos = d; if (dpos < 0) dpos = 0; else if (dpos > len) dpos = len; } result = Number(s.rfind(u2, int(dpos))); break; case Match: case Search: { RegExp *reg, *tmpReg = 0; RegExpImp *imp = 0; if (a0.isA(ObjectType) && a0.toObject(exec).inherits(&RegExpImp::info)) { imp = static_cast<RegExpImp *>( a0.toObject(exec).imp() ); reg = imp->regExp(); } else { /* * ECMA 15.5.4.12 String.prototype.search (regexp) * If regexp is not an object whose [[Class]] property is "RegExp", it is * replaced with the result of the expression new RegExp(regexp). */ reg = tmpReg = new RegExp(a0.toString(exec), RegExp::None); } RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->interpreter()->builtinRegExp().imp()); int **ovector = regExpObj->registerRegexp(reg, s); UString mstr = reg->match(s, -1, &pos, ovector); if (id == Search) { result = Number(pos); } else { // Match if (mstr.isNull()) { result = Null(); // no match } else if ((reg->flags() & RegExp::Global) == 0) { // case without 'g' flag is handled like RegExp.prototype.exec regExpObj->setSubPatterns(reg->subPatterns()); result = regExpObj->arrayOfMatches(exec,mstr); } else { // return array of matches List list; while (pos >= 0) { list.append(String(mstr)); pos += mstr.isEmpty() ? 1 : mstr.size(); delete [] *ovector; mstr = reg->match(s, pos, &pos, ovector); } result = exec->lexicalInterpreter()->builtinArray().construct(exec, list); } } delete tmpReg; break; } case Replace: if (a0.type() == ObjectType && a0.toObject(exec).inherits(&RegExpImp::info)) { RegExpImp* imp = static_cast<RegExpImp *>( a0.toObject(exec).imp() ); RegExp *reg = imp->regExp(); bool global = false; Value tmp = imp->get(exec,"global"); if (tmp.type() != UndefinedType && tmp.toBoolean(exec) == true) global = true; RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp().imp());
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?