string_object.cpp

来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 661 行 · 第 1/2 页

CPP
661
字号
      int lastIndex = 0;      Object o1;      // Test if 2nd arg is a function (new in JS 1.3)      if ( a1.type() == ObjectType && a1.toObject(exec).implementsCall() )        o1 = a1.toObject(exec);      else        u3 = a1.toString(exec); // 2nd arg is the replacement string      // This is either a loop (if global is set) or a one-way (if not).      do {        int **ovector = regExpObj->registerRegexp( reg, s );        UString mstr = reg->match(s, lastIndex, &pos, ovector);        regExpObj->setSubPatterns(reg->subPatterns());        if (pos == -1)          break;        len = mstr.size();        UString rstr;        // Prepare replacement        if (!o1.isValid())        {          rstr = u3;          bool ok;          // check if u3 matches $1 or $2 etc          for (int i = 0; (i = rstr.find(UString("$"), i)) != -1; i++) {            if (i+1<rstr.size() && rstr[i+1] == '$') {  // "$$" -> "$"              rstr = rstr.substr(0,i) + "$" + rstr.substr(i+2);              continue;            }            // Assume number part is one char exactly            unsigned long pos = rstr.substr(i+1,1).toULong(&ok, false /* tolerate empty string */);            if (ok && pos <= (unsigned)reg->subPatterns()) {              rstr = rstr.substr(0,i)                     + s.substr((*ovector)[2*pos],                                (*ovector)[2*pos+1]-(*ovector)[2*pos])                     + rstr.substr(i+2);              i += (*ovector)[2*pos+1]-(*ovector)[2*pos] - 1; // -1 offsets i++            }          }        } else // 2nd arg is a function call. Spec from http://devedge.netscape.com/library/manuals/2000/javascript/1.5/reference/string.html#1194258        {          List l;          l.append(String(mstr)); // First arg: complete matched substring          // Then the submatch strings          for ( unsigned int sub = 1; sub <= reg->subPatterns() ; ++sub )            l.append( String( s.substr((*ovector)[2*sub],                               (*ovector)[2*sub+1]-(*ovector)[2*sub]) ) );          l.append(Number(pos)); // The offset within the string where the match occurred          l.append(String(s)); // Last arg: the string itself. Can't see the difference with the 1st arg!          Object thisObj = exec->interpreter()->globalObject();          rstr = o1.call( exec, thisObj, l ).toString(exec);        }        lastIndex = pos + rstr.size();        s = s.substr(0, pos) + rstr + s.substr(pos + len);        //fprintf(stderr,"pos=%d,len=%d,lastIndex=%d,s=%s\n",pos,len,lastIndex,s.ascii());      } while (global);      result = String(s);    } else { // First arg is a string      u2 = a0.toString(exec);      pos = s.find(u2);      len = u2.size();      // Do the replacement      if (pos == -1)        result = String(s);      else {        u3 = s.substr(0, pos) + a1.toString(exec) +             s.substr(pos + len);        result = String(u3);      }    }    break;  case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/string.htm#1194366 or 15.5.4.13    {        // The arg processing is very much like ArrayProtoFunc::Slice        int begin = args[0].toUInt32(exec);        int end = len;        if (args[1].type() != UndefinedType) {          end = args[1].toInteger(exec);        }        int from = begin < 0 ? len + begin : begin;        int to = end < 0 ? len + end : end;        if (to > from && to > 0 && from < len) {          if (from < 0) {            from = 0;          }          if (to > len) {            to = len;          }          result = String(s.substr(from, to - from));        } else {          result = String("");        }        break;    }    case Split: {    Object constructor = exec->lexicalInterpreter()->builtinArray();    Object res = Object::dynamicCast(constructor.construct(exec,List::empty()));    result = res;    i = p0 = 0;    uint32_t limit = (a1.type() != UndefinedType) ? a1.toUInt32(exec) : 0xFFFFFFFFU;    if (a0.type() == ObjectType && Object::dynamicCast(a0).inherits(&RegExpImp::info)) {      Object obj0 = Object::dynamicCast(a0);      RegExp reg(obj0.get(exec,"source").toString(exec));      if (s.isEmpty() && !reg.match(s, 0).isNull()) {	// empty string matched by regexp -> empty array	res.put(exec, lengthPropertyName, Number(0), DontDelete|ReadOnly|DontEnum);	break;      }      pos = 0;      while (static_cast<uint32_t>(i) != limit && pos < s.size()) {	// TODO: back references        int mpos;        int *ovector = 0L;	UString mstr = reg.match(s, pos, &mpos, &ovector);        delete [] ovector; ovector = 0L;	if (mpos < 0)	  break;	pos = mpos + (mstr.isEmpty() ? 1 : mstr.size());	if (mpos != p0 || !mstr.isEmpty()) {	  res.put(exec,i, String(s.substr(p0, mpos-p0)));	  p0 = mpos + mstr.size();	  i++;	}      }    } else {      u2 = a0.toString(exec);      if (u2.isEmpty()) {	if (s.isEmpty()) {	  // empty separator matches empty string -> empty array	  put(exec,lengthPropertyName, Number(0));	  break;	} else {	  while (static_cast<uint32_t>(i) != limit && i < s.size()-1)	    res.put(exec,i++, String(s.substr(p0++, 1)));	}      } else {	while (static_cast<uint32_t>(i) != limit && (pos = s.find(u2, p0)) >= 0) {	  res.put(exec,i, String(s.substr(p0, pos-p0)));	  p0 = pos + u2.size();	  i++;	}      }    }    // add remaining string, if any    if (static_cast<uint32_t>(i) != limit)      res.put(exec,i++, String(s.substr(p0)));    res.put(exec,lengthPropertyName, Number(i));    }    break;  case Substr: {    n = a0.toInteger(exec);    m = a1.toInteger(exec);    int d, d2;    if (n >= 0)      d = n;    else      d = maxInt(len + n, 0);    if (a1.type() == UndefinedType)      d2 = len - d;    else      d2 = minInt(maxInt(m, 0), len - d);    result = String(s.substr(d, d2));    break;  }  case Substring: {    double start = a0.toNumber(exec);    double end = a1.toNumber(exec);    if (KJS::isNaN(start))      start = 0;    if (KJS::isNaN(end))      end = 0;    if (start < 0)      start = 0;    if (end < 0)      end = 0;    if (start > len)      start = len;    if (end > len)      end = len;    if (a1.type() == UndefinedType)      end = len;    if (start > end) {      double temp = end;      end = start;      start = temp;    }    result = String(s.substr((int)start, (int)end-(int)start));    }    break;  case ToLowerCase:  case ToLocaleLowerCase: // FIXME: To get this 100% right we need to detect Turkish and change I to lowercase i without a dot.    for (i = 0; i < len; i++)      s[i] = s[i].toLower();    result = String(s);    break;  case ToUpperCase:  case ToLocaleUpperCase: // FIXME: To get this 100% right we need to detect Turkish and change i to uppercase I with a dot.    for (i = 0; i < len; i++)      s[i] = s[i].toUpper();    result = String(s);    break;#ifndef KJS_PURE_ECMA  case Big:    result = String("<big>" + s + "</big>");    break;  case Small:    result = String("<small>" + s + "</small>");    break;  case Blink:    result = String("<blink>" + s + "</blink>");    break;  case Bold:    result = String("<b>" + s + "</b>");    break;  case Fixed:    result = String("<tt>" + s + "</tt>");    break;  case Italics:    result = String("<i>" + s + "</i>");    break;  case Strike:    result = String("<strike>" + s + "</strike>");    break;  case Sub:    result = String("<sub>" + s + "</sub>");    break;  case Sup:    result = String("<sup>" + s + "</sup>");    break;  case Fontcolor:    result = String("<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");    break;  case Fontsize:    result = String("<font size=\"" + a0.toString(exec) + "\">" + s + "</font>");    break;  case Anchor:    result = String("<a name=\"" + a0.toString(exec) + "\">" + s + "</a>");    break;  case Link:    result = String("<a href=\"" + a0.toString(exec) + "\">" + s + "</a>");    break;#endif  }  return result;}// ------------------------------ StringObjectImp ------------------------------StringObjectImp::StringObjectImp(ExecState *exec,                                 FunctionPrototypeImp *funcProto,                                 StringPrototypeImp *stringProto)  : InternalFunctionImp(funcProto){  Value protect(this);  // ECMA 15.5.3.1 String.prototype  putDirect(prototypePropertyName, stringProto, DontEnum|DontDelete|ReadOnly);  putDirect("fromCharCode", new StringObjectFuncImp(exec,funcProto), DontEnum);  // no. of arguments for constructor  putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);}bool StringObjectImp::implementsConstruct() const{  return true;}// ECMA 15.5.2Object StringObjectImp::construct(ExecState *exec, const List &args){  ObjectImp *proto = exec->lexicalInterpreter()->builtinStringPrototype().imp();  if (args.size() == 0)    return Object(new StringInstanceImp(proto));  return Object(new StringInstanceImp(proto, args.begin()->dispatchToString(exec)));}bool StringObjectImp::implementsCall() const{  return true;}// ECMA 15.5.1Value StringObjectImp::call(ExecState *exec, Object &/*thisObj*/, const List &args){  if (args.isEmpty())    return String("");  else {    Value v = args[0];    return String(v.toString(exec));  }}// ------------------------------ StringObjectFuncImp --------------------------// ECMA 15.5.3.2 fromCharCode()StringObjectFuncImp::StringObjectFuncImp(ExecState* /*exec*/, FunctionPrototypeImp *funcProto)  : InternalFunctionImp(funcProto){  Value protect(this);  putDirect(lengthPropertyName, NumberImp::one(), DontDelete|ReadOnly|DontEnum);}bool StringObjectFuncImp::implementsCall() const{  return true;}Value StringObjectFuncImp::call(ExecState *exec, Object &/*thisObj*/, 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(exec);      *p++ = UChar(u);      it++;    }    s = UString(buf, args.size(), false);  } else    s = "";  return String(s);}

⌨️ 快捷键说明

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