source: branches/0.17.x/abcl/src/org/armedbear/lisp/ComplexVector_UnsignedByte8.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: 13.1 KB
Line 
1/*
2 * ComplexVector_UnsignedByte8.java
3 *
4 * Copyright (C) 2002-2005 Peter Graves
5 * $Id: ComplexVector_UnsignedByte8.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
36// A specialized vector of element type (UNSIGNED-BYTE 8) that is displaced to
37// another array, has a fill pointer, and/or is expressly adjustable.
38public final class ComplexVector_UnsignedByte8 extends AbstractVector
39{
40    private int capacity;
41    private int fillPointer = -1; // -1 indicates no fill pointer.
42    private boolean isDisplaced;
43
44    // For non-displaced arrays.
45    private byte[] elements;
46
47    // For displaced arrays.
48    private AbstractArray array;
49    private int displacement;
50
51    public ComplexVector_UnsignedByte8(int capacity)
52    {
53        elements = new byte[capacity];
54        this.capacity = capacity;
55    }
56
57    public ComplexVector_UnsignedByte8(int capacity, AbstractArray array,
58                                       int displacement)
59    {
60        this.capacity = capacity;
61        this.array = array;
62        this.displacement = displacement;
63        isDisplaced = true;
64    }
65
66    @Override
67    public LispObject typeOf()
68    {
69        return list(Symbol.VECTOR, UNSIGNED_BYTE_8, Fixnum.getInstance(capacity));
70    }
71
72    @Override
73    public LispObject classOf()
74    {
75        return BuiltInClass.VECTOR;
76    }
77
78    @Override
79    public boolean hasFillPointer()
80    {
81        return fillPointer >= 0;
82    }
83
84    @Override
85    public int getFillPointer()
86    {
87        return fillPointer;
88    }
89
90    @Override
91    public void setFillPointer(int n)
92    {
93        fillPointer = n;
94    }
95
96    @Override
97    public void setFillPointer(LispObject obj)
98    {
99        if (obj == T)
100            fillPointer = capacity();
101        else {
102            int n = Fixnum.getValue(obj);
103            if (n > capacity()) {
104                StringBuffer sb = new StringBuffer("The new fill pointer (");
105                sb.append(n);
106                sb.append(") exceeds the capacity of the vector (");
107                sb.append(capacity());
108                sb.append(").");
109                error(new LispError(sb.toString()));
110            } else if (n < 0) {
111                StringBuffer sb = new StringBuffer("The new fill pointer (");
112                sb.append(n);
113                sb.append(") is negative.");
114                error(new LispError(sb.toString()));
115            } else
116                fillPointer = n;
117        }
118    }
119
120    @Override
121    public boolean isDisplaced()
122    {
123        return isDisplaced;
124    }
125
126    @Override
127    public LispObject arrayDisplacement()
128    {
129        LispObject value1, value2;
130        if (array != null) {
131            value1 = array;
132            value2 = Fixnum.getInstance(displacement);
133        } else {
134            value1 = NIL;
135            value2 = Fixnum.ZERO;
136        }
137        return LispThread.currentThread().setValues(value1, value2);
138    }
139
140    @Override
141    public LispObject getElementType()
142    {
143        return UNSIGNED_BYTE_8;
144    }
145
146    @Override
147    public boolean isSimpleVector()
148    {
149        return false;
150    }
151
152    @Override
153    public int capacity()
154    {
155        return capacity;
156    }
157
158    @Override
159    public int length()
160    {
161        return fillPointer >= 0 ? fillPointer : capacity;
162    }
163
164    @Override
165    public LispObject elt(int index)
166    {
167        final int limit = length();
168        if (index < 0 || index >= limit)
169            badIndex(index, limit);
170        return AREF(index);
171    }
172
173    // Ignores fill pointer.
174    @Override
175    public LispObject AREF(int index)
176    {
177        if (elements != null) {
178            try {
179                return coerceJavaByteToLispObject(elements[index]);
180            }
181            catch (ArrayIndexOutOfBoundsException e) {
182                badIndex(index, elements.length);
183                return NIL; // Not reached.
184            }
185        } else {
186            // Displaced array.
187            if (index < 0 || index >= capacity)
188                badIndex(index, capacity);
189            return array.AREF(index + displacement);
190        }
191    }
192
193    // Ignores fill pointer.
194    // FIXME inline
195    @Override
196    public LispObject AREF(LispObject index)
197    {
198        return AREF(Fixnum.getValue(index));
199    }
200
201    @Override
202    public void aset(int index, int n)
203    {
204        if (elements != null) {
205            try {
206                elements[index] = (byte) n;
207            }
208            catch (ArrayIndexOutOfBoundsException e) {
209                badIndex(index, elements.length);
210            }
211        } else {
212            // Displaced array.
213            if (index < 0 || index >= capacity)
214                badIndex(index, capacity);
215            else
216                array.aset(index + displacement, n);
217        }
218    }
219
220    @Override
221    public void aset(int index, LispObject newValue)
222    {
223        if (elements != null) {
224            try {
225                elements[index] = coerceLispObjectToJavaByte(newValue);
226            }
227            catch (ArrayIndexOutOfBoundsException e) {
228                badIndex(index, elements.length);
229            }
230        } else
231            array.aset(index + displacement, newValue);
232    }
233
234    @Override
235    public LispObject subseq(int start, int end)
236    {
237        SimpleVector v = new SimpleVector(end - start);
238        int i = start, j = 0;
239        try {
240            while (i < end)
241                v.aset(j++, AREF(i++));
242            return v;
243        }
244        catch (ArrayIndexOutOfBoundsException e) {
245            return error(new TypeError("Array index out of bounds: " + i + "."));
246        }
247    }
248
249    @Override
250    public void fill(LispObject obj)
251    {
252        byte b = (byte) Fixnum.getValue(obj);
253        for (int i = capacity; i-- > 0;)
254            elements[i] = b;
255    }
256
257    @Override
258    public void shrink(int n)
259    {
260        if (elements != null) {
261            if (n < elements.length) {
262                byte[] newArray = new byte[n];
263                System.arraycopy(elements, 0, newArray, 0, n);
264                elements = newArray;
265                capacity = n;
266                return;
267            }
268            if (n == elements.length)
269                return;
270        }
271        error(new LispError());
272    }
273
274    @Override
275    public LispObject reverse()
276    {
277        int length = length();
278        BasicVector_UnsignedByte8 result = new BasicVector_UnsignedByte8(length);
279        int i, j;
280        for (i = 0, j = length - 1; i < length; i++, j--)
281            result.aset(i, AREF(j));
282        return result;
283    }
284
285    @Override
286    public LispObject nreverse()
287    {
288        if (elements != null) {
289            int i = 0;
290            int j = length() - 1;
291            while (i < j) {
292                byte temp = elements[i];
293                elements[i] = elements[j];
294                elements[j] = temp;
295                ++i;
296                --j;
297            }
298        } else {
299            // Displaced array.
300            int length = length();
301            byte[] data = new byte[length];
302            int i, j;
303            for (i = 0, j = length - 1; i < length; i++, j--)
304                data[i] = coerceLispObjectToJavaByte(AREF(j));
305            elements = data;
306            capacity = length;
307            array = null;
308            displacement = 0;
309            isDisplaced = false;
310            fillPointer = -1;
311        }
312        return this;
313    }
314
315    @Override
316    public void vectorPushExtend(LispObject element)
317    {
318        if (fillPointer < 0)
319            noFillPointer();
320        if (fillPointer >= capacity) {
321            // Need to extend vector.
322            ensureCapacity(capacity * 2 + 1);
323        }
324        aset(fillPointer, element);
325        ++fillPointer;
326    }
327
328    @Override
329    public LispObject VECTOR_PUSH_EXTEND(LispObject element)
330
331    {
332        vectorPushExtend(element);
333        return Fixnum.getInstance(fillPointer - 1);
334    }
335
336    @Override
337    public LispObject VECTOR_PUSH_EXTEND(LispObject element, LispObject extension)
338
339    {
340        int ext = Fixnum.getValue(extension);
341        if (fillPointer < 0)
342            noFillPointer();
343        if (fillPointer >= capacity) {
344            // Need to extend vector.
345            ext = Math.max(ext, capacity + 1);
346            ensureCapacity(capacity + ext);
347        }
348        aset(fillPointer, element);
349        return Fixnum.getInstance(fillPointer++);
350    }
351
352    private final void ensureCapacity(int minCapacity)
353    {
354        if (elements != null) {
355            if (capacity < minCapacity) {
356                byte[] newArray = new byte[minCapacity];
357                System.arraycopy(elements, 0, newArray, 0, capacity);
358                elements = newArray;
359                capacity = minCapacity;
360            }
361        } else {
362            // Displaced array.
363            Debug.assertTrue(array != null);
364            if (capacity < minCapacity ||
365                array.getTotalSize() - displacement < minCapacity)
366            {
367                // Copy array.
368                elements = new byte[minCapacity];
369                final int limit =
370                    Math.min(capacity, array.getTotalSize() - displacement);
371                for (int i = 0; i < limit; i++)
372                    elements[i] = coerceLispObjectToJavaByte(array.AREF(displacement + i));
373                capacity = minCapacity;
374                array = null;
375                displacement = 0;
376                isDisplaced = false;
377            }
378        }
379    }
380
381    @Override
382    public AbstractVector adjustArray(int newCapacity,
383                                       LispObject initialElement,
384                                       LispObject initialContents)
385
386    {
387        if (initialContents != null) {
388            // "If INITIAL-CONTENTS is supplied, it is treated as for MAKE-
389            // ARRAY. In this case none of the original contents of array
390            // appears in the resulting array."
391            byte[] newElements = new byte[newCapacity];
392            if (initialContents.listp()) {
393                LispObject list = initialContents;
394                for (int i = 0; i < newCapacity; i++) {
395                    newElements[i] = coerceLispObjectToJavaByte(list.car());
396                    list = list.cdr();
397                }
398            } else if (initialContents.vectorp()) {
399                for (int i = 0; i < newCapacity; i++)
400                    newElements[i] = coerceLispObjectToJavaByte(initialContents.elt(i));
401            } else
402                error(new TypeError(initialContents, Symbol.SEQUENCE));
403            elements = newElements;
404        } else {
405            if (elements == null) {
406                // Displaced array. Copy existing elements.
407                elements = new byte[newCapacity];
408                final int limit = Math.min(capacity, newCapacity);
409                for (int i = 0; i < limit; i++)
410                    elements[i] = coerceLispObjectToJavaByte(array.AREF(displacement + i));
411            } else if (capacity != newCapacity) {
412                byte[] newElements = new byte[newCapacity];
413                System.arraycopy(elements, 0, newElements, 0,
414                                 Math.min(capacity, newCapacity));
415                elements = newElements;
416            }
417            // Initialize new elements (if aapplicable).
418            if (initialElement != null) {
419                byte b = coerceLispObjectToJavaByte(initialElement);
420                for (int i = capacity; i < newCapacity; i++)
421                    elements[i] = b;
422            }
423        }
424        capacity = newCapacity;
425        array = null;
426        displacement = 0;
427        isDisplaced = false;
428        return this;
429    }
430
431    @Override
432    public AbstractVector adjustArray(int newCapacity,
433                                       AbstractArray displacedTo,
434                                       int displacement)
435
436    {
437        capacity = newCapacity;
438        array = displacedTo;
439        this.displacement = displacement;
440        elements = null;
441        isDisplaced = true;
442        return this;
443    }
444}
Note: See TracBrowser for help on using the repository browser.