1 9 package javolution.lang; 10 11 import java.io.IOException; 12 13 import j2me.io.Serializable; 14 import j2me.lang.CharSequence; 15 16 import javolution.JavolutionError; 17 import javolution.realtime.ObjectFactory; 18 import javolution.realtime.Realtime; 19 import javolution.realtime.RealtimeObject; 20 21 35 public class TextBuilder extends RealtimeObject implements Appendable, 36 CharSequence, Reusable, Serializable { 37 38 41 private static final Factory FACTORY = new Factory() { 42 public Object create() { 43 return new TextBuilder(); 44 } 45 46 public void cleanup(Object obj) { 47 ((TextBuilder) obj).reset(); 48 } 49 }; 50 51 59 private static final int D0 = 5; 60 61 private static final int R0 = 0; 62 63 private static final int M0 = (1 << D0) - 1; 64 65 private static final int C0 = 1 << D0; 67 private static final int D1 = D0 + 2; 68 69 private static final int R1 = D0; 70 71 private static final int M1 = (1 << D1) - 1; 72 73 private static final int C1 = 1 << (D0 + D1); 75 private static final int D2 = D1 + 2; 76 77 private static final int R2 = D0 + D1; 78 79 private static final int M2 = (1 << D2) - 1; 80 81 private static final int C2 = 1 << (D0 + D1 + D2); 83 private static final int D3 = D2 + 2; 84 85 private static final int R3 = D0 + D1 + D2; 86 87 private static final int M3 = (1 << D3) - 1; 88 89 private final char[] _chars0 = new char[1 << D0]; 91 private char[][] _chars1; 93 private char[][][] _chars2; 95 private char[][][][] _chars3; 97 private static final ObjectFactory CHARS0_FACTORY = new ObjectFactory() { 98 public Object create() { 99 return new char[1 << D0]; 100 } 101 }; 102 103 private static final ObjectFactory CHARS1_FACTORY = new ObjectFactory() { 104 public Object create() { 105 return new char[1 << D1][]; 106 } 107 }; 108 109 private static final ObjectFactory CHARS2_FACTORY = new ObjectFactory() { 110 public Object create() { 111 return new char[1 << D2][][]; 112 } 113 }; 114 115 private static final ObjectFactory CHARS3_FACTORY = new ObjectFactory() { 116 public Object create() { 117 return new char[1 << D3][][][]; 118 } 119 }; 120 121 124 private int _capacity = 1 << D0; 125 126 129 private int _length; 130 131 134 public TextBuilder() { 135 } 136 137 142 public TextBuilder(CharSequence csq) { 143 append(csq); 144 } 145 146 153 public TextBuilder(int capacity) { 154 while (capacity > _capacity) { 155 increaseCapacity(); 156 } 157 } 158 159 165 public static TextBuilder newInstance() { 166 return (TextBuilder) FACTORY.object(); 167 } 168 169 174 public final int length() { 175 return _length; 176 } 177 178 186 public final char charAt(int index) { 187 if ((index < 0) || (index >= _length)) 188 throw new IndexOutOfBoundsException("index: " + index); 189 if (index < C0) { 190 return _chars0[index]; 191 } else if (index < C1) { 192 return _chars1[(index >> R1)][index & M0]; 193 } else if (index < C2) { 194 return _chars2[(index >> R2)][(index >> R1) & M1][index & M0]; 195 } else { 196 return _chars3[(index >> R3)][(index >> R2) & M2][(index >> R1) 197 & M1][index & M0]; 198 } 199 } 200 201 213 public final void getChars(int srcBegin, int srcEnd, char[] dst, 214 int dstBegin) { 215 if ((srcBegin < 0) || (dstBegin < 0) || (srcBegin > srcEnd) 216 || (srcEnd > this.length()) 217 || ((dstBegin + srcEnd - srcBegin) > dst.length)) 218 throw new IndexOutOfBoundsException(); 219 for (int i = srcBegin, j = dstBegin; i < srcEnd;) { 220 dst[j++] = charAt(i++); 221 } 222 } 223 224 232 public final void setCharAt(int index, char c) { 233 if ((index < 0) || (index >= _length)) 234 throw new IndexOutOfBoundsException("index: " + index); 235 if (index < C0) { 236 _chars0[index] = c; 237 } else if (index < C1) { 238 _chars1[(index >> R1)][index & M0] = c; 239 } else if (index < C2) { 240 _chars2[(index >> R2)][(index >> R1) & M1][index & M0] = c; 241 } else { 242 _chars3[(index >> R3)][(index >> R2) & M2][(index >> R1) & M1][index 243 & M0] = c; 244 } 245 } 246 247 255 public final void setLength(int newLength) { 256 if (newLength < 0) 257 throw new IndexOutOfBoundsException(); 258 if (newLength <= _length) { 259 _length = newLength; 260 } else { 261 for (int i = _length; i++ < newLength;) { 262 append('\u0000'); 263 } 264 } 265 } 266 267 277 public final CharSequence subSequence(int start, int end) { 278 if ((start < 0) || (end < 0) || (start > end) || (end > _length)) 279 throw new IndexOutOfBoundsException(); 280 return Text.valueOf(this, start, end); 281 } 282 283 289 public final Appendable append(char c) { 290 if (_length >= _capacity) 291 increaseCapacity(); 292 final int i = _length++; 293 if (i < C0) { 294 _chars0[i] = c; 295 } else if (i < C1) { 296 _chars1[(i >> R1)][i & M0] = c; 297 } else if (i < C2) { 298 _chars2[(i >> R2)][(i >> R1) & M1][i & M0] = c; 299 } else { 300 _chars3[(i >> R3)][(i >> R2) & M2][(i >> R1) & M1][i & M0] = c; 301 } 302 return this; 303 } 304 305 313 public final Appendable append(CharSequence csq) { 314 return (csq == null) ? append("null") : append(csq, 0, csq.length()); 315 } 316 317 329 public final Appendable append(CharSequence csq, int start, int end) { 330 if (csq == null) 331 return append("null"); 332 if ((start < 0) || (end < 0) || (start > end) || (end > csq.length())) 333 throw new IndexOutOfBoundsException(); 334 for (int i = start; i < end;) { 335 append(csq.charAt(i++)); 336 } 337 return this; 338 } 339 340 348 public final TextBuilder append(Object obj) { 349 if (obj instanceof String) { 350 return append((String) obj); 351 } else if (obj instanceof CharSequence) { 352 return (TextBuilder) append((CharSequence) obj); 353 } else if (obj instanceof Realtime) { 354 return append(((Realtime) obj).toText()); 355 } else if (obj != null) { 356 return append(obj.toString()); 357 } else { 358 return append("null"); 359 } 360 } 361 362 370 public final TextBuilder append(String str) { 371 if (str == null) 372 return append("null"); 373 final int length = str.length(); 374 for (int i = 0; i < length;) { 375 append(str.charAt(i++)); 376 } 377 return this; 378 } 379 380 392 public final TextBuilder append(String str, int start, int end) { 393 if (str == null) 394 return append("null"); 395 if ((start < 0) || (end < 0) || (start > end) || (end > str.length())) 396 throw new IndexOutOfBoundsException(); 397 for (int i = start; i < end;) { 398 append(str.charAt(i++)); 399 } 400 return this; 401 } 402 403 411 public TextBuilder append(Text text) { 412 if (text == null) 413 return append("null"); 414 final int length = text.length(); 415 for (int i = 0; i < length;) { 416 append(text.charAt(i++)); 417 } 418 return this; 419 } 420 421 427 public final TextBuilder append(char chars[]) { 428 return append(chars, 0, chars.length); 429 } 430 431 441 public final TextBuilder append(char chars[], int offset, int length) { 442 if ((offset < 0) || (length < 0) || ((offset + length) > chars.length)) 443 throw new IndexOutOfBoundsException(); 444 final int end = offset + length; 445 for (int i = offset; i < end;) { 446 append(chars[i++]); 447 } 448 return this; 449 } 450 451 459 public final TextBuilder append(boolean b) { 460 try { 461 TypeFormat.format(b, this); 462 return this; 463 } catch (IOException e) { 464 throw new JavolutionError(e); 465 } 466 } 467 468 476 public final TextBuilder append(int i) { 477 try { 478 TypeFormat.format(i, this); 479 return this; 480 } catch (IOException e) { 481 throw new JavolutionError(e); 482 } 483 } 484 485 494 public final TextBuilder append(int i, int radix) { 495 try { 496 TypeFormat.format(i, radix, this); 497 return this; 498 } catch (IOException e) { 499 throw new JavolutionError(e); 500 } 501 } 502 503 511 public final TextBuilder append(long l) { 512 try { 513 TypeFormat.format(l, this); 514 return this; 515 } catch (IOException e) { 516 throw new JavolutionError(e); 517 } 518 } 519 520 529 public final TextBuilder append(long l, int radix) { 530 try { 531 TypeFormat.format(l, radix, this); 532 return this; 533 } catch (IOException e) { 534 throw new JavolutionError(e); 535 } 536 } 537 538 555 556 573 574 599 600 609 public final TextBuilder insert(int index, CharSequence csq) { 610 if ((index < 0) || (index > _length)) 611 throw new IndexOutOfBoundsException("index: " + index); 612 final int shift = csq.length(); 613 _length += shift; 614 while (_length >= _capacity) { 615 increaseCapacity(); 616 } 617 for (int i = _length - shift; --i >= index;) { 618 this.setCharAt(i + shift, this.charAt(i)); 619 } 620 for (int i = csq.length(); --i >= 0;) { 621 this.setCharAt(index + i, csq.charAt(i)); 622 } 623 return this; 624 } 625 626 635 public final TextBuilder delete(int start, int end) { 636 if ((start < 0) || (end < 0) || (start > end) || (end > this.length())) 637 throw new IndexOutOfBoundsException(); 638 for (int i = end, j = start; i < _length;) { 639 this.setCharAt(j++, this.charAt(i++)); 640 } 641 _length -= end - start; 642 return this; 643 } 644 645 650 public final TextBuilder reverse() { 651 final int n = _length - 1; 652 for (int j = (n - 1) >> 1; j >= 0;) { 653 char c = charAt(j); 654 setCharAt(j, charAt(n - j)); 655 setCharAt(n - j--, c); 656 } 657 return this; 658 } 659 660 667 public final Text toText() { 668 return Text.valueOf(this, 0, this.length()); 669 } 670 671 674 public final void reset() { 675 setLength(0); 676 } 677 678 683 public final int hashCode() { 684 int h = 0; 685 for (int i = 0; i < _length;) { 686 h = 31 * h + charAt(i++); 687 } 688 return h; 689 } 690 691 700 public final boolean equals(Object obj) { 701 if (this == obj) 702 return true; 703 if (!(obj instanceof TextBuilder)) 704 return false; 705 TextBuilder that = (TextBuilder) obj; 706 if (this._length != that._length) 707 return false; 708 for (int i = 0; i < _length;) { 709 if (this.charAt(i) != that.charAt(i++)) 710 return false; 711 } 712 return true; 713 } 714 715 718 private void increaseCapacity() { 719 final int c = _capacity; 720 _capacity += 1 << D0; 721 if (c < C1) { 722 if (_chars1 == null) { 723 _chars1 = (char[][]) CHARS1_FACTORY.newObject(); 724 } 725 _chars1[(c >> R1)] = (char[]) CHARS0_FACTORY.newObject(); 726 727 } else if (c < C2) { 728 if (_chars2 == null) { 729 _chars2 = (char[][][]) CHARS2_FACTORY.newObject(); 730 } 731 if (_chars2[(c >> R2)] == null) { 732 _chars2[(c >> R2)] = (char[][]) CHARS1_FACTORY.newObject(); 733 } 734 _chars2[(c >> R2)][(c >> R1) & M1] = (char[]) CHARS0_FACTORY 735 .newObject(); 736 737 } else { 738 if (_chars3 == null) { 739 _chars3 = (char[][][][]) CHARS3_FACTORY.newObject(); 740 } 741 if (_chars3[(c >> R3)] == null) { 742 _chars3[(c >> R3)] = (char[][][]) CHARS2_FACTORY.newObject(); 743 } 744 if (_chars3[(c >> R3)][(c >> R2) & M2] == null) { 745 _chars3[(c >> R3)][(c >> R2) & M2] = (char[][]) CHARS1_FACTORY 746 .newObject(); 747 } 748 _chars3[(c >> R3)][(c >> R2) & M2][(c >> R1) & M1] = (char[]) CHARS0_FACTORY 749 .newObject(); 750 } 751 } 752 } | Popular Tags |