KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > lisp > SimpleString


1 /*
2  * SimpleString.java
3  *
4  * Copyright (C) 2004 Peter Graves
5  * $Id: SimpleString.java,v 1.18 2004/09/21 00:38:29 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.lisp;
23
24 public final class SimpleString extends AbstractString
25 {
26     private int capacity;
27     private char[] chars;
28
29     public SimpleString(LispCharacter c)
30     {
31         chars = new char[1];
32         chars[0] = c.getValue();
33         capacity = 1;
34     }
35
36     public SimpleString(char c)
37     {
38         chars = new char[1];
39         chars[0] = c;
40         capacity = 1;
41     }
42
43     public SimpleString(int capacity)
44     {
45         this.capacity = capacity;
46         chars = new char[capacity];
47     }
48
49     public SimpleString(String JavaDoc s)
50     {
51         capacity = s.length();
52         chars = s.toCharArray();
53     }
54
55     public SimpleString(StringBuffer JavaDoc sb)
56     {
57         chars = new char[capacity = sb.length()];
58         sb.getChars(0, capacity, chars, 0);
59     }
60
61     private SimpleString(char[] chars)
62     {
63         this.chars = chars;
64         capacity = chars.length;
65     }
66
67     public char[] chars()
68     {
69         return chars;
70     }
71
72     public char[] getStringChars()
73     {
74         return chars;
75     }
76
77     // Used by jvm compiler.
78
public static SimpleString getInstance(String JavaDoc s)
79     {
80         return new SimpleString(s);
81     }
82
83     public LispObject typeOf()
84     {
85         return list2(Symbol.SIMPLE_STRING, new Fixnum(capacity));
86     }
87
88     public LispClass classOf()
89     {
90         return BuiltInClass.SIMPLE_STRING;
91     }
92
93     public LispObject getDescription()
94     {
95         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("A simple-string (");
96         sb.append(capacity);
97         sb.append(") \"");
98         sb.append(chars);
99         sb.append('"');
100         return new SimpleString(sb);
101     }
102
103     public LispObject typep(LispObject type) throws ConditionThrowable
104     {
105         if (type == Symbol.SIMPLE_STRING)
106             return T;
107         if (type == Symbol.SIMPLE_BASE_STRING)
108             return T;
109         if (type == Symbol.SIMPLE_ARRAY)
110             return T;
111         if (type == BuiltInClass.SIMPLE_STRING)
112             return T;
113         if (type == BuiltInClass.SIMPLE_ARRAY)
114             return T;
115         return super.typep(type);
116     }
117
118     public LispObject SIMPLE_STRING_P()
119     {
120         return T;
121     }
122
123     public boolean hasFillPointer()
124     {
125         return false;
126     }
127
128     public boolean isAdjustable()
129     {
130         return false;
131     }
132
133     public boolean equal(LispObject obj) throws ConditionThrowable
134     {
135         if (this == obj)
136             return true;
137         if (obj instanceof SimpleString) {
138             SimpleString string = (SimpleString) obj;
139             if (string.capacity != capacity)
140                 return false;
141             for (int i = capacity; i-- > 0;)
142                 if (string.chars[i] != chars[i])
143                     return false;
144             return true;
145         }
146         if (obj instanceof AbstractString) {
147             AbstractString string = (AbstractString) obj;
148             if (string.length() != capacity)
149                 return false;
150             for (int i = length(); i-- > 0;)
151                 if (string.getChar(i) != chars[i])
152                     return false;
153             return true;
154         }
155         if (obj instanceof NilVector)
156             return obj.equal(this);
157         return false;
158     }
159
160     public boolean equalp(LispObject obj) throws ConditionThrowable
161     {
162         if (this == obj)
163             return true;
164         if (obj instanceof SimpleString) {
165             SimpleString string = (SimpleString) obj;
166             if (string.capacity != capacity)
167                 return false;
168             for (int i = capacity; i-- > 0;) {
169                 if (string.chars[i] != chars[i]) {
170                     if (Utilities.toLowerCase(string.chars[i]) != Utilities.toLowerCase(chars[i]))
171                         return false;
172                 }
173             }
174             return true;
175         }
176         if (obj instanceof AbstractString) {
177             AbstractString string = (AbstractString) obj;
178             if (string.length() != capacity)
179                 return false;
180             for (int i = length(); i-- > 0;) {
181                 if (string.getChar(i) != chars[i]) {
182                     if (Utilities.toLowerCase(string.getChar(i)) != Utilities.toLowerCase(chars[i]))
183                         return false;
184                 }
185             }
186             return true;
187         }
188         if (obj instanceof AbstractArray)
189             return obj.equalp(this);
190         return false;
191     }
192
193     public LispObject subseq(int start, int end) throws ConditionThrowable
194     {
195         SimpleString s = new SimpleString(end - start);
196         int i = start, j = 0;
197         try {
198             while (i < end)
199                 s.chars[j++] = chars[i++];
200             return s;
201         }
202         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
203             return signal(new TypeError("Array index out of bounds: " + i));
204         }
205     }
206
207     public void fill(LispObject obj) throws ConditionThrowable
208     {
209         fill(LispCharacter.getValue(obj));
210     }
211
212     public void fill(char c)
213     {
214         for (int i = capacity; i-- > 0;)
215             chars[i] = c;
216     }
217
218     public void shrink(int n) throws ConditionThrowable
219     {
220         if (n < capacity) {
221             char[] newArray = new char[n];
222             System.arraycopy(chars, 0, newArray, 0, n);
223             chars = newArray;
224             capacity = n;
225             return;
226         }
227         if (n == capacity)
228             return;
229         signal(new LispError());
230     }
231
232     public LispObject reverse() throws ConditionThrowable
233     {
234         SimpleString result = new SimpleString(capacity);
235         int i, j;
236         for (i = 0, j = capacity - 1; i < capacity; i++, j--)
237             result.chars[i] = chars[j];
238         return result;
239     }
240
241     public LispObject nreverse() throws ConditionThrowable
242     {
243         int i = 0;
244         int j = capacity - 1;
245         while (i < j) {
246             char temp = chars[i];
247             chars[i] = chars[j];
248             chars[j] = temp;
249             ++i;
250             --j;
251         }
252         return this;
253     }
254
255     public LispObject getRowMajor(int index) throws ConditionThrowable
256     {
257         try {
258             return LispCharacter.getInstance(chars[index]);
259         }
260         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
261             badIndex(index, capacity);
262             return NIL; // Not reached.
263
}
264     }
265
266     public void setRowMajor(int index, LispObject newValue) throws ConditionThrowable
267     {
268         try {
269             chars[index] = LispCharacter.getValue(newValue);
270         }
271         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
272             badIndex(index, capacity);
273         }
274     }
275
276     public char getChar(int index) throws ConditionThrowable
277     {
278         try {
279             return chars[index];
280         }
281         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
282             badIndex(index, capacity);
283             return 0; // Not reached.
284
}
285     }
286
287     public void setChar(int index, char c) throws ConditionThrowable
288     {
289         try {
290             chars[index] = c;
291         }
292         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
293             badIndex(index, capacity);
294         }
295     }
296
297     public String JavaDoc getStringValue()
298     {
299         return new String JavaDoc(chars);
300     }
301
302     public Object JavaDoc javaInstance()
303     {
304         return new String JavaDoc(chars);
305     }
306
307     public Object JavaDoc javaInstance(Class JavaDoc c)
308     {
309         return javaInstance();
310     }
311
312     public final int capacity()
313     {
314         return capacity;
315     }
316
317     public final int length()
318     {
319         return capacity;
320     }
321
322     public LispObject elt(int index) throws ConditionThrowable
323     {
324         try {
325             return LispCharacter.getInstance(chars[index]);
326         }
327         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
328             badIndex(index, capacity);
329             return NIL; // Not reached.
330
}
331     }
332
333     // Ignores fill pointer.
334
public LispObject AREF(LispObject index) throws ConditionThrowable
335     {
336         try {
337             return LispCharacter.getInstance(chars[((Fixnum)index).value]);
338         }
339         catch (ClassCastException JavaDoc e) {
340             return signal(new TypeError(index, Symbol.FIXNUM));
341         }
342         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
343             badIndex(((Fixnum)index).value, capacity);
344             return NIL; // Not reached.
345
}
346     }
347
348     public int sxhash()
349     {
350         int hashCode = 0;
351         for (int i = 0; i < capacity; i++)
352             hashCode = hashCode * 31 + chars[i];
353         return (hashCode & 0x7fffffff);
354     }
355
356     // For EQUALP hash tables.
357
public int psxhash()
358     {
359         int hashCode = 0;
360         for (int i = 0; i < capacity; i++)
361             hashCode = hashCode * 31 + Character.toUpperCase(chars[i]);
362         return (hashCode & 0x7fffffff);
363     }
364
365     public AbstractVector adjustVector(int newCapacity,
366                                        LispObject initialElement,
367                                        LispObject initialContents)
368         throws ConditionThrowable
369     {
370         if (initialContents != NIL) {
371             char[] newChars = new char[newCapacity];
372             if (initialContents.listp()) {
373                 LispObject list = initialContents;
374                 for (int i = 0; i < newCapacity; i++) {
375                     newChars[i] = LispCharacter.getValue(list.car());
376                     list = list.cdr();
377                 }
378             } else if (initialContents.vectorp()) {
379                 for (int i = 0; i < newCapacity; i++)
380                     newChars[i] = LispCharacter.getValue(initialContents.elt(i));
381             } else
382                 signal(new TypeError(initialContents, Symbol.SEQUENCE));
383             return new SimpleString(newChars);
384         }
385         if (capacity != newCapacity) {
386             char[] newChars = new char[newCapacity];
387             System.arraycopy(chars, 0, newChars, 0, Math.min(newCapacity, capacity));
388             if (initialElement != NIL && capacity < newCapacity) {
389                 final char c = LispCharacter.getValue(initialElement);
390                 for (int i = capacity; i < newCapacity; i++)
391                     newChars[i] = c;
392             }
393             return new SimpleString(newChars);
394         }
395         // No change.
396
return this;
397     }
398
399     public AbstractVector adjustVector(int newCapacity,
400                                        AbstractArray displacedTo,
401                                        int displacement)
402         throws ConditionThrowable
403     {
404         return new ComplexString(newCapacity, displacedTo, displacement);
405     }
406
407     // ### schar
408
private static final Primitive2 SCHAR = new Primitive2("schar", "string index")
409     {
410         public LispObject execute(LispObject first, LispObject second)
411             throws ConditionThrowable
412         {
413             try {
414                 return LispCharacter.getInstance(((SimpleString)first).chars[((Fixnum)second).value]);
415             }
416             catch (ClassCastException JavaDoc e) {
417                 if (first instanceof SimpleString)
418                     return signal(new TypeError(second, Symbol.FIXNUM));
419                 else
420                     return signal(new TypeError(first, Symbol.SIMPLE_STRING));
421             }
422             catch (ArrayIndexOutOfBoundsException JavaDoc e) {
423                 return signal(new TypeError("Array index out of bounds: " +
424                                             ((Fixnum)second).value));
425             }
426         }
427     };
428
429     // ### %set-schar
430
private static final Primitive3 _SET_SCHAR =
431         new Primitive3("%set-schar", PACKAGE_SYS, false)
432     {
433         public LispObject execute(LispObject first, LispObject second,
434                                   LispObject third)
435             throws ConditionThrowable
436         {
437             try {
438                 ((SimpleString)first).chars[((Fixnum)second).value] =
439                     ((LispCharacter)third).value;
440                 return third;
441             }
442             catch (ClassCastException JavaDoc e) {
443                 if (!(first instanceof SimpleString))
444                     return signal(new TypeError(first, Symbol.SIMPLE_STRING));
445                 if (!(second instanceof Fixnum))
446                     return signal(new TypeError(second, Symbol.FIXNUM));
447                 return signal(new TypeError(third, Symbol.CHARACTER));
448             }
449             catch (ArrayIndexOutOfBoundsException JavaDoc e) {
450                 return signal(new TypeError("Array index out of bounds: " +
451                                             ((Fixnum)second).value));
452             }
453         }
454     };
455 }
456
Popular Tags