📄 string_object.cpp
字号:
int lastIndex = 0; u3 = a1.toString(exec); // replacement string // This is either a loop (if global is set) or a one-way (if not). do { int **ovector = regExpObj->registerRegexp( reg, u ); UString mstr = reg->match(u, lastIndex, &pos, ovector); regExpObj->setSubPatterns(reg->subPatterns()); if (pos == -1) break; len = mstr.size(); UString 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) + u.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++ } } lastIndex = pos + rstr.size(); u = u.substr(0, pos) + rstr + u.substr(pos + len); //fprintf(stderr,"pos=%d,len=%d,lastIndex=%d,u=%s\n",pos,len,lastIndex,u.ascii()); // special case of empty match if (len == 0) { lastIndex = lastIndex + 1; if (lastIndex > u.size()) break; } } while (global); result = String(u); } else { // First arg is a string u2 = a0.toString(exec); pos = u.find(u2); len = u2.size(); // Do the replacement if (pos == -1) result = String(s); else { u3 = u.substr(0, pos) + a1.toString(exec) + u.substr(pos + len); result = String(u3); } } break; case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/string.htm#1194366 { // The arg processing is very much like ArrayProtoFunc::Slice double begin = args[0].toInteger(exec); if (begin < 0) { begin += len; if (begin < 0) begin = 0; } else { if (begin > len) begin = len; } double end = len; if (args[1].type() != UndefinedType) { end = args[1].toInteger(exec); if (end < 0) { end += len; if (end < 0) end = 0; } else { if (end > len) end = len; } } //printf( "Slicing from %d to %d \n", begin, end ); result = String(s.substr(static_cast<int>(begin), static_cast<int>(end-begin))); break; } case Split: { Object constructor = exec->lexicalInterpreter()->builtinArray(); Object res = Object::dynamicCast(constructor.construct(exec,List::empty())); result = res; u = s; i = p0 = 0; d = (a1.type() != UndefinedType) ? a1.toInteger(exec) : -1; // optional max number if (a0.type() == ObjectType && Object::dynamicCast(a0).inherits(&RegExpImp::info)) { Object obj0 = Object::dynamicCast(a0); RegExp reg(obj0.get(exec,"source").toString(exec)); if (u.isEmpty() && !reg.match(u, 0).isNull()) { // empty string matched by regexp -> empty array res.put(exec,lengthPropertyName, Number(0)); break; } pos = 0; while (pos < u.size()) { // TODO: back references int mpos; int *ovector = 0L; UString mstr = reg.match(u, 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(u.substr(p0, mpos-p0))); p0 = mpos + mstr.size(); i++; } } } else if (a0.type() != UndefinedType) { u2 = a0.toString(exec); if (u2.isEmpty()) { if (u.isEmpty()) { // empty separator matches empty string -> empty array put(exec,lengthPropertyName, Number(0)); break; } else { while (i != d && i < u.size()-1) res.put(exec, i++, String(u.substr(p0++, 1))); } } else { while (i != d && (pos = u.find(u2, p0)) >= 0) { res.put(exec, i, String(u.substr(p0, pos-p0))); p0 = pos + u2.size(); i++; } } } // add remaining string, if any if (i != d) res.put(exec, i++, String(u.substr(p0))); res.put(exec,lengthPropertyName, Number(i)); } break; case Substr: { double d = a0.toInteger(exec); double d2 = a1.toInteger(exec); if (d < 0) { d += len; if (d < 0) d = 0; } if (a1.type() == UndefinedType) d2 = len - d; else { if (d2 < 0) d2 = 0; if (d2 > len - d) d2 = len - d; } result = String(s.substr(static_cast<int>(d), static_cast<int>(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: u = s; for (i = 0; i < len; i++) u[i] = u[i].toLower(); result = String(u); break; case ToUpperCase: u = s; 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 + "</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); static Identifier fromCharCode("fromCharCode"); 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -