001: // Copyright (c) 2001 Per M.A. Bothner and Brainfood Inc.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.lists;
005:
006: import java.io.*;
007:
008: /** Simple adjustable-length vector whose elements are Object references. */
009:
010: public class FVector extends SimpleVector implements Externalizable,
011: Consumable
012: /* #ifdef JAVA2 */
013: , Comparable
014: /* #endif */
015: {
016: public Object[] data;
017:
018: protected static Object[] empty = new Object[0];
019:
020: public FVector() {
021: data = empty;
022: }
023:
024: public FVector(int num) {
025: size = num;
026: data = new Object[num];
027: }
028:
029: public FVector(int num, Object o) {
030: Object[] data = new Object[num];
031: if (o != null) {
032: for (int i = 0; i < num; i++)
033: data[i] = o;
034: }
035: this .data = data;
036: this .size = num;
037: }
038:
039: /** Reuses the argument without making a copy! */
040: public FVector(Object[] data) {
041: this .size = data.length;
042: this .data = data;
043: }
044:
045: /* #ifdef JAVA2 */
046: public FVector(java.util.List seq) {
047: this .data = new Object[seq.size()];
048: addAll(seq);
049: }
050:
051: /* #endif */
052: /* #ifndef JAVA2 */
053: // public FVector(Sequence seq)
054: // {
055: // this.data = new Object[seq.size()];
056: // addAll(seq);
057: // }
058: /* #endif */
059:
060: /** Get the allocated length of the data buffer. */
061: public int getBufferLength() {
062: return data.length;
063: }
064:
065: public void setBufferLength(int length) {
066: int oldLength = data.length;
067: if (oldLength != length) {
068: Object[] tmp = new Object[length];
069: System.arraycopy(data, 0, tmp, 0,
070: oldLength < length ? oldLength : length);
071: data = tmp;
072: }
073: }
074:
075: protected Object getBuffer() {
076: return data;
077: }
078:
079: public void shift(int srcStart, int dstStart, int count) {
080: System.arraycopy(data, srcStart, data, dstStart, count);
081: }
082:
083: public final Object getBuffer(int index) {
084: return data[index];
085: }
086:
087: public final Object get(int index) {
088: if (index >= size)
089: throw new ArrayIndexOutOfBoundsException();
090: return data[index];
091: }
092:
093: public final Object setBuffer(int index, Object value) {
094: Object old = data[index];
095: data[index] = value;
096: return old;
097: }
098:
099: protected void clearBuffer(int start, int count) {
100: while (--count >= 0)
101: data[start++] = null;
102: }
103:
104: public boolean equals(Object obj) {
105: if (obj == null || !(obj instanceof FVector))
106: return false;
107: FVector obj_vec = (FVector) obj;
108: int n = size;
109: if (obj_vec.data == null || obj_vec.size != n)
110: return false;
111: Object[] obj_data = obj_vec.data;
112: for (int i = 0; i < n; i++) {
113: if (!(data[i].equals(obj_data[i])))
114: return false;
115: }
116: return true;
117: }
118:
119: /* #ifdef JAVA2 */
120: public int compareTo(Object obj) {
121: FVector vec2 = (FVector) obj;
122: Object[] d1 = data;
123: Object[] d2 = vec2.data;
124: int n1 = size;
125: int n2 = vec2.size;
126: int n = n1 > n2 ? n2 : n1;
127: for (int i = 0; i < n; i++) {
128: Comparable v1 = (Comparable) d1[i];
129: Comparable v2 = (Comparable) d2[i];
130: int d = v1.compareTo(v2);
131: if (d != 0)
132: return d;
133: }
134: return n1 - n2;
135: }
136:
137: /* #endif */
138:
139: /*
140: public final void setElementAt (Object new_value, int index)
141: {
142: if (index >= size)
143: throw new ArrayIndexOutOfBoundsException();
144: data[index] = new_value;
145: }
146: */
147:
148: // FIXME - bad name - setAll should take a Collection
149: public final void setAll(Object new_value) {
150: for (int i = size; --i >= 0;)
151: data[i] = new_value;
152: }
153:
154: public boolean consumeNext(int ipos, Consumer out) {
155: int index = ipos >>> 1;
156: if (index >= size)
157: return false;
158: out.writeObject(data[index]);
159: return true;
160: }
161:
162: public void consumePosRange(int iposStart, int iposEnd, Consumer out) {
163: if (out.ignoring())
164: return;
165: int i = iposStart >>> 1;
166: int end = iposEnd >>> 1;
167: if (end > size)
168: end = size;
169: for (; i < end; i++)
170: out.writeObject(data[i]);
171: }
172:
173: public void consume(Consumer out) {
174: out.startElement("#vector");
175: int len = size;
176: for (int i = 0; i < len; i++)
177: out.writeObject(data[i]);
178: out.endElement();
179: }
180:
181: /**
182: * @serialData Write the number of elements (using writeInt), followed by
183: * the elements in order (written using writeObject).
184: * (It might seem simpler (and increase sharing) to just call
185: * writeObject(value), but that exposes the implementation.)
186: */
187: public void writeExternal(ObjectOutput out) throws IOException {
188: int n = size;
189: out.writeInt(n);
190: for (int i = 0; i < n; i++)
191: out.writeObject(data[i]);
192: }
193:
194: public void readExternal(ObjectInput in) throws IOException,
195: ClassNotFoundException {
196: int n = in.readInt();
197: Object[] data = new Object[n];
198: for (int i = 0; i < n; i++)
199: data[i] = in.readObject();
200: size = n;
201: this.data = data;
202: }
203: }
|