-// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
-
-package org.xwt.js;
-import org.xwt.util.*;
-
-/**
- * Misc static methods used internally by the JS engine
- */
-class Internal {
- // Package Helper Methods //////////////////////////////////////////////////////////////
-
- private static Object wrapInt(int i) { return new Integer(i); }
- static Object callMethodOnPrimitive(Object o, Object method, JSArray args) {
- int alength = args.length();
- String s;
- if(o instanceof Number) {
- if(method.equals("toFixed")) throw new JS.Exn("toFixed() not implemented");
- if(method.equals("toExponential")) throw new JS.Exn("toExponential() not implemented");
- if(method.equals("toPrecision")) throw new JS.Exn("toPrecision() not implemented");
- if(method.equals("toString")) {
- int radix = alength >= 1 ? JS.toInt(args.elementAt(0)) : 10;
- return Long.toString(((Number)o).longValue(),radix);
- }
- } else if(o instanceof Boolean) {
- // No methods for Booleans
- }
- s = JS.toString(o);
- int slength = s.length();
- if(method.equals("substring")) {
- int a = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0;
- int b = alength >= 2 ? JS.toInt(args.elementAt(1)) : slength;
- if(a > slength) a = slength;
- if(b > slength) b = slength;
- if(a < 0) a = 0;
- if(b < 0) b = 0;
- if(a > b) { int tmp = a; a = b; b = tmp; }
- return s.substring(a,b);
- }
- if(method.equals("substr")) {
- int start = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0;
- int len = alength >= 2 ? JS.toInt(args.elementAt(1)) : Integer.MAX_VALUE;
- if(start < 0) start = slength + start;
- if(start < 0) start = 0;
- if(len < 0) len = 0;
- if(len > slength - start) len = slength - start;
- if(len <= 0) return "";
- return s.substring(start,start+len);
- }
- if(method.equals("charAt")) {
- int p = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0;
- if(p < 0 || p >= slength) return "";
- return s.substring(p,p+1);
- }
- if(method.equals("charCodeAt")) {
- int p = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0;
- if(p < 0 || p >= slength) return new Double(Double.NaN);
- return wrapInt(s.charAt(p));
- }
- if(method.equals("concat")) {
- StringBuffer sb = new StringBuffer(slength*2).append(s);
- for(int i=0;i<alength;i++) sb.append(args.elementAt(i));
- return sb.toString();
- }
- if(method.equals("indexOf")) {
- String search = alength >= 1 ? args.elementAt(0).toString() : "null";
- int start = alength >= 2 ? JS.toInt(args.elementAt(1)) : 0;
- // Java's indexOf handles an out of bounds start index, it'll return -1
- return wrapInt(s.indexOf(search,start));
- }
- if(method.equals("lastIndexOf")) {
- String search = alength >= 1 ? args.elementAt(0).toString() : "null";
- int start = alength >= 2 ? JS.toInt(args.elementAt(1)) : 0;
- // Java's indexOf handles an out of bounds start index, it'll return -1
- return wrapInt(s.lastIndexOf(search,start));
- }
- if(method.equals("match")) {
- return JSRegexp.stringMatch(s,args);
- }
- if(method.equals("replace")) {
- return JSRegexp.stringReplace(s,args);
- }
- if(method.equals("search")) {
- return JSRegexp.stringSearch(s,args);
- }
- if(method.equals("slice")) {
- int a = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0;
- int b = alength >= 2 ? JS.toInt(args.elementAt(1)) : slength;
- if(a < 0) a = slength + a;
- if(b < 0) b = slength + b;
- if(a < 0) a = 0;
- if(b < 0) b = 0;
- if(a > slength) a = slength;
- if(b > slength) b = slength;
- if(a > b) return "";
- return s.substring(a,b);
- }
- if(method.equals("split")){
- return JSRegexp.stringSplit(s,args);
- }
- if(method.equals("toLowerCase")) return s.toLowerCase();
- if(method.equals("toUpperCase")) return s.toUpperCase();
- if(method.equals("toString")) return s;
- throw new JS.Exn("Attempted to call non-existent method: " + method);
- }
-
- static Object getFromPrimitive(Object o, Object key) {
- boolean returnJSCallable = false;
- if(o instanceof Boolean) {
- // no properties for Booleans
- } else if(o instanceof Number) {
- if(key.equals("toPrecision") || key.equals("toExponential") || key.equals("toFixed"))
- returnJSCallable = true;
- }
- if(!returnJSCallable) {
- // the string stuff applies to everything
- String s = o.toString();
-
- if(key.equals("length")) return wrapInt(s.length());
-
- // this is sort of ugly, but this list should never change
- // These should provide a complete (enough) implementation of the ECMA-262 String object
- if(key.equals("substring") || key.equals("charAt") || key.equals("charCodeAt") || key.equals("concat") ||
- key.equals("indexOf") || key.equals("lastIndexOf") || key.equals("match") || key.equals("replace") ||
- key.equals("seatch") || key.equals("slice") || key.equals("split") || key.equals("toLowerCase") ||
- key.equals("toUpperCase") || key.equals("toString") || key.equals("substr")
- )
- returnJSCallable = true;
- }
- if(returnJSCallable) {
- final Object target = o;
- final String method = key.toString();
- return new JSCallable() {
- public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) {
- JSArray args = new JSArray();
- for(int i=0; i<nargs; i++) args.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
- return callMethodOnPrimitive(target,method,args);
- }
- };
- }
- return null;
- }
-
- static class JSCallableStub extends JSCallable {
- private Object method;
- JS obj;
- public JSCallableStub(JS obj, Object method) { this.obj = obj; this.method = method; }
- public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) {
- return ((JSCallable)obj).callMethod(method, a0, a1, a2, rest, nargs);
- }
- }
-}