1 21 22 package org.armedbear.lisp; 23 24 public final class SimpleString extends AbstractString 25 { 26 private int capacity; 27 private char[] chars; 28 29 public SimpleString(LispCharacter c) 30 { 31 chars = new char[1]; 32 chars[0] = c.getValue(); 33 capacity = 1; 34 } 35 36 public SimpleString(char c) 37 { 38 chars = new char[1]; 39 chars[0] = c; 40 capacity = 1; 41 } 42 43 public SimpleString(int capacity) 44 { 45 this.capacity = capacity; 46 chars = new char[capacity]; 47 } 48 49 public SimpleString(String s) 50 { 51 capacity = s.length(); 52 chars = s.toCharArray(); 53 } 54 55 public SimpleString(StringBuffer sb) 56 { 57 chars = new char[capacity = sb.length()]; 58 sb.getChars(0, capacity, chars, 0); 59 } 60 61 private SimpleString(char[] chars) 62 { 63 this.chars = chars; 64 capacity = chars.length; 65 } 66 67 public char[] chars() 68 { 69 return chars; 70 } 71 72 public char[] getStringChars() 73 { 74 return chars; 75 } 76 77 public static SimpleString getInstance(String s) 79 { 80 return new SimpleString(s); 81 } 82 83 public LispObject typeOf() 84 { 85 return list2(Symbol.SIMPLE_STRING, new Fixnum(capacity)); 86 } 87 88 public LispClass classOf() 89 { 90 return BuiltInClass.SIMPLE_STRING; 91 } 92 93 public LispObject getDescription() 94 { 95 StringBuffer sb = new StringBuffer ("A simple-string ("); 96 sb.append(capacity); 97 sb.append(") \""); 98 sb.append(chars); 99 sb.append('"'); 100 return new SimpleString(sb); 101 } 102 103 public LispObject typep(LispObject type) throws ConditionThrowable 104 { 105 if (type == Symbol.SIMPLE_STRING) 106 return T; 107 if (type == Symbol.SIMPLE_BASE_STRING) 108 return T; 109 if (type == Symbol.SIMPLE_ARRAY) 110 return T; 111 if (type == BuiltInClass.SIMPLE_STRING) 112 return T; 113 if (type == BuiltInClass.SIMPLE_ARRAY) 114 return T; 115 return super.typep(type); 116 } 117 118 public LispObject SIMPLE_STRING_P() 119 { 120 return T; 121 } 122 123 public boolean hasFillPointer() 124 { 125 return false; 126 } 127 128 public boolean isAdjustable() 129 { 130 return false; 131 } 132 133 public boolean equal(LispObject obj) throws ConditionThrowable 134 { 135 if (this == obj) 136 return true; 137 if (obj instanceof SimpleString) { 138 SimpleString string = (SimpleString) obj; 139 if (string.capacity != capacity) 140 return false; 141 for (int i = capacity; i-- > 0;) 142 if (string.chars[i] != chars[i]) 143 return false; 144 return true; 145 } 146 if (obj instanceof AbstractString) { 147 AbstractString string = (AbstractString) obj; 148 if (string.length() != capacity) 149 return false; 150 for (int i = length(); i-- > 0;) 151 if (string.getChar(i) != chars[i]) 152 return false; 153 return true; 154 } 155 if (obj instanceof NilVector) 156 return obj.equal(this); 157 return false; 158 } 159 160 public boolean equalp(LispObject obj) throws ConditionThrowable 161 { 162 if (this == obj) 163 return true; 164 if (obj instanceof SimpleString) { 165 SimpleString string = (SimpleString) obj; 166 if (string.capacity != capacity) 167 return false; 168 for (int i = capacity; i-- > 0;) { 169 if (string.chars[i] != chars[i]) { 170 if (Utilities.toLowerCase(string.chars[i]) != Utilities.toLowerCase(chars[i])) 171 return false; 172 } 173 } 174 return true; 175 } 176 if (obj instanceof AbstractString) { 177 AbstractString string = (AbstractString) obj; 178 if (string.length() != capacity) 179 return false; 180 for (int i = length(); i-- > 0;) { 181 if (string.getChar(i) != chars[i]) { 182 if (Utilities.toLowerCase(string.getChar(i)) != Utilities.toLowerCase(chars[i])) 183 return false; 184 } 185 } 186 return true; 187 } 188 if (obj instanceof AbstractArray) 189 return obj.equalp(this); 190 return false; 191 } 192 193 public LispObject subseq(int start, int end) throws ConditionThrowable 194 { 195 SimpleString s = new SimpleString(end - start); 196 int i = start, j = 0; 197 try { 198 while (i < end) 199 s.chars[j++] = chars[i++]; 200 return s; 201 } 202 catch (ArrayIndexOutOfBoundsException e) { 203 return signal(new TypeError("Array index out of bounds: " + i)); 204 } 205 } 206 207 public void fill(LispObject obj) throws ConditionThrowable 208 { 209 fill(LispCharacter.getValue(obj)); 210 } 211 212 public void fill(char c) 213 { 214 for (int i = capacity; i-- > 0;) 215 chars[i] = c; 216 } 217 218 public void shrink(int n) throws ConditionThrowable 219 { 220 if (n < capacity) { 221 char[] newArray = new char[n]; 222 System.arraycopy(chars, 0, newArray, 0, n); 223 chars = newArray; 224 capacity = n; 225 return; 226 } 227 if (n == capacity) 228 return; 229 signal(new LispError()); 230 } 231 232 public LispObject reverse() throws ConditionThrowable 233 { 234 SimpleString result = new SimpleString(capacity); 235 int i, j; 236 for (i = 0, j = capacity - 1; i < capacity; i++, j--) 237 result.chars[i] = chars[j]; 238 return result; 239 } 240 241 public LispObject nreverse() throws ConditionThrowable 242 { 243 int i = 0; 244 int j = capacity - 1; 245 while (i < j) { 246 char temp = chars[i]; 247 chars[i] = chars[j]; 248 chars[j] = temp; 249 ++i; 250 --j; 251 } 252 return this; 253 } 254 255 public LispObject getRowMajor(int index) throws ConditionThrowable 256 { 257 try { 258 return LispCharacter.getInstance(chars[index]); 259 } 260 catch (ArrayIndexOutOfBoundsException e) { 261 badIndex(index, capacity); 262 return NIL; } 264 } 265 266 public void setRowMajor(int index, LispObject newValue) throws ConditionThrowable 267 { 268 try { 269 chars[index] = LispCharacter.getValue(newValue); 270 } 271 catch (ArrayIndexOutOfBoundsException e) { 272 badIndex(index, capacity); 273 } 274 } 275 276 public char getChar(int index) throws ConditionThrowable 277 { 278 try { 279 return chars[index]; 280 } 281 catch (ArrayIndexOutOfBoundsException e) { 282 badIndex(index, capacity); 283 return 0; } 285 } 286 287 public void setChar(int index, char c) throws ConditionThrowable 288 { 289 try { 290 chars[index] = c; 291 } 292 catch (ArrayIndexOutOfBoundsException e) { 293 badIndex(index, capacity); 294 } 295 } 296 297 public String getStringValue() 298 { 299 return new String (chars); 300 } 301 302 public Object javaInstance() 303 { 304 return new String (chars); 305 } 306 307 public Object javaInstance(Class c) 308 { 309 return javaInstance(); 310 } 311 312 public final int capacity() 313 { 314 return capacity; 315 } 316 317 public final int length() 318 { 319 return capacity; 320 } 321 322 public LispObject elt(int index) throws ConditionThrowable 323 { 324 try { 325 return LispCharacter.getInstance(chars[index]); 326 } 327 catch (ArrayIndexOutOfBoundsException e) { 328 badIndex(index, capacity); 329 return NIL; } 331 } 332 333 public LispObject AREF(LispObject index) throws ConditionThrowable 335 { 336 try { 337 return LispCharacter.getInstance(chars[((Fixnum)index).value]); 338 } 339 catch (ClassCastException e) { 340 return signal(new TypeError(index, Symbol.FIXNUM)); 341 } 342 catch (ArrayIndexOutOfBoundsException e) { 343 badIndex(((Fixnum)index).value, capacity); 344 return NIL; } 346 } 347 348 public int sxhash() 349 { 350 int hashCode = 0; 351 for (int i = 0; i < capacity; i++) 352 hashCode = hashCode * 31 + chars[i]; 353 return (hashCode & 0x7fffffff); 354 } 355 356 public int psxhash() 358 { 359 int hashCode = 0; 360 for (int i = 0; i < capacity; i++) 361 hashCode = hashCode * 31 + Character.toUpperCase(chars[i]); 362 return (hashCode & 0x7fffffff); 363 } 364 365 public AbstractVector adjustVector(int newCapacity, 366 LispObject initialElement, 367 LispObject initialContents) 368 throws ConditionThrowable 369 { 370 if (initialContents != NIL) { 371 char[] newChars = new char[newCapacity]; 372 if (initialContents.listp()) { 373 LispObject list = initialContents; 374 for (int i = 0; i < newCapacity; i++) { 375 newChars[i] = LispCharacter.getValue(list.car()); 376 list = list.cdr(); 377 } 378 } else if (initialContents.vectorp()) { 379 for (int i = 0; i < newCapacity; i++) 380 newChars[i] = LispCharacter.getValue(initialContents.elt(i)); 381 } else 382 signal(new TypeError(initialContents, Symbol.SEQUENCE)); 383 return new SimpleString(newChars); 384 } 385 if (capacity != newCapacity) { 386 char[] newChars = new char[newCapacity]; 387 System.arraycopy(chars, 0, newChars, 0, Math.min(newCapacity, capacity)); 388 if (initialElement != NIL && capacity < newCapacity) { 389 final char c = LispCharacter.getValue(initialElement); 390 for (int i = capacity; i < newCapacity; i++) 391 newChars[i] = c; 392 } 393 return new SimpleString(newChars); 394 } 395 return this; 397 } 398 399 public AbstractVector adjustVector(int newCapacity, 400 AbstractArray displacedTo, 401 int displacement) 402 throws ConditionThrowable 403 { 404 return new ComplexString(newCapacity, displacedTo, displacement); 405 } 406 407 private static final Primitive2 SCHAR = new Primitive2("schar", "string index") 409 { 410 public LispObject execute(LispObject first, LispObject second) 411 throws ConditionThrowable 412 { 413 try { 414 return LispCharacter.getInstance(((SimpleString)first).chars[((Fixnum)second).value]); 415 } 416 catch (ClassCastException e) { 417 if (first instanceof SimpleString) 418 return signal(new TypeError(second, Symbol.FIXNUM)); 419 else 420 return signal(new TypeError(first, Symbol.SIMPLE_STRING)); 421 } 422 catch (ArrayIndexOutOfBoundsException e) { 423 return signal(new TypeError("Array index out of bounds: " + 424 ((Fixnum)second).value)); 425 } 426 } 427 }; 428 429 private static final Primitive3 _SET_SCHAR = 431 new Primitive3("%set-schar", PACKAGE_SYS, false) 432 { 433 public LispObject execute(LispObject first, LispObject second, 434 LispObject third) 435 throws ConditionThrowable 436 { 437 try { 438 ((SimpleString)first).chars[((Fixnum)second).value] = 439 ((LispCharacter)third).value; 440 return third; 441 } 442 catch (ClassCastException e) { 443 if (!(first instanceof SimpleString)) 444 return signal(new TypeError(first, Symbol.SIMPLE_STRING)); 445 if (!(second instanceof Fixnum)) 446 return signal(new TypeError(second, Symbol.FIXNUM)); 447 return signal(new TypeError(third, Symbol.CHARACTER)); 448 } 449 catch (ArrayIndexOutOfBoundsException e) { 450 return signal(new TypeError("Array index out of bounds: " + 451 ((Fixnum)second).value)); 452 } 453 } 454 }; 455 } 456 | Popular Tags |