1    // Copyright (C) 2003 Adam Megacz <adam@xwt.org> all rights reserved.
2    //
3    // You may modify, copy, and redistribute this code under the terms of
4    // the GNU Library Public License version 2.1, with the exception of
5    // the portion of clause 6a after the semicolon (aka the "obnoxious
6    // relink clause")
7    
8    package org.xwt.util;
9    
10   import java.util.*;
11   import java.io.*;
12   
13   /** 
14    *  An unsynchronized Vector implementation; same semantics as
15    *  java.util.Vector. Useful for JDK1.1 platforms that don't have
16    *  java.util.ArrayList.
17    *
18    *  May contain nulls.
19    *
20    *  @see java.util.Vector
21    */
22   public final class Vec implements Serializable {
23       
24       private Object[] store;
25       private int size = 0;
26       
27       public Vec() { this(10); }
28       public Vec(int i) { store = new Object[i]; }
29       public Vec(int i, Object[] store) { size = i; this.store = store; }
30       
31       private void grow() { grow(store.length * 2); }
32       private void grow(int newsize) {
33           Object[] newstore = new Object[newsize];
34           System.arraycopy(store, 0, newstore, 0, size);
35           store = newstore;
36       }
37   
38       public void removeAllElements() {
39           for(int i=0; i<size; i++) store[i] = null;
40           size = 0;
41       }
42   
43       public void toArray(Object[] o) {
44           for(int i=0; i<size; i++)
45               o[i] = store[i];
46       }
47       
48       public int indexOf(Object o) {
49           for(int i=0; i<size; i++)
50               if (o == null ? store[i] == null : store[i].equals(o)) return i;
51           
52           return -1;
53       }
54       
55       public void addElement(Object o) {
56           if (size >= store.length - 1) grow();
57           store[size++] = o;
58       }
59   
60       public Object peek() {
61           return lastElement();
62       }
63   
64       public Object elementAt(int i) {
65           return store[i];
66       }
67       
68       public Object lastElement() {
69           if (size == 0) return null;
70           return store[size - 1];
71       }
72   
73       public void push(Object o) { addElement(o); }
74       public Object pop() {
75           Object ret = lastElement();
76           if (size > 0) store[size--] = null;
77           return ret;
78       }
79   
80       public int size() { return size; }
81   
82       public void setSize(int newSize) {
83           if (newSize < 0) throw new RuntimeException("tried to set size to negative value");
84           if (newSize > store.length) grow(newSize * 2);
85           if (newSize < size)
86               for(int i=newSize; i<size; i++)
87                   store[i] = null;
88           size = newSize;
89       }
90   
91       public void copyInto(Object[] out) {
92           for(int i=0; i<size; i++)
93               out[i] = store[i];
94       }
95   
96       public void fromArray(Object[] in) {
97           setSize(in.length);
98           for(int i=0; i<size; i++)
99               store[i] = in[i];
100      }
101  
102      public void removeElementAt(int i) {
103          if (i >= size || i < 0) throw new RuntimeException("tried to remove an element outside the vector's limits");
104          for(int j=i; j<size - 1; j++)
105              store[j] = store[j + 1];
106          setSize(size - 1);
107      }
108  
109      public void setElementAt(Object o, int i) {
110          if (i >= size) setSize(i);
111          store[i] = o;
112      }
113  
114      public void removeElement(Object o) {
115          int idx = indexOf(o);
116          if (idx != -1) removeElementAt(idx);
117      }
118  
119      public void insertElementAt(Object o, int at) {
120          if (size == store.length) grow();
121          for(int i=size; i>at; i--)
122              store[i] = store[i-1];
123          store[at] = o;
124          size++;
125      }
126  
127      public interface CompareFunc {
128          public int compare(Object a, Object b);
129      }
130  
131      public void sort(CompareFunc c) {
132          sort(this, null, c, 0, size-1);
133      }
134  
135      public static void sort(Vec a, Vec b, CompareFunc c) {
136          if (b != null && a.size != b.size) throw new IllegalArgumentException("Vec a and b must be of equal size");
137          sort(a, b, c, 0, a.size-1);
138      }
139  
140      private static final void sort(Vec a, Vec b, CompareFunc c, int start, int end) {
141          ObjectObject tmpb = null;
142          if(start >= end) return;
143          if(end-start <= 6) {
144              for(int i=start+1;i<=end;i++) {
145                  tmpa = a.store[i];
146                  if (b != null) tmpb = b.store[i];
147                  int j;
148                  for(j=i-1;j>=start;j--) {
149                      if(c.compare(a.store[j],tmpa) <= 0) break;
150                      a.store[j+1] = a.store[j];
151                      if (b != null) b.store[j+1] = b.store[j];
152                  }
153                  a.store[j+1] = tmpa;
154                  if (b != null) b.store[j+1] = tmpb;
155              }
156              return;
157          }
158  
159          Object pivot = a.store[end];
160          int lo = start - 1;
161          int hi = end;
162  
163          do {
164              while(c.compare(a.store[++lo],pivot) < 0) { }
165              while((hi > lo) && c.compare(a.store[--hi],pivot) > 0) { }
166              swap(a, lo,hi);
167              if (b != null) swap(b, lo,hi);
168          } while(lo < hi);
169  
170          swap(a, lo,end);
171          if (b != null) swap(b, lo,end);
172  
173          sort(a, b, c, start, lo-1);
174          sort(a, b, c, lo+1, end);
175      }
176  
177      private static final void swap(Vec vec, int a, int b) {
178          if(a != b) {
179              Object tmp = vec.store[a];
180              vec.store[a] = vec.store[b];
181              vec.store[b] = tmp;
182          }
183      }
184  }
185