001 /* 002 * Copyright (c) 2003, The Regents of the University of California, through 003 * Lawrence Berkeley National Laboratory (subject to receipt of any required 004 * approvals from the U.S. Dept. of Energy). All rights reserved. 005 */ 006 package gov.lbl.dsd.sea.nio.util; 007 008 import java.nio.ByteBuffer; 009 import java.nio.charset.Charset; 010 011 /** 012 Highly efficient resizable list holding <code>byte</code> elements; 013 implemented with arrays; Convenient to assemble variable-sized byte messages 014 if message lengths are a priori unknown. 015 <p> 016 Manipulating primitive values other than bytes and ints is not directly 017 supported. However, this can be done along the following lines: 018 <pre> 019 020 // append double at end 021 list = ... 022 double elemToAdd = 1234.0; 023 int s = list.size(); 024 list.setSize(s + 8); 025 list.asByteBuffer().putDouble(s, elemToAdd); 026 027 // or insertion at beginning can be done this way 028 list = ... 029 double elemToInsert = 1234.0; 030 list.replace(0, 0, 0, 8); // insert 8 bytes at beginning 031 list.asByteBuffer().putDouble(0, elemToInsert); 032 033 </pre> 034 035 @author whoschek@lbl.gov 036 @author $Author: hoschek3 $ 037 @version $Revision: 1.34 $, $Date: 2004/06/17 18:34:39 $ 038 */ 039 public class ByteArrayList implements java.io.Serializable { 040 041 /** 042 * The array into which the elements of the list are stored. The 043 * capacity of the list is the length of this array. 044 */ 045 protected byte[] elements; 046 047 /** 048 * The current number of elements contained in this list. 049 */ 050 protected int size; 051 052 /** 053 * Constructs an empty list. 054 */ 055 public ByteArrayList() { 056 this(64); 057 } 058 059 /** 060 * Constructs an empty list with the specified initial capacity. 061 * 062 * @param initialCapacity 063 * the number of elements the receiver can hold without 064 * auto-expanding itself by allocating new internal memory. 065 */ 066 public ByteArrayList(int initialCapacity) { 067 this(new byte[initialCapacity]); 068 size = 0; 069 } 070 071 /** 072 * Constructs a list SHARING the specified elements. The initial size and 073 * capacity of the list is the length of the array. 074 * 075 * <b>WARNING: </b> For efficiency reasons and to keep memory usage low, 076 * <b>the array is not copied </b>. So if subsequently you modify the 077 * specified array directly via the [] operator, be sure you know what 078 * you're doing. 079 * 080 * @param elems 081 * the array to be backed by the the constructed list 082 */ 083 public ByteArrayList(byte[] elems) { 084 elements = elems; 085 size = elems.length; 086 } 087 088 /** 089 * Constructs a list containing a copy of the remaining buffer elements. The 090 * initial size and capacity of the list is 091 * <code>elements.remaining()</code>. 092 * 093 * @param elems 094 * the elements initially to be added to the list 095 * 096 */ 097 public ByteArrayList(ByteBuffer elems) { 098 this(elems.remaining()); 099 add(elems); 100 } 101 102 /** 103 * Constructs a list containing the encoded representation of the given 104 * string. 105 * 106 * @param str 107 * the string to convert. 108 * @param charset 109 * the requested charset to convert with (e.g. 110 * Charset.forName("US-ASCII"), Charset.forName("UTF-8")) 111 */ 112 public ByteArrayList(String str, Charset charset) { 113 this(BufferUtil.toByteBuffer(str, charset)); 114 } 115 116 // /** 117 // * Constructs a list SHARING elements with the given buffer's contents. The 118 // * initial size and capacity of the list is newSize and buffer.capacity(), 119 // * respectively. 120 // * 121 // * <b>WARNING: </b> For efficiency reasons and to keep memory usage low, 122 // * <b>the buffer is not copied </b>. So if subsequently you modify the 123 // * specified buffer directly, be sure you know what you're doing. 124 // * 125 // * @param buffer 126 // * the buffer to use 127 // * @param newSize 128 // * the desired list size 129 // */ 130 // public ByteArrayList(ByteBuffer buffer, int newSize) { 131 // if (! buffer.hasArray() || buffer.arrayOffset() != 0) { 132 // throw new IllegalArgumentException(); 133 // } 134 // this.elements = buffer.array(); 135 // if (newSize < 0 || newSize > elements.length) throw new IllegalArgumentException(); 136 // this.size = newSize; 137 // } 138 // 139 /** 140 * Appends the specified element to the end of this list. 141 * 142 * @param elem 143 * element to be appended to this list. 144 */ 145 public void add(byte elem) { 146 if (size == elements.length) ensureCapacity(size + 1); 147 elements[size++] = elem; 148 } 149 150 /** 151 * Appends the specified elements to the end of this list. 152 * 153 * @param elems 154 * elements to be appended. 155 */ 156 public void add(byte[] elems) { 157 insert(size, elems); 158 } 159 160 /** 161 * Appends the specified elements to the end of this list. 162 * 163 * @param elems 164 * elements to be appended. 165 */ 166 public void add(ByteArrayList elems) { 167 insert(size, elems); 168 } 169 170 /** 171 * Appends the remaining buffer elements to the end of this list. 172 * 173 * @param elems 174 * elements to be appended. 175 */ 176 public void add(ByteBuffer elems) { 177 insert(size, elems); 178 } 179 180 /** 181 * Appends the encoded representation of the given string. 182 * 183 * @param str 184 * the string to convert. 185 * @param charset 186 * the requested charset to convert with (e.g. 187 * Charset.forName("US-ASCII"), Charset.forName("UTF-8")) 188 */ 189 public void add(String str, Charset charset) { 190 add(BufferUtil.toByteBuffer(str, charset)); 191 } 192 193 /** 194 * Returns the elements currently stored, including invalid elements between 195 * size and capacity, if any. 196 * <p> 197 * <b>WARNING: </b> For efficiency reasons and to keep memory usage low, 198 * <b>the array is not copied </b>. So if subsequently you modify the 199 * returned array directly via the [] operator, be sure you know what you're 200 * doing. 201 * 202 * @return the elements currently stored. 203 */ 204 public byte[] asArray() { 205 return elements; 206 } 207 208 /** 209 * Returns a byte buffer SHARING elements with the receiver; the buffer will 210 * have the default NIO byte order, which is ByteOrder.BIG_ENDIAN. 211 * <p> 212 * <b>WARNING: </b> For efficiency reasons and to keep memory usage low, 213 * <b>the array is not copied </b>. So if subsequently you modify the 214 * returned bytebuffer, be sure you know what you're doing. 215 */ 216 public ByteBuffer asByteBuffer() { 217 return ByteBuffer.wrap(elements, 0, size); 218 } 219 220 /** 221 * Removes all elements from the receiver. The receiver will be empty after 222 * this call returns, but keep its current capacity. 223 */ 224 public void clear() { 225 size = 0; 226 } 227 228 /** 229 * Returns a deep copy of the receiver. 230 * 231 * @return a deep copy of the receiver. 232 */ 233 public ByteArrayList copy() { 234 return new ByteArrayList(toArray()); 235 } 236 237 /** 238 * Compares the specified Object with the receiver. Returns true if and only 239 * if the specified Object is also an ArrayList of the same type, both Lists 240 * have the same size, and all corresponding pairs of elements in the two 241 * Lists are identical. In other words, two Lists are defined to be equal if 242 * they contain the same elements in the same order. 243 * 244 * @param otherObj 245 * the Object to be compared for equality with the receiver. 246 * @return true if the specified Object is equal to the receiver. 247 */ 248 public boolean equals(Object otherObj) { //delta 249 // overridden for performance only. 250 if (!(otherObj instanceof ByteArrayList)) 251 return super.equals(otherObj); 252 if (this == otherObj) return true; 253 if (otherObj == null) return false; 254 ByteArrayList other = (ByteArrayList) otherObj; 255 if (size != other.size) return false; 256 257 byte[] theElements = asArray(); 258 byte[] otherElements = other.asArray(); 259 for (int i = size; --i >= 0;) { 260 if (theElements[i] != otherElements[i]) return false; 261 } 262 return true; 263 } 264 265 /** 266 * Ensures that the receiver can hold at least the specified number of 267 * elements without needing to allocate new internal memory. If necessary, 268 * allocates new internal memory and increases the capacity of the receiver. 269 * 270 * @param minCapacity 271 * the desired minimum capacity. 272 */ 273 public void ensureCapacity(int minCapacity) { 274 int oldCapacity = elements.length; 275 if (minCapacity > oldCapacity) { 276 int newCapacity = (oldCapacity * 3) / 2 + 1; 277 if (newCapacity < minCapacity) { 278 newCapacity = minCapacity; 279 } 280 281 byte[] newArray = new byte[newCapacity]; 282 System.arraycopy(elements, 0, newArray, 0, size); 283 elements = newArray; 284 } 285 } 286 287 /** 288 * Returns the element at the specified position in the receiver. 289 * 290 * @param index 291 * index of element to return. 292 * @throws IndexOutOfBoundsException if index is out of range. 293 */ 294 public final byte get(int index) { 295 checkIndex(index); 296 return elements[index]; 297 } 298 299 /** 300 * Returns the 4 byte integer at the specified position in the receiver; 301 * using the NIO default byte order, which is ByteOrder.BIG_ENDIAN. 302 * 303 * @param index 304 * index of first byte of the integer. 305 * @throws IndexOutOfBoundsException if index is out of range. 306 */ 307 public int getInt(int index) { 308 checkIndex(index); 309 checkIndex(index + 4 - 1); 310 return asByteBuffer().getInt(index); 311 //return ByteConverter.readInt(elements, index); 312 } 313 314 /** 315 * Returns a decoded string representation of the receiver's bytes in the 316 * given range. 317 * 318 * @param from 319 * the index of the first element (inclusive). 320 * @param to 321 * the index of the last element (exclusive). 322 * @param charset 323 * the requested charset to convert with (e.g. 324 * Charset.forName("US-ASCII"), Charset.forName("UTF-8")) 325 * @throws IndexOutOfBoundsException 326 * if indexes are out of range 327 */ 328 public String getString(int from, int to, Charset charset) { 329 checkFromTo(from, to); 330 return BufferUtil.toString(this.elements, from, to-from, charset); 331 } 332 333 /** 334 * Returns the index of the first occurrence of the specified element. 335 * Returns <code>-1</code> if the receiver does not contain this element. 336 * Searches between <code>from</code>, inclusive and <code>to</code>, 337 * exclusive. Tests for identity. 338 * 339 * @param elem 340 * element to search for. 341 * @param from 342 * the leftmost search position, inclusive. 343 * @param to 344 * the rightmost search position, exclusive. 345 * @return the index of the first occurrence of the element in the receiver; 346 * returns <code>-1</code> if the element is not found. 347 * @throws IndexOutOfBoundsException if indexes are out of range 348 */ 349 public int indexOf(byte elem, int from, int to) { 350 checkFromTo(from, to); 351 352 byte[] theElements = elements; 353 for (int i = from; i < to; i++) { 354 if (elem == theElements[i]) { return i; } //found 355 } 356 return -1; //not found 357 } 358 359 // /** 360 // * Returns the index of the first occurrence of the specified element. 361 // * Returns <code>-1</code> if the receiver does not contain this element. 362 // * 363 // * @param elem 364 // * the element to be searched for. 365 // * @return the index of the first occurrence of the element in the receiver; 366 // * returns <code>-1</code> if the element is not found. 367 // */ 368 // public int indexOf(byte elem) { //delta 369 // return indexOf(elem, 0, size); 370 // } 371 // 372 /** 373 * Inserts the specified element before the specified position into the 374 * receiver. Shifts the element currently at that position (if any) and any 375 * subsequent elements to the right. 376 * 377 * @param index 378 * index before which the specified element is to be inserted 379 * @param elem 380 * element to insert. 381 */ 382 public void insert(int index, byte elem) { 383 replace(index, 0, elem, 1); 384 } 385 386 /** 387 * Inserts the specified elements before the specified position into the 388 * receiver. Shifts the element currently at that position (if any) and any 389 * subsequent elements to the right. 390 * 391 * @param index 392 * index before which the specified elements are to be inserted 393 * @param elems 394 * elements to insert. 395 */ 396 public void insert(int index, byte[] elems) { 397 replace(index, 0, elems); 398 } 399 400 /** 401 * Inserts the specified elements before the specified position into the 402 * receiver. Shifts the element currently at that position (if any) and any 403 * subsequent elements to the right. 404 * 405 * @param index 406 * index before which the specified elements are to be inserted 407 * @param elems 408 * elements to insert. 409 */ 410 public void insert(int index, ByteArrayList elems) { 411 replace(index, 0, elems); 412 } 413 414 /** 415 * Inserts the remaining buffer elements before the specified position into 416 * the receiver. Shifts the element currently at that position (if any) and 417 * any subsequent elements to the right. 418 * 419 * @param index 420 * index before which the specified elements are to be inserted 421 * @param elems 422 * elements to insert. 423 */ 424 public void insert(int index, ByteBuffer elems) { 425 replace(index, 0, elems); 426 } 427 428 // /** 429 // * Returns the index of the last occurrence of the specified element. 430 // * Returns <code>-1</code> if the receiver does not contain this element. 431 // * 432 // * @param elem 433 // * the element to be searched for. 434 // * @return the index of the last occurrence of the element in the receiver; 435 // * returns <code>-1</code> if the element is not found. 436 // */ 437 // public int lastIndexOf(byte elem) { 438 // return lastIndexOf(elem, 0, size); 439 // } 440 441 /** 442 * Returns the index of the last occurrence of the specified element. 443 * Returns <code>-1</code> if the receiver does not contain this element. 444 * Searches beginning at <code>to</code>, inclusive until 445 * <code>from</code>, exclusive. Tests for identity. 446 * 447 * @param elem 448 * element to search for. 449 * @param from 450 * the leftmost search position, inclusive. 451 * @param to 452 * the rightmost search position, exclusive. 453 * @return the index of the last occurrence of the element in the receiver; 454 * returns <code>-1</code> if the element is not found. 455 * @throws IndexOutOfBoundsException if indexes are out of range. 456 */ 457 public int lastIndexOf(byte elem, int from, int to) { 458 checkFromTo(from, to); 459 460 for (int i = to-1; i >= from; i--) { 461 if (elem == elements[i]) return i; //found 462 } 463 return -1; //not found 464 } 465 466 /** 467 * Removes the element at the specified position from the receiver. Shifts 468 * any subsequent elements to the left. 469 * 470 * @param index 471 * the index of the element to removed. 472 * @throws IndexOutOfBoundsException if index is out of range 473 */ 474 public void remove(int index) { 475 remove(index, index+1); 476 } 477 478 /** 479 * Removes the elements in the given range from the receiver. Shifts 480 * any subsequent elements to the left. 481 * 482 * @param from 483 * the index of the first element to removed (inclusive). 484 * @param to 485 * the index of the last element to removed (exclusive). 486 * @throws IndexOutOfBoundsException if indexes are out of range 487 */ 488 public void remove(int from, int to) { 489 checkFromTo(from, to); 490 if (from != to) { 491 System.arraycopy(elements, to, elements, from, size - to); 492 size -= to - from; 493 } 494 } 495 496 /** 497 * Removes from the receiver all elements that are contained in the 498 * specified list. Tests for identity. 499 * 500 * @param other 501 * the other list. 502 * @return <code>true</code> if the receiver changed as a result of the 503 * call. 504 */ 505 public boolean removeAll(ByteArrayList other) { 506 if (other.size() == 0) return false; //nothing to do 507 int limit = other.size() - 1; 508 int j = 0; 509 510 for (int i = 0; i < size; i++) { 511 if (other.indexOf(elements[i], 0, limit) < 0) 512 elements[j++] = elements[i]; 513 } 514 515 boolean modified = (j != size); 516 size = j; 517 return modified; 518 } 519 520 /** 521 * The powerful work horse for all add/insert/replace operations. 522 * One powerful efficient method does it all :-) 523 */ 524 private final void shrinkOrExpand(int from, int length, int replacementSize) { 525 checkLength(from, length); 526 int diff = replacementSize - length; 527 if (diff < 0) { 528 remove(from, from - diff); 529 } 530 else if (diff > 0) { 531 ensureCapacity(this.size + diff); 532 System.arraycopy(this.elements, from + length, this.elements, from + length + diff, size - (from + length)); 533 this.size += diff; 534 } 535 } 536 537 /** 538 * Replaces all elements[from..from+length-1] with the given replacement. 539 * The replacement can have any length. 540 * Examples: 541 * <p> 542 * <code>[a,b,c,d,e].replace(1,3, [x,y]) --> [a,x,y,e]</code> 543 * <p> 544 * <code>[a,b].replace(1,0, [w,x,y,z]) --> [a,w,x,y,z,b]</code> 545 * 546 * @param from the index of the first element to replace (inclusive) 547 * @param length the number of elements to replace 548 * @param replacement the elements to replace the replaced elements 549 */ 550 public void replace(int from, int length, byte[] replacement) { 551 shrinkOrExpand(from, length, replacement.length); 552 System.arraycopy(replacement, 0, this.elements, from, replacement.length); 553 } 554 555 /** 556 * Replaces all elements[from..from+length-1] with the given replacement. 557 * The replacement can have any length. 558 * Examples: 559 * <p> 560 * <code>[a,b,c,d,e].replace(1,3, [x,y]) --> [a,x,y,e]</code> 561 * <p> 562 * <code>[a,b].replace(1,0, [w,x,y,z]) --> [a,w,x,y,z,b]</code> 563 * 564 * @param from the index of the first element to replace (inclusive) 565 * @param length the number of elements to replace 566 * @param replacement the elements to replace the replaced elements 567 */ 568 public void replace(int from, int length, ByteArrayList replacement) { 569 shrinkOrExpand(from, length, replacement.size); 570 System.arraycopy(replacement.elements, 0, this.elements, from, replacement.size); 571 } 572 573 /** 574 * Replaces all elements[from..from+length-1] with the given replacement. 575 * The replacement can have any length. 576 * Examples: 577 * <p> 578 * <code>[a,b,c,d,e].replace(1,3, [x,y]) --> [a,x,y,e]</code> 579 * <p> 580 * <code>[a,b].replace(1,0, [w,x,y,z]) --> [a,w,x,y,z,b]</code> 581 * 582 * @param from the index of the first element to replace (inclusive) 583 * @param length the number of elements to replace 584 * @param replacement the elements to replace the replaced elements 585 */ 586 public void replace(int from, int length, ByteBuffer replacement) { 587 shrinkOrExpand(from, length, replacement.remaining()); 588 replacement.get(this.elements, from, replacement.remaining()); 589 } 590 591 /** 592 * Replaces all elements[from..from+length-1] with the given replacement. 593 * The replacement can have any length. 594 * Example: <code>[a,b,c,d,e].replace(1,3,x,4) --> [a,x,x,x,x,e]</code> 595 * 596 * @param from the index of the first element to replace (inclusive) 597 * @param length the number of elements to replace 598 * @param replacement the elements to replace the replaced elements 599 * @param replacementSize the number of times <code>replacement</code> is to replace the replaced elements 600 */ 601 public void replace(int from, int length, byte replacement, int replacementSize) { 602 checkSize(replacementSize); 603 shrinkOrExpand(from, length, replacementSize); 604 java.util.Arrays.fill(this.elements, from, from + replacementSize, replacement); 605 } 606 607 /** 608 * Retains (keeps) only the elements in the receiver that are contained in 609 * the specified other list. In other words, removes from the receiver all 610 * of its elements that are not contained in the specified other list. 611 * 612 * @param other 613 * the other list to test against. 614 * @return <code>true</code> if the receiver changed as a result of the 615 * call. 616 */ 617 public boolean retainAll(ByteArrayList other) { 618 if (other.size() == 0) { 619 if (size == 0) return false; 620 size = 0; 621 return true; 622 } 623 624 int limit = other.size() - 1; 625 int j = 0; 626 for (int i = 0; i < size; i++) { 627 if (other.indexOf(elements[i], 0, limit) >= 0) 628 elements[j++] = elements[i]; 629 } 630 631 boolean modified = (j != size); 632 size = j; 633 return modified; 634 } 635 636 /** 637 * Reverses the elements of the receiver. Last becomes first, second last 638 * becomes second first, and so on. 639 */ 640 public void reverse() { 641 byte tmp; 642 int limit = size / 2; 643 int j = size - 1; 644 645 byte[] theElements = elements; 646 for (int i = 0; i < limit;) { //swap 647 tmp = theElements[i]; 648 theElements[i++] = theElements[j]; 649 theElements[j--] = tmp; 650 } 651 } 652 653 /** 654 * Replaces the element at the specified position in the receiver with the 655 * specified element. 656 * 657 * @param index 658 * index of element to replace. 659 * @param element 660 * element to be stored at the specified position. 661 * @throws IndexOutOfBoundsException if index is out of range. 662 */ 663 public final void set(int index, byte element) { 664 checkIndex(index); 665 elements[index] = element; 666 } 667 668 /** 669 * Replaces the 4 bytes at the specified position in the receiver with the 670 * specified element; 671 * using the NIO default byte order, which is ByteOrder.BIG_ENDIAN. 672 * 673 * @param index 674 * index of first element to replace. 675 * @param elem 676 * element value to set. 677 * @throws IndexOutOfBoundsException if index is out of range. 678 */ 679 public void setInt(int index, int elem) { 680 checkIndex(index); 681 checkIndex(index + 4 - 1); 682 asByteBuffer().putInt(index, elem); 683 //ByteConverter.write(elem, elements, s); 684 } 685 686 // /** 687 // * Sets the receiver's elements to be the specified array (not a copy of 688 // * it). 689 // * <p> 690 // * The size and capacity of the list is the length of the array. <b>WARNING: 691 // * </b> For efficiency reasons and to keep memory usage low, <b>the array is 692 // * not copied </b>. So if subsequently you modify the specified array 693 // * directly via the [] operator, be sure you know what you're doing. 694 // * 695 // * @param elems 696 // * the new elements to be stored. 697 // */ 698 // public void setElements(byte[] elems) { 699 // this.elements = elems; 700 // this.size = elems.length; 701 // } 702 703 /** 704 * Sets the size to the given new size; expanding the list capacity if 705 * necessary. 706 * 707 * @param newSize 708 * the new size. 709 * @throws IndexOutOfBoundsException 710 * if index is out of range. 711 */ 712 public void setSize(int newSize) { 713 checkSize(newSize); 714 ensureCapacity(newSize); 715 size = newSize; 716 } 717 718 /** 719 * Returns the number of elements contained in the receiver. 720 * 721 * @return the number of elements contained in the receiver. 722 */ 723 public int size() { 724 return size; 725 } 726 727 /** 728 * Sorts the receiver into ascending numerical order. 729 */ 730 public void sort() { 731 java.util.Arrays.sort(elements, 0, size); 732 } 733 734 /** 735 * Returns a new list of the copied part of the receiver between 736 * <code>from</code>, inclusive, and <code>to</code>, exclusive. 737 * 738 * @param from 739 * the index of the first element (inclusive). 740 * @param to 741 * the index of the last element (exclusive). 742 * @return a new list 743 * @throws IndexOutOfBoundsException 744 * if indexes are out of range 745 */ 746 public ByteArrayList subList(int from, int to) { 747 checkFromTo(from, to); 748 byte[] part = new byte[to - from]; 749 System.arraycopy(elements, from, part, 0, to - from); 750 return new ByteArrayList(part); 751 } 752 753 /** 754 * Returns a copied array of bytes containing all the elements 755 * in the receiver; the returned array has length = this.size(). 756 */ 757 public byte[] toArray() { 758 byte[] copy = new byte[size]; 759 System.arraycopy(elements, 0, copy, 0, size); 760 return copy; 761 } 762 763 /** 764 * Returns a <code>java.util.ArrayList</code> containing all the elements 765 * in the receiver. 766 */ 767 public java.util.ArrayList toList() { 768 java.util.ArrayList list = new java.util.ArrayList(size); 769 for (int i = 0; i < size; i++) 770 list.add(new Byte(elements[i])); 771 return list; 772 } 773 774 /** 775 * Returns a string representation of the receiver, containing the numeric 776 * String representation of each element. 777 */ 778 public String toString() { 779 //return toList().toString(); 780 StringBuffer buf = new StringBuffer(4*size); 781 buf.append("["); 782 for (int i = 0; i < size; i++) { 783 buf.append(elements[i]); 784 if (i < size-1) buf.append(", "); 785 } 786 buf.append("]"); 787 return buf.toString(); 788 } 789 790 /** 791 * Returns a decoded string representation of the receiver. 792 * 793 * @param charset the requested charset to convert with 794 * (e.g. Charset.forName("US-ASCII"), Charset.forName("UTF-8")) 795 */ 796 public String toString(Charset charset) { 797 return getString(0, size, charset); 798 } 799 800 /** 801 * Trims the capacity of the receiver to be the receiver's current size. 802 * Releases any superfluos internal memory. An application can use this 803 * operation to minimize the storage of the receiver. 804 */ 805 public void trimToSize() { 806 if (elements.length > size) { 807 byte[] newArray = new byte[size]; 808 System.arraycopy(elements, 0, newArray, 0, size); 809 elements = newArray; 810 } 811 } 812 813 /** 814 * Checks if the given index is in range. 815 */ 816 protected final void checkIndex(int index) { 817 if (index >= size || index < 0) 818 throw new IndexOutOfBoundsException("index: " + index 819 + ", size: " + size); 820 } 821 822 /** 823 * Checks if the given range is within the contained array's bounds. 824 */ 825 protected final void checkLength(int from, int length) { 826 if (from < 0 || length < 0 || from + length > size) 827 throw new IndexOutOfBoundsException("from: " + from + ", length: " 828 + length + ", size=" + size); 829 } 830 831 /** 832 * Checks if the given range is within the contained array's bounds. 833 */ 834 protected final void checkFromTo(int from, int to) { 835 if (from < 0 || from > to || to > size) 836 throw new IndexOutOfBoundsException("from: " + from + ", to: " 837 + to + ", size=" + size); 838 } 839 840 /** 841 * Checks if the given size is within bounds. 842 */ 843 protected final void checkSize(int newSize) { 844 if (newSize < 0) 845 throw new IndexOutOfBoundsException("newSize: " + newSize 846 + ", Size: " + size); 847 } 848 849 }