2003/07/05 03:23:31
[org.ibex.core.git] / src / org / xwt / js / ArrayImpl.java
1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] 
2
3 package org.xwt.js; 
4 import org.xwt.util.*; 
5 import java.io.*;
6 import java.util.*;
7
8 // FIXME: could use some cleaning up...
9 // FIXME: Finish implementing ECMA-262
10
11 /** A JavaScript Array */
12 class ArrayImpl extends JS.Obj {
13     private Vec vec = new Vec();
14     public ArrayImpl() { }
15     public ArrayImpl(int size) { vec.setSize(size); }
16     private static int intVal(Object o) {
17         if (o instanceof Number) {
18             int intVal = ((Number)o).intValue();
19             if (intVal == ((Number)o).doubleValue()) return intVal;
20             return Integer.MIN_VALUE;
21         }
22         if (!(o instanceof String)) return Integer.MIN_VALUE;
23         String s = (String)o;
24         for(int i=0; i<s.length(); i++) if (s.charAt(i) < '0' || s.charAt(i) > '9') return Integer.MIN_VALUE;
25         return Integer.parseInt(s);
26     }
27     // we use _get instead of get solely to work around a GCJ bug
28     public Object _get(Object key) throws JS.Exn {
29         if (key.equals("length")) return new Long(vec.size());
30         if (key.equals("push")) return new JS.Callable() {
31             public Object call(JS.Array args) {
32                 for(int i=0;i<args.length();i++)
33                     vec.push(args.elementAt(i));
34                 return new Long(vec.size());
35             }
36         };
37         if (key.equals("pop")) return new JS.Callable() {
38             public Object call(JS.Array args) {
39                 return vec.pop(); // this'll return null on size()==0 
40             }
41         };
42                 
43         int i = intVal(key);
44         if (i == Integer.MIN_VALUE) return super.get(key);
45         try {
46             return vec.elementAt(i);
47         } catch (ArrayIndexOutOfBoundsException e) {
48             return null;
49         }
50     }
51     // we use _put instead of put solely to work around a GCJ bug
52     public void _put(Object key, Object val) {
53         if (key.equals("length")) vec.setSize(toNumber(val).intValue());
54         int i = intVal(key);
55         if (i == Integer.MIN_VALUE) super.put(key, val);
56         else {
57             if (i >= vec.size()) vec.setSize(i+1);
58             vec.setElementAt(val, i);
59         }
60     }
61     public Object[] keys() {
62         Object[] sup = super.keys();
63         Object[] ret = new Object[vec.size() + 1 + sup.length];
64         System.arraycopy(sup, 0, ret, vec.size(), sup.length);
65         for(int i=0; i<vec.size(); i++) ret[i] = new Integer(i);
66         ret[vec.size()] = "length";
67         return ret;
68     }
69     public void setSize(int i) { vec.setSize(i); }
70     public int length() { return vec.size(); }
71     public Object elementAt(int i) { return vec.elementAt(i); }
72     public void addElement(Object o) { vec.addElement(o); }
73     public void setElementAt(Object o, int i) { vec.setElementAt(o, i); }
74     
75     public String typeName() { return "array"; }
76 }
77