📄 nativestring.java
字号:
/* * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * Free SoftwareFoundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.es;import com.caucho.util.CharBuffer;import com.caucho.util.IntArray;/** * JavaScript object */class NativeString extends Native { static final int NEW = 1; static final int TO_STRING = NEW + 1; static final int FROM_CHAR_CODE = TO_STRING + 1; static final int VALUE_OF = FROM_CHAR_CODE + 1; static final int CHAR_AT = VALUE_OF + 1; static final int CHAR_CODE_AT = CHAR_AT + 1; static final int INDEX_OF = CHAR_CODE_AT + 1; static final int LAST_INDEX_OF = INDEX_OF + 1; static final int SPLIT = LAST_INDEX_OF + 1; static final int SUBSTRING = SPLIT + 1; static final int TO_UPPER_CASE = SUBSTRING + 1; static final int TO_LOWER_CASE = TO_UPPER_CASE + 1; // js1.2 static final int CONCAT = TO_LOWER_CASE + 1; static final int MATCH = CONCAT + 1; static final int REPLACE = MATCH + 1; static final int SEARCH = REPLACE + 1; static final int SLICE = SEARCH + 1; static final int SUBSTR = SLICE + 1; // caucho static final int PRINTF = SUBSTR + 1; static final int CONTAINS = PRINTF + 1; static final int STARTS_WITH = CONTAINS + 1; static final int ENDS_WITH = STARTS_WITH + 1; static final int GET_BYTES = ENDS_WITH + 1; static final int REPLACE_WS = 0; static final int REPLACE_DIGIT = REPLACE_WS + 1; static final int REPLACE_ID = REPLACE_DIGIT + 1; private NativeString(String name, int n, int len) { super(name, len); this.n = n; } /** * Creates the native String object */ static ESObject create(Global resin) { NativeString nativeString = new NativeString("String", NEW, 1); ESObject stringProto = new ESWrapper("String", resin.objProto, ESString.NULL); NativeWrapper string; string = new NativeWrapper(resin, nativeString, stringProto, ESThunk.STRING_THUNK); resin.stringProto = stringProto; stringProto.put("length", ESNumber.create(0), DONT_ENUM|DONT_DELETE|READ_ONLY); put(stringProto, "valueOf", VALUE_OF, 0); put(stringProto, "toString", TO_STRING, 0); put(stringProto, "charAt", CHAR_AT, 1); put(stringProto, "charCodeAt", CHAR_CODE_AT, 1); put(stringProto, "indexOf", INDEX_OF, 2); put(stringProto, "lastIndexOf", LAST_INDEX_OF, 2); put(stringProto, "split", SPLIT, 1); put(stringProto, "substring", SUBSTRING, 2); put(stringProto, "toUpperCase", TO_UPPER_CASE, 0); put(stringProto, "toLowerCase", TO_LOWER_CASE, 0); put(string, "fromCharCode", FROM_CHAR_CODE, 0); // js1.2 put(stringProto, "concat", CONCAT, 1); put(stringProto, "match", MATCH, 1); put(stringProto, "replace", REPLACE, 2); put(stringProto, "search", SEARCH, 1); put(stringProto, "slice", SLICE, 2); put(stringProto, "substr", SUBSTR, 2); // caucho extensions put(string, "printf", PRINTF, 1); put(stringProto, "contains", CONTAINS, 1); put(stringProto, "startsWith", STARTS_WITH, 1); put(stringProto, "endsWith", ENDS_WITH, 1); put(stringProto, "getBytes", GET_BYTES, 1); stringProto.setClean(); string.setClean(); return string; } private static void put(ESObject obj, String name, int n, int len) { ESId id = ESId.intern(name); obj.put(id, new NativeString(name, n, len), DONT_ENUM); } public ESBase call(Call eval, int length) throws Throwable { switch (n) { case NEW: if (length == 0) return ESString.create(""); else return eval.getArg(0).toStr(); case FROM_CHAR_CODE: return fromCharCode(eval, length); case VALUE_OF: case TO_STRING: try { return (ESBase) ((ESWrapper) eval.getArg(-1)).value; } catch (ClassCastException e) { if (eval.getArg(-1) instanceof ESString) return eval.getArg(-1); if (eval.getArg(-1) instanceof ESThunk) return (ESBase) ((ESWrapper) ((ESThunk) eval.getArg(-1)).getObject()).value; throw new ESException("toString expects string object"); } case CHAR_AT: return charAt(eval, length); case CHAR_CODE_AT: return charCodeAt(eval, length); case INDEX_OF: return indexOf(eval, length); case LAST_INDEX_OF: return lastIndexOf(eval, length); case SPLIT: return split(eval, length); case SUBSTRING: return substring(eval, length); case TO_UPPER_CASE: return eval.getArg(-1).toStr().toUpperCase(); case TO_LOWER_CASE: return eval.getArg(-1).toStr().toLowerCase(); case CONCAT: return concat(eval, length); case MATCH: return match(eval, length); case REPLACE: return replace(eval, length); case SEARCH: return search(eval, length); case SLICE: return slice(eval, length); case SUBSTR: return substr(eval, length); case PRINTF: return printf(eval, length); case CONTAINS: if (length < 1) return ESBoolean.FALSE; else return eval.getArg(-1).toStr().contains(eval.getArg(0)); case STARTS_WITH: if (length < 1) return ESBoolean.FALSE; else return eval.getArg(-1).toStr().startsWith(eval.getArg(0)); case ENDS_WITH: if (length < 1) return ESBoolean.FALSE; else return eval.getArg(-1).toStr().endsWith(eval.getArg(0)); case GET_BYTES: if (length < 1) return eval.wrap(eval.getArgString(-1, length).getBytes()); else return eval.wrap(eval.getArgString(-1, length).getBytes(eval.getArgString(0, length))); default: throw new ESException("Unknown object function"); } } public ESBase construct(Call eval, int length) throws Throwable { if (n != NEW) throw new ESException("Unknown object function"); return (ESObject) create(eval, length); } private ESBase create(Call eval, int length) throws Throwable { ESBase value; if (length == 0) value = ESString.create(""); else value = eval.getArg(0).toStr(); return value.toObject(); } private ESBase fromCharCode(Call eval, int length) throws Throwable { StringBuffer sbuf = new StringBuffer(); for (int i = 0; i < length; i++) { int value = eval.getArg(i).toInt32() & 0xffff; sbuf.append((char) value); } return ESString.create(sbuf.toString()); } private ESBase charAt(Call eval, int length) throws Throwable { ESString string = eval.getArg(-1).toStr(); if (length == 0) return ESString.create(""); int value = (int) eval.getArg(0).toNum(); if (value < 0 || value >= string.length()) return ESString.create(""); else return ESString.create("" + (char) string.charAt(value)); } private ESBase charCodeAt(Call eval, int length) throws Throwable { ESString string = eval.getArg(-1).toStr(); if (length == 0) return ESNumber.NaN; int value = (int) eval.getArg(0).toNum(); if (value < 0 || value >= string.length()) return ESNumber.NaN; else return ESNumber.create(string.charAt(value)); } private ESBase indexOf(Call eval, int length) throws Throwable { ESString string = eval.getArg(-1).toStr(); if (length == 0) return ESNumber.create(-1); int pos = 0; if (length > 1) pos = (int) eval.getArg(1).toNum(); ESString test = eval.getArg(0).toStr(); return ESNumber.create(string.indexOf(test, pos)); } private ESBase lastIndexOf(Call eval, int length) throws Throwable { ESString string = eval.getArg(-1).toStr(); if (length == 0) return ESNumber.create(-1); int pos = string.length() + 1; if (length > 1) pos = (int) eval.getArg(1).toNum(); ESString test = eval.getArg(0).toStr(); return ESNumber.create(string.lastIndexOf(test, pos)); } private String escapeRegexp(String arg) { CharBuffer cb = new CharBuffer(); for (int i = 0; i < arg.length(); i++) { int ch; switch ((ch = arg.charAt(i))) { case '\\': case '-': case '[': case ']': case '(': case ')': case '$': case '^': case '|': case '?': case '*': case '{': case '}': case '.': cb.append('\\'); cb.append((char) ch); break; default: cb.append((char) ch); } } return cb.toString(); } private ESBase split(Call eval, int length) throws Throwable { Global resin = Global.getGlobalProto(); ESString string = eval.getArg(-1).toStr(); ESArray array = resin.createArray(); if (length == 0) { array.setProperty(0, string);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -