1 package org.python.core; 2 3 import java.io.Serializable ; 4 import java.lang.reflect.Array ; 5 import java.util.Arrays ; 6 7 39 public abstract class AbstractArray implements Serializable { 40 41 45 protected int capacity; 46 47 50 protected int size; 51 52 69 protected int modCountIncr; 70 71 90 public AbstractArray(AbstractArray toCopy) { 91 capacity = toCopy.capacity; 92 size = toCopy.size; 94 } 95 96 101 public AbstractArray(int size) { 102 this.size = size; 103 capacity = size; 104 } 105 106 111 public AbstractArray(Class type) { 112 this(type, 10); 113 } 114 115 128 public AbstractArray(Class type, int[] dimensions) { 129 Object array = Array.newInstance(type, dimensions); 130 capacity = dimensions[0]; 131 setArray(array); 132 } 133 134 140 public AbstractArray(Class type, int size) { 141 Object array = Array.newInstance(type, size); 142 capacity = Math.max(size, 10); 143 setArray(array); 144 } 145 146 154 public void appendArray(Object ofArrayType) { 155 replaceSubArray(ofArrayType, size); 156 } 157 158 168 public void clear() { 169 modCountIncr = 0; 170 if (size != 0) { 171 modCountIncr = 1; 172 clearRange(0, size); 173 setSize(0); 174 } 175 176 } 177 178 179 190 protected void clearRange(int start, int stop) { 191 192 if (start < stop && start >= 0 && stop <= size) { 193 clearRangeInternal(start, stop); 194 } else { 195 if (start == stop && start >= 0 && stop <= size) return; 196 197 throw new ArrayIndexOutOfBoundsException ("start and stop must follow: 0 <= start <= stop <= " + 198 (size) + ", but found start= " + start + " and stop=" + stop); 199 } 200 } 201 202 208 private void clearRangeInternal(int start, int stop) { 209 210 Object base = getArray(); 211 Class arrayType = base.getClass().getComponentType(); 212 if (arrayType.isPrimitive()) { 213 if (arrayType == Boolean.TYPE) { 214 Arrays.fill((boolean[]) base, start, stop, false); 215 } else if (arrayType == Character.TYPE) { 216 Arrays.fill((char[]) base, start, stop, '\u0000'); 217 } else if (arrayType == Byte.TYPE) { 218 Arrays.fill((byte[]) base, start, stop, (byte) 0); 219 } else if (arrayType == Short.TYPE) { 220 Arrays.fill((short[]) base, start, stop, (short) 0); 221 } else if (arrayType == Integer.TYPE) { 222 Arrays.fill((int[]) base, start, stop, 0); 223 } else if (arrayType == Long.TYPE) { 224 Arrays.fill((long[]) base, start, stop, 0); 225 } else if (arrayType == Float.TYPE) { 226 Arrays.fill((float[]) base, start, stop, 0.f); 227 } else if (arrayType == Double.TYPE) { 228 Arrays.fill((double[]) base, start, stop, 0.); 229 } 230 } else { 231 Arrays.fill((Object []) base, start, stop, null); 232 } 233 234 } 235 236 242 public Object copyArray() { 243 Object copy = Array.newInstance(getArray().getClass().getComponentType(), size); 244 System.arraycopy(getArray(), 0, copy, 0, size); 245 return copy; 246 } 247 248 256 protected void ensureCapacity(int minCapacity) { 257 modCountIncr = 0; 261 if (minCapacity > capacity) { 262 modCountIncr = 1; 263 int newCapacity = (capacity * 2) + 1; 264 newCapacity = (newCapacity < minCapacity) 265 ? minCapacity 266 : newCapacity; 267 setNewBase(newCapacity); 268 capacity = newCapacity; 269 } 270 } 271 272 282 protected int getAddIndex() { 283 int index = size++; 284 if (size > capacity) { 285 ensureCapacity(size); 286 } 287 return index; 288 } 289 290 297 protected abstract Object getArray(); 298 299 protected boolean isEmpty() { 300 return size == 0; 301 } 302 303 311 protected void makeInsertSpace(int index) { 312 makeInsertSpace(index, 1); 313 } 314 315 protected void makeInsertSpace(int index, int length) { 316 317 modCountIncr = 0; 318 if (index >= 0 && index <= size) { 319 int toCopy = size - index; 320 size = size + length; 321 if (size > capacity) { 323 ensureCapacity(size); 324 } 325 if (index < size - 1) { 326 modCountIncr = 1; 327 Object array = getArray(); 328 System.arraycopy(array, index, array, index + length, toCopy); 329 } 330 } else { 331 throw new ArrayIndexOutOfBoundsException ("Index must be between 0 and " + 332 size + ", but was " + index); 333 } 334 } 335 336 345 public void remove(int index) { 346 if (index >= 0 && index < size) { 347 size = size - 1; 348 if (index < size) { 349 Object base = getArray(); 350 System.arraycopy(base, index + 1, base, index, size - index); 351 clearRangeInternal(size, size); 352 } 353 354 } else { 355 if (size == 0) { 356 throw new IllegalStateException ("Cannot remove data from an empty array"); 357 } 358 throw new IndexOutOfBoundsException ("Index must be between 0 and " + 359 (size - 1) + ", but was " + index); 360 361 } 362 } 363 364 369 public void remove(int start, int stop) { 370 if (start >= 0 && stop <= size && start <= stop) { 371 Object base = getArray(); 372 int nRemove = stop - start; 373 if (nRemove == 0) return; 374 System.arraycopy(base, stop, base, start, size - stop); 375 size = size - nRemove; 376 clearRangeInternal(size, size + nRemove - 1); 377 setArray(base); 378 return; 379 } 380 381 throw new IndexOutOfBoundsException ("start and stop must follow: 0 <= start <= stop <= " + 382 (size - 1) + ", but found start= " + start + " and stop=" + stop); 383 } 384 385 395 public void replaceSubArray(Object array, int atIndex) { 396 int arrayLen = Array.getLength(array); 397 replaceSubArray(atIndex, Math.min(size, atIndex + arrayLen), array, 0, arrayLen); 398 } 399 400 410 public void replaceSubArray(int thisStart, int thisStop, Object srcArray, 411 int srcStart, int srcStop) { 412 413 modCountIncr = 0; 414 if (!srcArray.getClass().isArray()) { 415 throw new IllegalArgumentException ("'array' must be an array type"); 416 } 417 418 int replacedLen = thisStop - thisStart; 419 if (thisStart < 0 || replacedLen < 0 || thisStop > size) { 420 String message = null; 421 if (thisStart < 0) { 422 message = "thisStart < 0 (thisStart = " + thisStart + ")"; 423 } else if (replacedLen < 0) { 424 message = "thisStart > thistStop (thisStart = " + thisStart + 425 ", thisStop = " + thisStop + ")"; 426 } else if (thisStop > size) { 427 message = "thisStop > size (thisStop = " + thisStop + 428 ", size = " + size + ")"; 429 } else { 430 throw new InternalError ("Incorrect validation logic"); 431 } 432 433 throw new ArrayIndexOutOfBoundsException (message); 434 } 435 436 int srcLen = Array.getLength(srcArray); 437 int replacementLen = srcStop - srcStart; 438 if (srcStart < 0 || replacementLen < 0 || srcStop > srcLen) { 439 String message = null; 440 if (srcStart < 0) { 441 message = "srcStart < 0 (srcStart = " + srcStart +")"; 442 } else if (replacementLen < 0) { 443 message = "srcStart > srcStop (srcStart = " + srcStart + 444 ", srcStop = " + srcStop + ")"; 445 } else if (srcStop > srcLen) { 446 message = "srcStop > srcArray length (srcStop = " + srcStop + 447 ", srcArray length = " +srcLen + ")"; 448 } else { 449 throw new InternalError ("Incorrect validation logic"); 450 } 451 452 throw new IllegalArgumentException ("start, stop and array must follow:\n\t" 453 + "0 <= start <= stop <= array length\nBut found\n\t" + 454 message); 455 } 456 457 int lengthChange = replacementLen - replacedLen; 458 459 if (lengthChange < 0) { 461 remove(thisStop + lengthChange, thisStop); 462 } else if (lengthChange > 0) { 463 makeInsertSpace(thisStop, lengthChange); 464 } 465 466 try { 467 modCountIncr = 1; 468 System.arraycopy(srcArray, srcStart, getArray(), thisStart, replacementLen); 469 } catch (ArrayStoreException e) { 470 throw new IllegalArgumentException ("'ofArrayType' must be compatible with existing array type of " + 471 getArray().getClass().getName() + "\tsee java.lang.Class.getName()."); 472 } 473 } 474 475 482 protected abstract void setArray(Object array); 483 484 490 private void setNewBase(int newCapacity) { 491 modCountIncr = 1; 492 Object base = getArray(); 493 Class baseType = base.getClass().getComponentType(); 494 Object newBase = Array.newInstance(baseType, newCapacity); 495 System.arraycopy(base, 0, newBase, 0, capacity); 496 setArray(newBase); 497 } 498 499 509 public void setSize(int count) { 510 if (count > capacity) { 511 ensureCapacity(count); 512 } else if (count < size) { 513 clearRange(count, size); 514 } 515 size = count; 516 } 517 518 523 public int getSize() { 524 return size; 525 } 526 527 532 public String toString() { 533 StringBuffer buf = new StringBuffer (); 534 buf.append("["); 535 536 Object base = getArray(); 537 Class arrayType = base.getClass().getComponentType(); 538 int n = size - 1; 539 if (arrayType.isPrimitive()) { 540 for (int i = 0; i < n; i++) { 541 buf.append(Array.get(base, i)).append(", "); 542 } 543 if (n >= 0) buf.append(Array.get(base, n)); 544 } else { 545 Object [] objects = (Object []) base; 546 for (int i = 0; i < n; i++) { 547 buf.append(objects[i]).append(", "); 548 } 549 if (n >= 0) buf.append(objects[n]); 550 } 551 buf.append("]"); 552 return buf.toString(); 553 } 554 555 556 560 protected void trimToSize() { 561 if (size < capacity) { 565 setNewBase(size); 566 } 567 } 568 569 570 580 public int getModCountIncr() { 581 return modCountIncr; 582 } 583 } 584 | Popular Tags |