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 + -
显示快捷键?