?? nativestring.java
字號:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1997-1999 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * Tom Beauvais * Norris Boyd * Mike McCabe * * Alternatively, the contents of this file may be used under the * terms of the GNU Public License (the "GPL"), in which case the * provisions of the GPL are applicable instead of those above. * If you wish to allow use of your version of this file only * under the terms of the GPL and not to allow others to use your * version of this file under the NPL, indicate your decision by * deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete * the provisions above, a recipient may use your version of this * file under either the NPL or the GPL. */package org.mozilla.javascript;/** * This class implements the String native object. * * See ECMA 15.5. * * String methods for dealing with regular expressions are * ported directly from C. Latest port is from version 1.40.12.19 * in the JSFUN13_BRANCH. * * @author Mike McCabe * @author Norris Boyd */final class NativeString extends IdScriptableObject{ static final long serialVersionUID = 920268368584188687L; private static final Object STRING_TAG = new Object(); static void init(Scriptable scope, boolean sealed) { NativeString obj = new NativeString(""); obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); } private NativeString(String s) { string = s; } public String getClassName() { return "String"; } private static final int Id_length = 1, MAX_INSTANCE_ID = 1; protected int getMaxInstanceId() { return MAX_INSTANCE_ID; } protected int findInstanceIdInfo(String s) { if (s.equals("length")) { return instanceIdInfo(DONTENUM | READONLY | PERMANENT, Id_length); } return super.findInstanceIdInfo(s); } protected String getInstanceIdName(int id) { if (id == Id_length) { return "length"; } return super.getInstanceIdName(id); } protected Object getInstanceIdValue(int id) { if (id == Id_length) { return ScriptRuntime.wrapInt(string.length()); } return super.getInstanceIdValue(id); } protected void fillConstructorProperties(IdFunctionObject ctor) { addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_fromCharCode, "fromCharCode", 1); super.fillConstructorProperties(ctor); } protected void initPrototypeId(int id) { String s; int arity; switch (id) { case Id_constructor: arity=1; s="constructor"; break; case Id_toString: arity=0; s="toString"; break; case Id_toSource: arity=0; s="toSource"; break; case Id_valueOf: arity=0; s="valueOf"; break; case Id_charAt: arity=1; s="charAt"; break; case Id_charCodeAt: arity=1; s="charCodeAt"; break; case Id_indexOf: arity=1; s="indexOf"; break; case Id_lastIndexOf: arity=1; s="lastIndexOf"; break; case Id_split: arity=2; s="split"; break; case Id_substring: arity=2; s="substring"; break; case Id_toLowerCase: arity=0; s="toLowerCase"; break; case Id_toUpperCase: arity=0; s="toUpperCase"; break; case Id_substr: arity=2; s="substr"; break; case Id_concat: arity=1; s="concat"; break; case Id_slice: arity=2; s="slice"; break; case Id_bold: arity=0; s="bold"; break; case Id_italics: arity=0; s="italics"; break; case Id_fixed: arity=0; s="fixed"; break; case Id_strike: arity=0; s="strike"; break; case Id_small: arity=0; s="small"; break; case Id_big: arity=0; s="big"; break; case Id_blink: arity=0; s="blink"; break; case Id_sup: arity=0; s="sup"; break; case Id_sub: arity=0; s="sub"; break; case Id_fontsize: arity=0; s="fontsize"; break; case Id_fontcolor: arity=0; s="fontcolor"; break; case Id_link: arity=0; s="link"; break; case Id_anchor: arity=0; s="anchor"; break; case Id_equals: arity=1; s="equals"; break; case Id_equalsIgnoreCase: arity=1; s="equalsIgnoreCase"; break; case Id_match: arity=1; s="match"; break; case Id_search: arity=1; s="search"; break; case Id_replace: arity=1; s="replace"; break; default: throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(STRING_TAG, id, s, arity); } public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(STRING_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); switch (id) { case ConstructorId_fromCharCode: { int N = args.length; if (N < 1) return ""; StringBuffer sb = new StringBuffer(N); for (int i = 0; i != N; ++i) { sb.append(ScriptRuntime.toUint16(args[i])); } return sb.toString(); } case Id_constructor: { String s = (args.length >= 1) ? ScriptRuntime.toString(args[0]) : ""; if (thisObj == null) { // new String(val) creates a new String object. return new NativeString(s); } // String(val) converts val to a string value. return s; } case Id_toString: case Id_valueOf: // ECMA 15.5.4.2: 'the toString function is not generic. return realThis(thisObj, f).string; case Id_toSource: { String s = realThis(thisObj, f).string; return "(new String(\""+ScriptRuntime.escapeString(s)+"\"))"; } case Id_charAt: case Id_charCodeAt: { // See ECMA 15.5.4.[4,5] String target = ScriptRuntime.toString(thisObj); double pos = ScriptRuntime.toInteger(args, 0); if (pos < 0 || pos >= target.length()) { if (id == Id_charAt) return ""; else return ScriptRuntime.NaNobj; } char c = target.charAt((int)pos); if (id == Id_charAt) return String.valueOf(c); else return ScriptRuntime.wrapInt(c); } case Id_indexOf: return ScriptRuntime.wrapInt(js_indexOf( ScriptRuntime.toString(thisObj), args)); case Id_lastIndexOf: return ScriptRuntime.wrapInt(js_lastIndexOf( ScriptRuntime.toString(thisObj), args)); case Id_split: return js_split(cx, scope, ScriptRuntime.toString(thisObj), args); case Id_substring: return js_substring(cx, ScriptRuntime.toString(thisObj), args); case Id_toLowerCase: // See ECMA 15.5.4.11 return ScriptRuntime.toString(thisObj).toLowerCase(); case Id_toUpperCase: // See ECMA 15.5.4.12 return ScriptRuntime.toString(thisObj).toUpperCase(); case Id_substr: return js_substr(ScriptRuntime.toString(thisObj), args); case Id_concat: return js_concat(ScriptRuntime.toString(thisObj), args); case Id_slice: return js_slice(ScriptRuntime.toString(thisObj), args); case Id_bold: return tagify(thisObj, "b", null, null); case Id_italics: return tagify(thisObj, "i", null, null); case Id_fixed: return tagify(thisObj, "tt", null, null); case Id_strike: return tagify(thisObj, "strike", null, null); case Id_small: return tagify(thisObj, "small", null, null); case Id_big: return tagify(thisObj, "big", null, null); case Id_blink: return tagify(thisObj, "blink", null, null); case Id_sup: return tagify(thisObj, "sup", null, null); case Id_sub: return tagify(thisObj, "sub", null, null); case Id_fontsize: return tagify(thisObj, "font", "size", args); case Id_fontcolor: return tagify(thisObj, "font", "color", args); case Id_link: return tagify(thisObj, "a", "href", args); case Id_anchor: return tagify(thisObj, "a", "name", args); case Id_equals: case Id_equalsIgnoreCase: { String s1 = ScriptRuntime.toString(thisObj); String s2 = ScriptRuntime.toString(args, 0); return ScriptRuntime.wrapBoolean( (id == Id_equals) ? s1.equals(s2) : s1.equalsIgnoreCase(s2)); } case Id_match: case Id_search: case Id_replace: { int actionType; if (id == Id_match) { actionType = RegExpProxy.RA_MATCH; } else if (id == Id_search) { actionType = RegExpProxy.RA_SEARCH; } else { actionType = RegExpProxy.RA_REPLACE; } return ScriptRuntime.checkRegExpProxy(cx). action(cx, scope, thisObj, args, actionType); } } throw new IllegalArgumentException(String.valueOf(id)); } private static NativeString realThis(Scriptable thisObj, IdFunctionObject f) { if (!(thisObj instanceof NativeString)) throw incompatibleCallError(f); return (NativeString)thisObj; } /* * HTML composition aids. */ private static String tagify(Object thisObj, String tag, String attribute, Object[] args) { String str = ScriptRuntime.toString(thisObj); StringBuffer result = new StringBuffer(); result.append('<'); result.append(tag); if (attribute != null) { result.append(' '); result.append(attribute); result.append("=\""); result.append(ScriptRuntime.toString(args, 0)); result.append('"'); } result.append('>'); result.append(str); result.append("</"); result.append(tag); result.append('>'); return result.toString(); } public String toString() { return string; } /* Make array-style property lookup work for strings. * XXX is this ECMA? A version check is probably needed. In js too. */ public Object get(int index, Scriptable start) { if (0 <= index && index < string.length()) { return string.substring(index, index + 1); } return super.get(index, start); } public void put(int index, Scriptable start, Object value) { if (0 <= index && index < string.length()) { return; } super.put(index, start, value); } /* * * See ECMA 15.5.4.6. Uses Java String.indexOf() * OPT to add - BMH searching from jsstr.c. */ private static int js_indexOf(String target, Object[] args) { String search = ScriptRuntime.toString(args, 0); double begin = ScriptRuntime.toInteger(args, 1); if (begin > target.length()) { return -1; } else { if (begin < 0) begin = 0; return target.indexOf(search, (int)begin); } } /* * * See ECMA 15.5.4.7 * */ private static int js_lastIndexOf(String target, Object[] args) { String search = ScriptRuntime.toString(args, 0); double end = ScriptRuntime.toNumber(args, 1); if (end != end || end > target.length()) end = target.length(); else if (end < 0) end = 0; return target.lastIndexOf(search, (int)end); } /* * Used by js_split to find the next split point in target, * starting at offset ip and looking either for the given * separator substring, or for the next re match. ip and * matchlen must be reference variables (assumed to be arrays of * length 1) so they can be updated in the leading whitespace or * re case. * * Return -1 on end of string, >= 0 for a valid index of the next * separator occurrence if found, or the string length if no * separator is found. */ private static int find_split(Context cx, Scriptable scope, String target, String separator, int version, RegExpProxy reProxy, Scriptable re, int[] ip, int[] matchlen, boolean[] matched, String[][] parensp) { int i = ip[0]; int length = target.length(); /* * Perl4 special case for str.split(' '), only if the user has selected * JavaScript1.2 explicitly. Split on whitespace, and skip leading w/s. * Strange but true, apparently modeled after awk. */ if (version == Context.VERSION_1_2 && re == null && separator.length() == 1 && separator.charAt(0) == ' ') { /* Skip leading whitespace if at front of str. */ if (i == 0) { while (i < length && Character.isWhitespace(target.charAt(i))) i++; ip[0] = i; } /* Don't delimit whitespace at end of string. */ if (i == length)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -