source: branches/0.19.x/abcl/src/org/armedbear/lisp/ComplexVector_UnsignedByte8.java

Last change on this file was 12288, checked in by vvoutilainen, 16 years ago

Don't extend Lisp in LispObject, static import Lisp wherever
necessary. Patch by Douglas R. Miles.

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