KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > lists > FString


1 // Copyright (c) 2001, 2004 Per M.A. Bothner and Brainfood Inc.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.lists;
5 import java.io.*;
6
7 /** Simple adjustable-length vector whose elements are 32-bit floats.
8  * Used for the Scheme string type.
9  * @author Per Bothner
10  */

11
12 public class FString extends SimpleVector
13   implements
14   /* #ifdef JAVA2 */
15   Comparable JavaDoc,
16   /* #endif */
17   /* #ifdef JAVA5 */
18   // Appendable,
19
/* #endif */
20   CharSeq, Externalizable, Consumable
21 {
22   public char[] data;
23   protected static char[] empty = new char[0];
24
25   public FString ()
26   {
27     data = empty;
28   }
29
30   public FString (int num)
31   {
32     size = num;
33     data = new char[num];
34   }
35
36   public FString (int num, char value)
37   {
38     char[] array = new char[num];
39     data = array;
40     size = num;
41     while (--num >= 0)
42       array[num] = value;
43   }
44
45   /** Create an FString from a char[].
46    * Note that this contructor does *not* copy the argument. */

47   public FString (char[] values)
48   {
49     size = values.length;
50     data = values;
51   }
52
53   public FString (String JavaDoc str)
54   {
55     data = str.toCharArray();
56     size = data.length;
57   }
58
59   public FString (StringBuffer JavaDoc buffer)
60   {
61     this(buffer, 0, buffer.length());
62   }
63
64   public FString (StringBuffer JavaDoc buffer, int offset, int length)
65   {
66     this.size = length;
67     data = new char[length];
68     if (length > 0)
69       buffer.getChars (offset, offset+length, data, 0);
70   }
71
72   public FString (char[] buffer, int offset, int length)
73   {
74     this.size = length;
75     data = new char[length];
76     System.arraycopy(buffer, offset, data, 0, length);
77   }
78
79   public FString(Sequence seq)
80   {
81     this.data = new char[seq.size()];
82     addAll(seq);
83   }
84
85   public FString(CharSeq seq)
86   {
87     int size = seq.size();
88     char[] data = new char[size];
89     seq.getChars(0, size, data, 0);
90     this.data = data;
91     this.size = size;
92   }
93
94   public FString(CharSeq seq, int offset, int length)
95   {
96     char[] data = new char[length];
97     seq.getChars(offset, offset+length, data, 0);
98     this.data = data;
99     this.size = length;
100   }
101
102   public int length() { return size; }
103
104   /** Get the allocated length of the data buffer. */
105   public int getBufferLength()
106   {
107     return data.length;
108   }
109
110   public void setBufferLength(int length)
111   {
112     int oldLength = data.length;
113     if (oldLength != length)
114       {
115     char[] tmp = new char[length];
116     System.arraycopy(data, 0, tmp, 0,
117              oldLength < length ? oldLength : length);
118     data = tmp;
119       }
120   }
121
122   public void ensureBufferLength (int sz)
123   {
124     if (sz > data.length)
125       {
126         char[] d = new char[sz < 60 ? 120 : 2 * sz];
127         System.arraycopy(data, 0, d, 0, sz);
128         data = d;
129       }
130   }
131
132   protected Object JavaDoc getBuffer() { return data; }
133
134   public final Object JavaDoc getBuffer(int index)
135   {
136     return Convert.toObject(data[index]);
137   }
138
139   public final Object JavaDoc setBuffer(int index, Object JavaDoc value)
140   {
141     Object JavaDoc old = Convert.toObject(data[index]);
142     data[index] = Convert.toChar(value);
143     return old;
144   }
145
146   public final Object JavaDoc get (int index)
147   {
148     if (index >= size)
149       throw new ArrayIndexOutOfBoundsException JavaDoc();
150     return Convert.toObject(data[index]);
151   }
152
153   public final char charAt(int index)
154   {
155     if (index >= size)
156       throw new StringIndexOutOfBoundsException JavaDoc(index);
157     return data[index];
158   }
159
160   public final char charAtBuffer(int index)
161   {
162     return data[index];
163   }
164
165   public void getChars (int srcBegin, int srcEnd, char dst[], int dstBegin)
166   {
167     if (srcBegin < 0 || srcBegin > srcEnd)
168       throw new StringIndexOutOfBoundsException JavaDoc(srcBegin);
169     if (srcEnd > size)
170       throw new StringIndexOutOfBoundsException JavaDoc(srcEnd);
171     if (dstBegin+srcEnd-srcBegin > dst.length)
172       throw new StringIndexOutOfBoundsException JavaDoc(dstBegin);
173     if (srcBegin < srcEnd)
174       System.arraycopy(data, srcBegin, dst, dstBegin, srcEnd - srcBegin);
175   }
176
177   public void getChars (int srcBegin, int srcEnd, StringBuffer JavaDoc dst)
178   {
179     if (srcBegin < 0 || srcBegin > srcEnd)
180       throw new StringIndexOutOfBoundsException JavaDoc(srcBegin);
181     if (srcEnd > size)
182       throw new StringIndexOutOfBoundsException JavaDoc(srcEnd);
183     if (srcBegin < srcEnd)
184       dst.append(data, srcBegin, srcEnd - srcBegin);
185   }
186
187   public void getChars (StringBuffer JavaDoc dst)
188   {
189     dst.append(data, 0, size);
190   }
191
192   /** Return a char[] contain the characters of this string.
193    * It is unspecified if the result is a copy or shares with this FString.
194    */

195   public char[] toCharArray()
196   {
197     int val_length = data.length;
198     int seq_length = size;
199     if (seq_length == val_length)
200       return data;
201     else
202       {
203     char[] tmp = new char[seq_length];
204     System.arraycopy(data, 0, tmp, 0, seq_length);
205     return tmp;
206       }
207   }
208
209   public void shift(int srcStart, int dstStart, int count)
210   {
211     System.arraycopy(data, srcStart, data, dstStart, count);
212   }
213
214   public FString copy (int start, int end)
215   {
216     char[] copy = new char[end-start];
217     for (int i = start; i < end; i++)
218       copy[i-start] = data[i];
219     return new FString(copy);
220   }
221
222   /** Append all the characters of another <code>FString</code>. */
223   public boolean addAll(FString s)
224   {
225     int newSize = size + s.size;
226     if (data.length < newSize)
227       setBufferLength(newSize);
228     System.arraycopy(s.data, 0, data, size, s.size);
229     size = newSize;
230     return s.size > 0;
231   }
232     
233   /** Append arguments to this FString.
234    * Used to implement Scheme's string-append and string-append/shared.
235    * @param args an array of FString value
236    * @param startIndex index of first string in <code>args</code> to use
237    */

238   public void addAllStrings(Object JavaDoc[] args, int startIndex)
239   {
240     int total = size;
241     for (int i = startIndex; i < args.length; ++i)
242       total += ((FString) args[i]).size;
243     if (data.length < total)
244     setBufferLength(total);
245     
246     for (int i = startIndex; i < args.length; ++i)
247       addAll((FString) args[i]);
248   }
249   
250   public String JavaDoc toString ()
251   {
252     return new String JavaDoc (data, 0, size);
253   }
254
255   public String JavaDoc substring(int start, int end)
256   {
257     return new String JavaDoc (data, start, end - start);
258   }
259
260   /* #ifdef use:java.lang.CharSequence */
261   public CharSequence JavaDoc subSequence(int start, int end)
262   {
263     return new FString(data, start, end-start);
264   }
265   /* #endif */
266
267   public void setCharAt (int index, char ch)
268   {
269     if (index < 0 || index >= size)
270       throw new StringIndexOutOfBoundsException JavaDoc(index);
271     data[index] = ch;
272   }
273
274   public void setCharAtBuffer (int index, char ch)
275   {
276     data[index] = ch;
277   }
278
279   /** Set all the elements to a given character. */
280   public final void fill (char ch)
281   {
282     for (int i = size; --i >= 0; )
283       data[i] = ch;
284   }
285
286   public void fill(int fromIndex, int toIndex, char value)
287   {
288     if (fromIndex < 0 || toIndex > size)
289       throw new IndexOutOfBoundsException JavaDoc();
290     for (int i = fromIndex; i < toIndex; i++)
291       data[i] = value;
292   }
293
294   protected void clearBuffer(int start, int count)
295   {
296     while (--count >= 0)
297       data[start++] = 0;
298   }
299
300   public void replace(int where, char[] chars, int start, int count)
301   {
302     System.arraycopy(chars, start, data, where, count);
303   }
304
305   public void replace(int where, String JavaDoc string)
306   {
307     string.getChars(0, string.length(), data, where);
308   }
309
310   public int hashCode ()
311   {
312     /* Matches String.hashCode specification, as updated specification in
313        http://www.javasoft.com/docs/books/jls/clarify.html. */

314     char[] val = data;
315     int len = size;
316     int hash = 0;
317     for (int i = 0; i < len; i++)
318       hash = 31 * hash + val[i];
319     return hash;
320   }
321
322   public boolean equals (Object JavaDoc obj)
323   {
324     if (obj == null || !(obj instanceof FString))
325       return false;
326     char[] str = ((FString) obj).data;
327     int n = size;
328     if (str == null || str.length != n)
329       return false;
330     for (int i = n; --i >= 0; )
331       {
332     if (data[i] != str[i])
333       return false;
334       }
335     return true;
336   }
337
338    public int compareTo(Object JavaDoc obj)
339   {
340     FString str2 = (FString) obj;
341     char[] cs1 = data;
342     char[] cs2 = str2.data;
343     int n1 = size;
344     int n2 = str2.size;
345     int n = n1 > n2 ? n2 : n1;
346     for (int i = 0; i < n; i++)
347       {
348     char c1 = cs1[i];
349     char c2 = cs2[i];
350     int d = c1 - c2;
351     if (d != 0)
352       return d;
353       }
354     return n1 - n2;
355   }
356
357  public int getElementKind()
358   {
359     return CHAR_VALUE;
360   }
361
362   public void consume(Consumer out)
363   {
364     out.write(data, 0, data.length);
365   }
366
367   public boolean consumeNext (int ipos, Consumer out)
368   {
369     int index = ipos >>> 1;
370     if (index >= size)
371       return false;
372     out.write(data[index]);
373     return true;
374   }
375
376   public void consumePosRange (int iposStart, int iposEnd, Consumer out)
377   {
378     if (out.ignoring())
379       return;
380     int i = iposStart >>> 1;
381     int end = iposEnd >>> 1;
382     if (end > size)
383       end = size;
384     if (end > i)
385       out.write(data, i, end - i);
386   }
387
388   public FString append (char c)
389   {
390     int sz = size;
391     if (sz >= data.length)
392       ensureBufferLength(sz+1);
393     char[] d = data;
394     d[sz] = c;
395     size = sz + 1;
396     return this;
397   }
398
399   /* #ifdef use:java.lang.CharSequence */
400   public FString append (CharSequence JavaDoc csq)
401   {
402     if (csq == null)
403       csq = "null";
404     return append(csq, 0, csq.length());
405   }
406
407   public FString append (CharSequence JavaDoc csq, int start, int end)
408   {
409     if (csq == null)
410       csq = "null";
411     /* FIXME optimize to use getChars if csq is a CharSeq. */
412     for (int i = start; i < end; i++)
413       append(csq.charAt(i));
414     return this;
415   }
416   /* #else */
417   // public FString append (String str)
418
// {
419
// int len = str.length();
420
// ensureBufferLength(size+len);
421
// str.getChars(0, len, data, size);
422
// size += len;
423
// return this;
424
// }
425
/* #endif */
426
427   /* #ifdef JAVA5 */
428   // public void writeTo(int start, int count, Appendable dest)
429
// throws java.io.IOException
430
// {
431
// if (dest instanceof java.io.Writer)
432
// {
433
// try
434
// {
435
// ((java.io.Writer) dest).write(data, start, count);
436
// }
437
// catch (java.io.IOException ex)
438
// {
439
// throw new RuntimeException(ex);
440
// }
441
// }
442
// else
443
// {
444
// dest.append(this, start, start+count);
445
// }
446
// }
447

448   // public void writeTo(Appendable dest) throws java.io.IOException
449
// {
450
// writeTo(0, size, dest);
451
// }
452
/* #else */
453   public void writeTo(int start, int count, java.io.Writer JavaDoc dest)
454     throws java.io.IOException JavaDoc
455   {
456     dest.write(data, start, count);
457   }
458
459   public void writeTo(java.io.Writer JavaDoc dest) throws java.io.IOException JavaDoc
460   {
461     dest.write(data, 0, size);
462   }
463   /* #endif */
464
465   /**
466    * @serialData Write 'size' (using writeInt),
467    * followed by 'size' elements in order (using writeChar).
468    */

469   public void writeExternal(ObjectOutput out) throws IOException
470   {
471     int size = this.size;
472     out.writeInt(size);
473     for (int i = 0; i < size; i++)
474       out.writeChar(data[i]);
475   }
476
477   public void readExternal(ObjectInput in)
478     throws IOException, ClassNotFoundException JavaDoc
479   {
480     int size = in.readInt();
481     char[] data = new char[size];
482     for (int i = 0; i < size; i++)
483       data[i] = in.readChar();
484     this.data = data;
485     this.size = size;
486   }
487 }
488
Popular Tags