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