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