1 /*
2  * BasicVector_UnsignedByte8.java
3  *
4  * Copyright (C) 2002-2006 Peter Graves
5  * $Id$
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 
34 package org.armedbear.lisp;
35 
36 import static org.armedbear.lisp.Lisp.*;
37 
38 // A basic vector is a specialized vector that is not displaced to another
39 // array, has no fill pointer, and is not expressly adjustable.
40 public final class BasicVector_UnsignedByte8 extends AbstractVector
41 {
42   private int capacity;
43   private byte[] elements;
44 
BasicVector_UnsignedByte8(int capacity)45   public BasicVector_UnsignedByte8(int capacity)
46   {
47     elements = new byte[capacity];
48     this.capacity = capacity;
49   }
50 
BasicVector_UnsignedByte8(byte[] array)51   public BasicVector_UnsignedByte8(byte[] array)
52   {
53     capacity = array.length;
54     elements = new byte[capacity];
55     System.arraycopy(array, 0, elements, 0, capacity);
56   }
57 
58 
BasicVector_UnsignedByte8(LispObject[] array)59   public BasicVector_UnsignedByte8(LispObject[] array)
60   {
61     capacity = array.length;
62     elements = new byte[capacity];
63     for (int i = array.length; i-- > 0;)
64       elements[i] = coerceToJavaByte(array[i]);
65   }
66 
67   @Override
typeOf()68   public LispObject typeOf()
69   {
70     return list(Symbol.SIMPLE_ARRAY, UNSIGNED_BYTE_8, new Cons(Fixnum.getInstance(capacity)));
71   }
72 
73   @Override
classOf()74   public LispObject classOf()
75   {
76     return BuiltInClass.VECTOR;
77   }
78 
79   @Override
typep(LispObject type)80   public LispObject typep(LispObject type)
81   {
82     if (type == Symbol.SIMPLE_ARRAY)
83       return T;
84     if (type == BuiltInClass.SIMPLE_ARRAY)
85       return T;
86     return super.typep(type);
87   }
88 
89   @Override
getElementType()90   public LispObject getElementType()
91   {
92     return UNSIGNED_BYTE_8;
93   }
94 
95   @Override
isSimpleVector()96   public boolean isSimpleVector()
97   {
98     return false;
99   }
100 
101   @Override
hasFillPointer()102   public boolean hasFillPointer()
103   {
104     return false;
105   }
106 
107   @Override
isAdjustable()108   public boolean isAdjustable()
109   {
110     return false;
111   }
112 
113   @Override
capacity()114   public int capacity()
115   {
116     return capacity;
117   }
118 
119   @Override
length()120   public int length()
121   {
122     return capacity;
123   }
124 
125   @Override
elt(int index)126   public LispObject elt(int index)
127   {
128     try
129       {
130         return coerceFromJavaByte(elements[index]);
131       }
132     catch (ArrayIndexOutOfBoundsException e)
133       {
134         badIndex(index, capacity);
135         return NIL; // Not reached.
136       }
137   }
138 
139   @Override
aref(int index)140   public int aref(int index)
141   {
142     try
143       {
144         return (((int)elements[index]) & 0xff);
145       }
146     catch (ArrayIndexOutOfBoundsException e)
147       {
148         badIndex(index, elements.length);
149         // Not reached.
150         return 0;
151       }
152   }
153 
154   @Override
AREF(int index)155   public LispObject AREF(int index)
156   {
157     try
158       {
159         return coerceFromJavaByte(elements[index]);
160       }
161     catch (ArrayIndexOutOfBoundsException e)
162       {
163         badIndex(index, elements.length);
164         return NIL; // Not reached.
165       }
166   }
167 
168   @Override
aset(int index, int n)169   public void aset(int index, int n)
170   {
171     try
172       {
173         elements[index] = (byte) n;
174       }
175     catch (ArrayIndexOutOfBoundsException e)
176       {
177         badIndex(index, capacity);
178       }
179   }
180 
181   @Override
aset(int index, LispObject value)182   public void aset(int index, LispObject value)
183   {
184     try
185       {
186         elements[index] = coerceToJavaByte(value);
187       }
188     catch (ArrayIndexOutOfBoundsException e)
189       {
190         badIndex(index, capacity);
191       }
192   }
193 
194   @Override
subseq(int start, int end)195   public LispObject subseq(int start, int end)
196   {
197     BasicVector_UnsignedByte8 v = new BasicVector_UnsignedByte8(end - start);
198     int i = start, j = 0;
199     try
200       {
201         while (i < end)
202           v.elements[j++] = elements[i++];
203         return v;
204       }
205     catch (ArrayIndexOutOfBoundsException e)
206       {
207         return error(new TypeError("Array index out of bounds: " + i + "."));
208       }
209   }
210 
211   @Override
fill(LispObject obj)212   public void fill(LispObject obj)
213   {
214     if (!(obj instanceof Fixnum)) {
215       type_error(obj, Symbol.FIXNUM);
216       // Not reached.
217       return;
218     }
219     int n = ((Fixnum) obj).value;
220     if (n < 0 || n > 255) {
221       type_error(obj, UNSIGNED_BYTE_8);
222       // Not reached.
223       return;
224     }
225     for (int i = capacity; i-- > 0;)
226       elements[i] = (byte) n;
227   }
228 
229   @Override
shrink(int n)230   public void shrink(int n)
231   {
232     if (n < capacity)
233       {
234         byte[] newArray = new byte[n];
235         System.arraycopy(elements, 0, newArray, 0, n);
236         elements = newArray;
237         capacity = n;
238         return;
239       }
240     if (n == capacity)
241       return;
242     error(new LispError());
243   }
244 
245   @Override
reverse()246   public LispObject reverse()
247   {
248     BasicVector_UnsignedByte8 result = new BasicVector_UnsignedByte8(capacity);
249     int i, j;
250     for (i = 0, j = capacity - 1; i < capacity; i++, j--)
251       result.elements[i] = elements[j];
252     return result;
253   }
254 
255   @Override
nreverse()256   public LispObject nreverse()
257   {
258     int i = 0;
259     int j = capacity - 1;
260     while (i < j)
261       {
262         byte temp = elements[i];
263         elements[i] = elements[j];
264         elements[j] = temp;
265         ++i;
266         --j;
267       }
268     return this;
269   }
270 
271   @Override
adjustArray(int newCapacity, LispObject initialElement, LispObject initialContents)272   public AbstractVector adjustArray(int newCapacity,
273                                      LispObject initialElement,
274                                      LispObject initialContents)
275 
276   {
277     if (initialContents != null)
278       {
279         LispObject[] newElements = new LispObject[newCapacity];
280         if (initialContents.listp())
281           {
282             LispObject list = initialContents;
283             for (int i = 0; i < newCapacity; i++)
284               {
285                 newElements[i] = list.car();
286                 list = list.cdr();
287               }
288           }
289         else if (initialContents.vectorp())
290           {
291             for (int i = 0; i < newCapacity; i++)
292               newElements[i] = initialContents.elt(i);
293           }
294         else
295           type_error(initialContents, Symbol.SEQUENCE);
296         return new BasicVector_UnsignedByte8(newElements);
297       }
298     if (capacity != newCapacity)
299       {
300         byte[] newElements = new byte[newCapacity];
301         System.arraycopy(elements, 0, newElements, 0,
302                          Math.min(capacity, newCapacity));
303         if (initialElement != null) {
304             byte initValue = (byte)(initialElement.intValue() & 0xFF);
305             for (int i = capacity; i < newCapacity; i++)
306                 newElements[i] = initValue;
307         }
308         return new BasicVector_UnsignedByte8(newElements);
309       }
310     // No change.
311     return this;
312   }
313 
314   @Override
adjustArray(int newCapacity, AbstractArray displacedTo, int displacement)315   public AbstractVector adjustArray(int newCapacity,
316                                      AbstractArray displacedTo,
317                                      int displacement)
318   {
319     return new ComplexVector(newCapacity, displacedTo, displacement);
320   }
321 }
322