string_object.cpp

来自「将konqueror浏览器移植到ARM9 2410中」· C++ 代码 · 共 425 行

CPP
425
字号
/* *  This file is part of the KDE libraries *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "kjs.h"#include "operations.h"#include "types.h"#include "regexp.h"#include "string_object.h"#include <stdio.h>using namespace KJS;StringObject::StringObject(const Object &funcProto, const Object &stringProto)  : ConstructorImp(funcProto, 1){  // ECMA 15.5.3.1 String.prototype  setPrototypeProperty(stringProto);}KJSO StringObject::get(const UString &p) const{  if (p == "fromCharCode")    return Function(new StringObjectFunc());  else    return Imp::get(p);}// ECMA 15.5.1Completion StringObject::execute(const List &args){  KJSO v;  String s;  if (args.isEmpty())    s = String("");  else {    v = args[0];    s = v.toString();  }  return Completion(ReturnValue, s);}// ECMA 15.5.2Object StringObject::construct(const List &args){  String s;  if (args.size() > 0)    s = args.begin()->toString();  else    s = String("");  return Object::create(StringClass, s);}// ECMA 15.5.3.2 fromCharCode()Completion StringObjectFunc::execute(const List &args){  UString s;  if (args.size()) {    UChar *buf = new UChar[args.size()];    UChar *p = buf;    ListIterator it = args.begin();    while (it != args.end()) {      unsigned short u = it->toUInt16();      *p++ = UChar(u);      it++;    }    s = UString(buf, args.size(), false);  } else    s = "";  return Completion(ReturnValue, String(s));}// ECMA 15.5.4StringPrototype::StringPrototype(const Object& proto)  : ObjectImp(StringClass, String(""), proto){  // The constructor will be added later in StringObject's constructor}KJSO StringPrototype::get(const UString &p) const{  int id;  if (p == "toString")    id = StringProtoFunc::ToString;  else if (p == "valueOf")    id = StringProtoFunc::ValueOf;  else if (p == "charAt")    id = StringProtoFunc::CharAt;  else if (p == "charCodeAt")    id = StringProtoFunc::CharCodeAt;  else if (p == "indexOf")    id = StringProtoFunc::IndexOf;  else if (p == "lastIndexOf")    id = StringProtoFunc::LastIndexOf;  else if (p == "match")    id = StringProtoFunc::Match;  else if (p == "replace")    id = StringProtoFunc::Replace;  else if (p == "search")    id = StringProtoFunc::Search;  else if (p == "split")    id = StringProtoFunc::Split;  else if (p == "substr")    id = StringProtoFunc::Substr;  else if (p == "substring")    id = StringProtoFunc::Substring;  else if (p == "toLowerCase")    id = StringProtoFunc::ToLowerCase;  else if (p == "toUpperCase")    id = StringProtoFunc::ToUpperCase;#ifndef KJS_PURE_ECMA  else if (p == "big")    id = StringProtoFunc::Big;  else if (p == "small")    id = StringProtoFunc::Small;  else if (p == "blink")    id = StringProtoFunc::Blink;  else if (p == "bold")    id = StringProtoFunc::Bold;  else if (p == "fixed")    id = StringProtoFunc::Fixed;  else if (p == "italics")    id = StringProtoFunc::Italics;  else if (p == "strike")    id = StringProtoFunc::Strike;  else if (p == "sub")    id = StringProtoFunc::Sub;  else if (p == "sup")    id = StringProtoFunc::Sup;  else if (p == "fontcolor")    id = StringProtoFunc::Fontcolor;  else if (p == "fontsize")    id = StringProtoFunc::Fontsize;  else if (p == "anchor")    id = StringProtoFunc::Anchor;  else if (p == "link")    id = StringProtoFunc::Link;#endif  else    return Imp::get(p);  return Function(new StringProtoFunc(id));}StringProtoFunc::StringProtoFunc(int i)  : id(i){}// ECMA 15.5.4.2 - 15.5.4.20Completion StringProtoFunc::execute(const List &args){  KJSO result;  Object thisObj = Object::dynamicCast(thisValue());  // toString and valueOf are no generic function.  if (id == ToString || id == ValueOf) {    if (thisObj.isNull() || thisObj.getClass() != StringClass) {      result = Error::create(TypeError);      return Completion(ReturnValue, result);    }  }  String s2;  Number n, m;  UString u, u2, u3;  int pos, p0, i;  double d, d2;  KJSO v = thisObj.internalValue();  String s = v.toString();  int len = s.value().size();  KJSO a0 = args[0];  KJSO a1 = args[1];  switch (id) {  case ToString:  case ValueOf:    result = v.toString();    break;  case CharAt:    n = a0.toInteger();    pos = (int) n.value();    if (pos < 0 || pos >= len)      u = "";    else      u = s.value().substr(pos, 1);    result = String(u);    break;  case CharCodeAt:    n = a0.toInteger();    pos = (int) n.value();    if (pos < 0 || pos >= len)      d = NaN;    else {      UChar c = s.value()[pos];      d = (c.high() << 8) + c.low();    }    result = Number(d);    break;  case IndexOf:    s2 = a0.toString();    if (a1.isA(UndefinedType))      pos = 0;    else      pos = a1.toInteger().intValue();    d = s.value().find(s2.value(), pos);    result = Number(d);    break;  case LastIndexOf:    s2 = a0.toString();    if (a1.isA(UndefinedType))      pos = len;    else      pos = a1.toInteger().intValue();    d = s.value().rfind(s2.value(), pos);    result = Number(d);    break;  case Match:  case Search:    u = s.value();    if (a0.isA(ObjectType) && a0.toObject().getClass() == RegExpClass)      s2 = a0.get("source").toString();    else if (a0.isA(StringType))      s2 = a0.toString();    else    {      printf("KJS: Match/Search. Argument is not a RegExp nor a String - returning Undefined\n");      result = Undefined(); // No idea what to do here      break;    }    {      RegExp reg(s2.value());      UString mstr = reg.match(u, -1, &pos);      if (id == Search) {        result = Number(pos);        break;      }      if (mstr.isNull()) {	result = Null();	break;      }      /* TODO return an array, with the matches, etc. */      result = String(mstr);    }    break;  case Replace:    /* TODO: this is just a hack to get the most common cases going */    u = s.value();    if (a0.isA(ObjectType) && a0.toObject().getClass() == RegExpClass) {      s2 = a0.get("source").toString();      RegExp reg(s2.value());      UString mstr = reg.match(u, -1, &pos);      len = mstr.size();    } else {      s2 = a0.toString();      u2 = s2.value();      pos = u.find(u2);      len = u2.size();    }    if (pos == -1)	result = s;    else {	u3 = u.substr(0, pos) + a1.toString().value() +	     u.substr(pos + len);	result = String(u3);    }    break;  case Split:    result = Object::create(ArrayClass);    u = s.value();    i = p0 = 0;    d = a1.isDefined() ? a1.toInteger().intValue() : -1; // optional max number    if (a0.isA(ObjectType) && Object(a0.imp()).getClass() == RegExpClass) {      RegExp reg(a0.get("source").toString().value());      if (u.isEmpty() && !reg.match(u, 0).isNull()) {	// empty string matched by regexp -> empty array	result.put("length", 0);	break;      }      int mpos;      pos = 0;      while (1) {	/* TODO: back references */	UString mstr = reg.match(u, pos, &mpos);	if (mpos < 0)	  break;	pos = mpos + (mstr.isEmpty() ? 1 : mstr.size());	if (mpos != p0 || !mstr.isEmpty()) {	  result.put(UString::from(i), String(u.substr(p0, mpos-p0)));	  p0 = mpos + mstr.size();	  i++;	}      }    } else if (a0.isDefined()) {      u2 = a0.toString().value();      if (u2.isEmpty()) {	if (u.isEmpty()) {	  // empty separator matches empty string -> empty array	  put("length", 0);	  break;	} else {	  while (i != d && i < u.size())	    result.put(UString::from(i++), String(u.substr(p0++, 1)));	}      } else {	while (i != d && (pos = u.find(u2, p0)) >= 0) {	  result.put(UString::from(i), String(u.substr(p0, pos-p0)));	  p0 = pos + u2.size();	  i++;	}      }    }    // add remaining string, if any    if (i != d && (p0 < len || i == 0))      result.put(UString::from(i++), String(u.substr(p0)));    result.put("length", i);    break;  case Substr:    n = a0.toInteger();    m = a1.toInteger();    if (n.value() >= 0)      d = n.value();    else      d = max(len + n.value(), 0);    if (a1.isA(UndefinedType))      d2 = len - d;    else      d2 = min(max(m.value(), 0), len - d);    result = String(s.value().substr((int)d, (int)d2));    break;  case Substring:    n = a0.toInteger();    m = a1.toInteger();    d = min(max(n.value(), 0), len);    if (a1.isA(UndefinedType))      d2 = len - d;    else {      d2 = min(max(m.value(), 0), len);      d2 = max(d2-d, 0);    }    result = String(s.value().substr((int)d, (int)d2));    break;  case ToLowerCase:    u = UString(s.value());    for (i = 0; i < len; i++)      u[i] = u[i].toLower();    result = String(u);    break;  case ToUpperCase:    u = UString(s.value());    for (i = 0; i < len; i++)      u[i] = u[i].toUpper();    result = String(u);    break;#ifndef KJS_PURE_ECMA  case Big:    result = String("<BIG>" + s.value() + "</BIG>");    break;  case Small:    result = String("<SMALL>" + s.value() + "</SMALL>");    break;  case Blink:    result = String("<BLINK>" + s.value() + "</BLINK>");    break;  case Bold:    result = String("<B>" + s.value() + "</B>");    break;  case Fixed:    result = String("<TT>" + s.value() + "</TT>");    break;  case Italics:    result = String("<I>" + s.value() + "</I>");    break;  case Strike:    result = String("<STRIKE>" + s.value() + "</STRIKE>");    break;  case Sub:    result = String("<SUB>" + s.value() + "</SUB>");    break;  case Sup:    result = String("<SUP>" + s.value() + "</SUP>");    break;  case Fontcolor:    result = String("<FONT COLOR=" + a0.toString().value() + ">"		    + s.value() + "</FONT>");    break;  case Fontsize:    result = String("<FONT SIZE=" + a0.toString().value() + ">"		    + s.value() + "</FONT>");    break;  case Anchor:    result = String("<a name=" + a0.toString().value() + ">"		    + s.value() + "</a>");    break;  case Link:    result = String("<a href=" + a0.toString().value() + ">"		    + s.value() + "</a>");    break;#endif  }  return Completion(ReturnValue, result);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?