1 /*
2  * ComplexArray_UnsignedByte32.java
3  *
4  * Copyright (C) 2003-2005 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 public final class ComplexArray_UnsignedByte32 extends AbstractArray
39 {
40     private final int[] dimv;
41     private int totalSize;
42 
43     // For non-displaced arrays.
44     // FIXME We should really use an array of unboxed values!
45     private LispObject[] data;
46 
47     // For displaced arrays.
48     private AbstractArray array;
49     private int displacement;
50 
ComplexArray_UnsignedByte32(int[] dimv)51     public ComplexArray_UnsignedByte32(int[] dimv)
52     {
53         this.dimv = dimv;
54         totalSize = computeTotalSize(dimv);
55         data = new LispObject[totalSize];
56         for (int i = totalSize; i-- > 0;)
57             data[i] = NIL;
58     }
59 
ComplexArray_UnsignedByte32(int[] dimv, LispObject initialContents)60     public ComplexArray_UnsignedByte32(int[] dimv, LispObject initialContents)
61 
62     {
63         this.dimv = dimv;
64         final int rank = dimv.length;
65         LispObject rest = initialContents;
66         for (int i = 0; i < rank; i++) {
67             dimv[i] = rest.length();
68             rest = rest.elt(0);
69         }
70         totalSize = computeTotalSize(dimv);
71         data = new LispObject[totalSize];
72         setInitialContents(0, dimv, initialContents, 0);
73     }
74 
ComplexArray_UnsignedByte32(int[] dimv, AbstractArray array, int displacement)75     public ComplexArray_UnsignedByte32(int[] dimv, AbstractArray array,
76                                        int displacement)
77     {
78         this.dimv = dimv;
79         this.array = array;
80         this.displacement = displacement;
81         totalSize = computeTotalSize(dimv);
82     }
83 
setInitialContents(int axis, int[] dims, LispObject contents, int index)84     private int setInitialContents(int axis, int[] dims, LispObject contents,
85                                    int index)
86 
87     {
88         if (dims.length == 0) {
89             try {
90                 data[index] = contents;
91             }
92             catch (ArrayIndexOutOfBoundsException e) {
93                 error(new LispError("Bad initial contents for array."));
94                 return -1;
95             }
96             ++index;
97         } else {
98             int dim = dims[0];
99             if (dim != contents.length()) {
100                 error(new LispError("Bad initial contents for array."));
101                 return -1;
102             }
103             int[] newDims = new int[dims.length-1];
104             for (int i = 1; i < dims.length; i++)
105                 newDims[i-1] = dims[i];
106             if (contents.listp()) {
107                 for (int i = contents.length();i-- > 0;) {
108                     LispObject content = contents.car();
109                     index =
110                         setInitialContents(axis + 1, newDims, content, index);
111                     contents = contents.cdr();
112                 }
113             } else {
114                 AbstractVector v = checkVector(contents);
115                 final int length = v.length();
116                 for (int i = 0; i < length; i++) {
117                     LispObject content = v.AREF(i);
118                     index =
119                         setInitialContents(axis + 1, newDims, content, index);
120                 }
121             }
122         }
123         return index;
124     }
125 
126     @Override
typeOf()127     public LispObject typeOf()
128     {
129         return list(Symbol.ARRAY, UNSIGNED_BYTE_32, getDimensions());
130     }
131 
132     @Override
classOf()133     public LispObject classOf()
134     {
135         return BuiltInClass.ARRAY;
136     }
137 
138     @Override
getRank()139     public int getRank()
140     {
141         return dimv.length;
142     }
143 
144     @Override
getDimensions()145     public LispObject getDimensions()
146     {
147         LispObject result = NIL;
148         for (int i = dimv.length; i-- > 0;)
149             result = new Cons(Fixnum.getInstance(dimv[i]), result);
150         return result;
151     }
152 
153     @Override
getDimension(int n)154     public int getDimension(int n)
155     {
156         try {
157             return dimv[n];
158         }
159         catch (ArrayIndexOutOfBoundsException e) {
160             error(new TypeError("Bad array dimension " + n + "."));
161             return -1;
162         }
163     }
164 
165     @Override
getElementType()166     public LispObject getElementType()
167     {
168         return UNSIGNED_BYTE_32;
169     }
170 
171     @Override
getTotalSize()172     public int getTotalSize()
173     {
174         return totalSize;
175     }
176 
177     @Override
arrayDisplacement()178     public LispObject arrayDisplacement()
179     {
180         LispObject value1, value2;
181         if (array != null) {
182             value1 = array;
183             value2 = Fixnum.getInstance(displacement);
184         } else {
185             value1 = NIL;
186             value2 = Fixnum.ZERO;
187         }
188         return LispThread.currentThread().setValues(value1, value2);
189     }
190 
191     @Override
AREF(int index)192     public LispObject AREF(int index)
193     {
194         if (data != null) {
195             try {
196                 return data[index];
197             }
198             catch (ArrayIndexOutOfBoundsException e) {
199                 return error(new TypeError("Bad row major index " + index + "."));
200             }
201         } else
202             return array.AREF(index + displacement);
203     }
204 
205     @Override
aset(int index, LispObject newValue)206     public void aset(int index, LispObject newValue)
207     {
208         if (data != null) {
209             try {
210                 data[index] = newValue;
211             }
212             catch (ArrayIndexOutOfBoundsException e) {
213                 error(new TypeError("Bad row major index " + index + "."));
214             }
215         } else
216             array.aset(index + displacement, newValue);
217     }
218 
219     @Override
fill(LispObject obj)220     public void fill(LispObject obj)
221     {
222         if (!(obj instanceof LispInteger)) {
223             type_error(obj, Symbol.INTEGER);
224             // Not reached.
225             return;
226         }
227         if (obj.isLessThan(Fixnum.ZERO) || obj.isGreaterThan(UNSIGNED_BYTE_32_MAX_VALUE)) {
228             type_error(obj, UNSIGNED_BYTE_32);
229         }
230         if (data != null) {
231             for (int i = data.length; i-- > 0;)
232                 data[i] = obj;
233         } else {
234             for (int i = totalSize; i-- > 0;)
235                 aset(i, obj);
236         }
237     }
238 
239     @Override
printObject()240     public String printObject()
241     {
242         return printObject(dimv);
243     }
244 
245 
246     @Override
adjustArray(int[] dims, LispObject initialElement, LispObject initialContents)247     public AbstractArray adjustArray(int[] dims,
248                                               LispObject initialElement,
249                                               LispObject initialContents)
250             {
251         if (isAdjustable()) {
252             if (initialContents != null)
253                 setInitialContents(0, dims, initialContents, 0);
254             else {
255                 //### FIXME Take the easy way out: we don't want to reorganize
256                 // all of the array code yet
257                 SimpleArray_UnsignedByte32 tempArray = new SimpleArray_UnsignedByte32(dims);
258                 if (initialElement != null)
259                     tempArray.fill(initialElement);
260                 SimpleArray_UnsignedByte32.copyArray(this, tempArray);
261                 this.data = tempArray.data;
262 
263                 for (int i = 0; i < dims.length; i++)
264                     dimv[i] = dims[i];
265             }
266             return this;
267         } else {
268             if (initialContents != null)
269                 return new ComplexArray_UnsignedByte32(dims, initialContents);
270             else {
271                 ComplexArray_UnsignedByte32 newArray = new ComplexArray_UnsignedByte32(dims);
272                 if (initialElement != null)
273                     newArray.fill(initialElement);
274                 return newArray;
275             }
276         }
277     }
278 
279     @Override
adjustArray(int[] dims, AbstractArray displacedTo, int displacement)280     public AbstractArray adjustArray(int[] dims,
281                                               AbstractArray displacedTo,
282                                               int displacement)
283             {
284         if (isAdjustable()) {
285             for (int i = 0; i < dims.length; i++)
286                 dimv[i] = dims[i];
287 
288             this.data = null;
289             this.array = displacedTo;
290             this.displacement = displacement;
291             this.totalSize = computeTotalSize(dims);
292 
293             return this;
294         } else {
295             ComplexArray_UnsignedByte32 a = new ComplexArray_UnsignedByte32(dims, displacedTo, displacement);
296 
297             return a;
298         }
299     }
300 }
301