source: branches/0.17.x/abcl/src/org/armedbear/lisp/SimpleString.java

Last change on this file was 12254, checked in by ehuelsmann, 16 years ago

Remove 'throws ConditionThrowable?' method annotations:

it's an unchecked exception now, so no need to declare it thrown.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.9 KB
Line 
1/*
2 * SimpleString.java
3 *
4 * Copyright (C) 2004-2005 Peter Graves
5 * $Id: SimpleString.java 12254 2009-11-06 20:07:54Z ehuelsmann $
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 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36public final class SimpleString extends AbstractString
37{
38    private int capacity;
39    private char[] chars;
40
41    public SimpleString(LispCharacter c)
42    {
43        chars = new char[1];
44        chars[0] = c.value;
45        capacity = 1;
46    }
47
48    public SimpleString(char c)
49    {
50        chars = new char[1];
51        chars[0] = c;
52        capacity = 1;
53    }
54
55    public SimpleString(int capacity)
56    {
57        this.capacity = capacity;
58        chars = new char[capacity];
59    }
60
61    public SimpleString(String s)
62    {
63        capacity = s.length();
64        chars = s.toCharArray();
65    }
66
67    public SimpleString(StringBuffer sb)
68    {
69        chars = new char[capacity = sb.length()];
70        sb.getChars(0, capacity, chars, 0);
71    }
72
73    public SimpleString(FastStringBuffer sb)
74    {
75        chars = sb.toCharArray();
76        capacity = chars.length;
77    }
78
79    private SimpleString(char[] chars)
80    {
81        this.chars = chars;
82        capacity = chars.length;
83    }
84
85    @Override
86    public char[] chars()
87    {
88        return chars;
89    }
90
91    @Override
92    public char[] getStringChars()
93    {
94        return chars;
95    }
96
97    @Override
98    public LispObject typeOf()
99    {
100        return list(Symbol.SIMPLE_BASE_STRING, Fixnum.getInstance(capacity));
101    }
102
103    @Override
104    public LispObject classOf()
105    {
106        return BuiltInClass.SIMPLE_BASE_STRING;
107    }
108
109    @Override
110    public LispObject getDescription()
111    {
112        FastStringBuffer sb = new FastStringBuffer("A simple-string (");
113        sb.append(capacity);
114        sb.append(") \"");
115        sb.append(chars);
116        sb.append('"');
117        return new SimpleString(sb);
118    }
119
120    @Override
121    public LispObject typep(LispObject type)
122    {
123        if (type == Symbol.SIMPLE_STRING)
124            return T;
125        if (type == Symbol.SIMPLE_ARRAY)
126            return T;
127        if (type == Symbol.SIMPLE_BASE_STRING)
128            return T;
129        if (type == BuiltInClass.SIMPLE_STRING)
130            return T;
131        if (type == BuiltInClass.SIMPLE_ARRAY)
132            return T;
133        if (type == BuiltInClass.SIMPLE_BASE_STRING)
134            return T;
135        return super.typep(type);
136    }
137
138    @Override
139    public LispObject SIMPLE_STRING_P()
140    {
141        return T;
142    }
143
144    @Override
145    public boolean hasFillPointer()
146    {
147        return false;
148    }
149
150    @Override
151    public boolean isAdjustable()
152    {
153        return false;
154    }
155
156    @Override
157    public boolean equal(LispObject obj)
158    {
159        if (this == obj)
160            return true;
161        if (obj instanceof SimpleString) {
162            SimpleString string = (SimpleString) obj;
163            if (string.capacity != capacity)
164                return false;
165            for (int i = capacity; i-- > 0;)
166                if (string.chars[i] != chars[i])
167                    return false;
168            return true;
169        }
170        if (obj instanceof AbstractString) {
171            AbstractString string = (AbstractString) obj;
172            if (string.length() != capacity)
173                return false;
174            for (int i = length(); i-- > 0;)
175                if (string.charAt(i) != chars[i])
176                    return false;
177            return true;
178        }
179        if (obj instanceof NilVector)
180            return obj.equal(this);
181        return false;
182    }
183
184    @Override
185    public boolean equalp(LispObject obj)
186    {
187        if (this == obj)
188            return true;
189        if (obj instanceof SimpleString) {
190            SimpleString string = (SimpleString) obj;
191            if (string.capacity != capacity)
192                return false;
193            for (int i = capacity; i-- > 0;) {
194                if (string.chars[i] != chars[i]) {
195                    if (LispCharacter.toLowerCase(string.chars[i]) != LispCharacter.toLowerCase(chars[i]))
196                        return false;
197                }
198            }
199            return true;
200        }
201        if (obj instanceof AbstractString) {
202            AbstractString string = (AbstractString) obj;
203            if (string.length() != capacity)
204                return false;
205            for (int i = length(); i-- > 0;) {
206                if (string.charAt(i) != chars[i]) {
207                    if (LispCharacter.toLowerCase(string.charAt(i)) != LispCharacter.toLowerCase(chars[i]))
208                        return false;
209                }
210            }
211            return true;
212        }
213        if (obj instanceof AbstractBitVector)
214            return false;
215        if (obj instanceof AbstractArray)
216            return obj.equalp(this);
217        return false;
218    }
219
220    public final SimpleString substring(int start)
221    {
222        return substring(start, capacity);
223    }
224
225    public final SimpleString substring(int start, int end)
226
227    {
228        SimpleString s = new SimpleString(end - start);
229        int i = start, j = 0;
230        try {
231            while (i < end)
232                s.chars[j++] = chars[i++];
233            return s;
234        }
235        catch (ArrayIndexOutOfBoundsException e) {
236            error(new TypeError("Array index out of bounds: " + i));
237            // Not reached.
238            return null;
239        }
240    }
241
242    @Override
243    public final LispObject subseq(int start, int end)
244    {
245        return substring(start, end);
246    }
247
248    @Override
249    public void fill(LispObject obj)
250    {
251        fill(LispCharacter.getValue(obj));
252    }
253
254    @Override
255    public void fill(char c)
256    {
257        for (int i = capacity; i-- > 0;)
258            chars[i] = c;
259    }
260
261    @Override
262    public void shrink(int n)
263    {
264        if (n < capacity) {
265            char[] newArray = new char[n];
266            System.arraycopy(chars, 0, newArray, 0, n);
267            chars = newArray;
268            capacity = n;
269            return;
270        }
271        if (n == capacity)
272            return;
273        error(new LispError());
274    }
275
276    @Override
277    public LispObject reverse()
278    {
279        SimpleString result = new SimpleString(capacity);
280        int i, j;
281        for (i = 0, j = capacity - 1; i < capacity; i++, j--)
282            result.chars[i] = chars[j];
283        return result;
284    }
285
286    @Override
287    public LispObject nreverse()
288    {
289        int i = 0;
290        int j = capacity - 1;
291        while (i < j) {
292            char temp = chars[i];
293            chars[i] = chars[j];
294            chars[j] = temp;
295            ++i;
296            --j;
297        }
298        return this;
299    }
300
301    @Override
302    public String getStringValue()
303    {
304        return String.valueOf(chars);
305    }
306
307    @Override
308    public Object javaInstance()
309    {
310        return String.valueOf(chars);
311    }
312
313    @Override
314    public Object javaInstance(Class c)
315    {
316        return javaInstance();
317    }
318
319    @Override
320    public final int capacity()
321    {
322        return capacity;
323    }
324
325    @Override
326    public final int length()
327    {
328        return capacity;
329    }
330
331    @Override
332    public char charAt(int index)
333    {
334        try {
335            return chars[index];
336        }
337        catch (ArrayIndexOutOfBoundsException e) {
338            badIndex(index, capacity);
339            return 0; // Not reached.
340        }
341    }
342
343    @Override
344    public void setCharAt(int index, char c)
345    {
346        try {
347            chars[index] = c;
348        }
349        catch (ArrayIndexOutOfBoundsException e) {
350            badIndex(index, capacity);
351        }
352    }
353
354    @Override
355    public LispObject elt(int index)
356    {
357        try {
358            return LispCharacter.getInstance(chars[index]);
359        }
360        catch (ArrayIndexOutOfBoundsException e) {
361            badIndex(index, capacity);
362            return NIL; // Not reached.
363        }
364    }
365
366    @Override
367    public LispObject CHAR(int index)
368    {
369        try {
370            return LispCharacter.getInstance(chars[index]);
371        }
372        catch (ArrayIndexOutOfBoundsException e) {
373            badIndex(index, capacity);
374            return NIL; // Not reached.
375        }
376    }
377
378    @Override
379    public LispObject SCHAR(int index)
380    {
381        try {
382            return LispCharacter.getInstance(chars[index]);
383        }
384        catch (ArrayIndexOutOfBoundsException e) {
385            badIndex(index, capacity);
386            return NIL; // Not reached.
387        }
388    }
389
390    @Override
391    public LispObject AREF(int index)
392    {
393        try {
394            return LispCharacter.getInstance(chars[index]);
395        }
396        catch (ArrayIndexOutOfBoundsException e) {
397            badIndex(index, capacity);
398            return NIL; // Not reached.
399        }
400    }
401
402    @Override
403    public LispObject AREF(LispObject index)
404    {
405        try {
406            return LispCharacter.getInstance(chars[Fixnum.getValue(index)]);
407        }
408        catch (ArrayIndexOutOfBoundsException e) {
409            badIndex(((Fixnum)index).value, capacity);
410            return NIL; // Not reached.
411        }
412    }
413
414    @Override
415    public void aset(int index, LispObject obj)
416    {
417        try {
418            chars[index] = LispCharacter.getValue(obj);
419        }
420        catch (ArrayIndexOutOfBoundsException e) {
421            badIndex(index, capacity);
422        }
423    }
424
425    @Override
426    public int sxhash()
427    {
428        int hashCode = 0;
429        for (int i = 0; i < capacity; i++) {
430            hashCode += chars[i];
431            hashCode += (hashCode << 10);
432            hashCode ^= (hashCode >> 6);
433        }
434        hashCode += (hashCode << 3);
435        hashCode ^= (hashCode >> 11);
436        hashCode += (hashCode << 15);
437        return (hashCode & 0x7fffffff);
438    }
439
440    // For EQUALP hash tables.
441    @Override
442    public int psxhash()
443    {
444        int hashCode = 0;
445        for (int i = 0; i < capacity; i++) {
446            hashCode += Character.toUpperCase(chars[i]);
447            hashCode += (hashCode << 10);
448            hashCode ^= (hashCode >> 6);
449        }
450        hashCode += (hashCode << 3);
451        hashCode ^= (hashCode >> 11);
452        hashCode += (hashCode << 15);
453        return (hashCode & 0x7fffffff);
454    }
455
456    @Override
457    public AbstractVector adjustArray(int newCapacity,
458                                       LispObject initialElement,
459                                       LispObject initialContents)
460
461    {
462        if (initialContents != null) {
463            char[] newChars = new char[newCapacity];
464            if (initialContents.listp()) {
465                LispObject list = initialContents;
466                for (int i = 0; i < newCapacity; i++) {
467                    newChars[i] = LispCharacter.getValue(list.car());
468                    list = list.cdr();
469                }
470            } else if (initialContents.vectorp()) {
471                for (int i = 0; i < newCapacity; i++)
472                    newChars[i] = LispCharacter.getValue(initialContents.elt(i));
473            } else
474                type_error(initialContents, Symbol.SEQUENCE);
475            return new SimpleString(newChars);
476        }
477        if (capacity != newCapacity) {
478            char[] newChars = new char[newCapacity];
479            System.arraycopy(chars, 0, newChars, 0, Math.min(newCapacity, capacity));
480            if (initialElement != null && capacity < newCapacity) {
481                final char c = LispCharacter.getValue(initialElement);
482                for (int i = capacity; i < newCapacity; i++)
483                    newChars[i] = c;
484            }
485            return new SimpleString(newChars);
486        }
487        // No change.
488        return this;
489    }
490
491    @Override
492    public AbstractVector adjustArray(int newCapacity,
493                                       AbstractArray displacedTo,
494                                       int displacement)
495
496    {
497        return new ComplexString(newCapacity, displacedTo, displacement);
498    }
499}
Note: See TracBrowser for help on using the repository browser.