1 29 30 package com.caucho.quercus.env; 31 32 import com.caucho.quercus.Quercus; 33 34 import java.io.IOException ; 35 import java.io.ObjectInputStream ; 36 import java.io.ObjectOutputStream ; 37 import java.io.PrintWriter ; 38 import java.io.Serializable ; 39 40 43 public class StringBuilderValue extends UnicodeValue 44 implements Serializable 45 { 46 private char []_buffer; 47 private int _length; 48 49 private String _value; 50 51 public StringBuilderValue() 52 { 53 _buffer = new char[128]; 54 } 55 56 public StringBuilderValue(int capacity) 57 { 58 if (capacity < 64) 59 capacity = 64; 60 61 _buffer = new char[capacity]; 62 } 63 64 public StringBuilderValue(String value) 65 { 66 if (value == null) 67 value = ""; 68 69 int length = value.length(); 70 71 _buffer = new char[length]; 72 73 _length = length; 74 75 value.getChars(0, length, _buffer, 0); 76 77 _value = value; 78 } 79 80 public StringBuilderValue(String value, int minLength) 81 { 82 if (value == null) 83 value = ""; 84 85 _length = value.length(); 86 _value = value; 87 88 int length = _length; 89 90 if (length < minLength) 91 length = minLength; 92 93 _buffer = new char[length]; 94 95 value.getChars(0, _length, _buffer, 0); 96 } 97 98 public StringBuilderValue(char []buffer, int offset, int length) 99 { 100 int capacity; 101 102 if (length < 64) 103 capacity = 128; 104 else 105 capacity = 2 * length; 106 107 _buffer = new char[capacity]; 108 _length = length; 109 110 System.arraycopy(buffer, offset, _buffer, 0, length); 111 } 112 113 public StringBuilderValue(char []buffer) 114 { 115 this(buffer, 0, buffer.length); 116 } 117 118 public StringBuilderValue(char []buffer, int offset, int length, 119 boolean isExact) 120 { 121 _buffer = new char[length]; 122 _length = length; 123 124 System.arraycopy(buffer, offset, _buffer, 0, length); 125 } 126 127 public StringBuilderValue(Character []buffer) 128 { 129 int length = buffer.length; 130 131 _buffer = new char[length]; 132 _length = length; 133 134 for (int i = 0; i < length; i++) { 135 _buffer[i] = buffer[i].charValue(); 136 } 137 } 138 139 142 public String getValue() 143 { 144 return toString(); 145 } 146 147 150 public String getType() 151 { 152 return "string"; 153 } 154 155 158 public InternStringValue intern(Quercus quercus) 159 { 160 return quercus.intern(toString()); 161 } 162 163 166 public boolean isLongConvertible() 167 { 168 char []buffer = _buffer; 169 int len = _length; 170 171 if (len == 0) 172 return true; 173 174 int i = 0; 175 char ch = _buffer[0]; 176 177 if (ch == '-' || ch == '+') 178 i++; 179 180 for (; i < len; i++) { 181 ch = _buffer[i]; 182 183 if (! ('0' <= ch && ch <= '9')) 184 return false; 185 } 186 187 return true; 188 } 189 190 193 public boolean isDouble() 194 { 195 return getNumericType() == IS_DOUBLE; 196 } 197 198 201 @Override 202 public boolean isNumber() 203 { 204 return getNumericType() != IS_STRING; 205 } 206 207 210 public boolean isScalar() 211 { 212 return true; 213 } 214 215 218 protected int getNumericType() 219 { 220 char []buffer = _buffer; 221 int len = _length; 222 223 if (len == 0) { 224 return IS_STRING; 226 } 227 228 int i = 0; 229 int ch = 0; 230 boolean hasPoint = false; 231 232 if (i < len && ((ch = buffer[i]) == '+' || ch == '-')) { 233 i++; 234 } 235 236 if (len <= i) 237 return IS_STRING; 238 239 ch = buffer[i]; 240 241 if (ch == '.') { 242 for (i++; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 243 return IS_DOUBLE; 244 } 245 246 return IS_STRING; 247 } 248 else if (! ('0' <= ch && ch <= '9')) 249 return IS_STRING; 250 251 for (; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 252 } 253 254 if (len <= i) 255 return IS_LONG; 256 else if (ch == '.' || ch == 'e' || ch == 'E') { 257 for (i++; 258 i < len && ('0' <= (ch = buffer[i]) && ch <= '9' || 259 ch == '+' || ch == '-' || ch == 'e' || ch == 'E'); 260 i++) { 261 } 262 263 if (i < len) 264 return IS_STRING; 265 else 266 return IS_DOUBLE; 267 } 268 else 269 return IS_STRING; 270 } 271 272 275 public boolean toBoolean() 276 { 277 if (_length == 0) 278 return false; 279 else if (_length == 1 && _buffer[0] == '0') 280 return false; 281 else 282 return true; 283 } 284 285 288 public long toLong() 289 { 290 return toLong(_buffer, 0, _length); 291 } 292 293 296 public static long toLong(char []buffer, int offset, int len) 297 { 298 if (len == 0) 299 return 0; 300 301 long value = 0; 302 long sign = 1; 303 304 int i = 0; 305 int end = offset + len; 306 307 char ch = buffer[offset]; 308 if (ch == '-') { 309 sign = -1; 310 offset++; 311 } 312 else if (ch == '+') 313 offset++; 314 315 while (offset < end) { 316 ch = buffer[offset++]; 317 318 if ('0' <= ch && ch <= '9') 319 value = 10 * value + ch - '0'; 320 else 321 return sign * value; 322 } 323 324 return sign * value; 325 } 326 327 330 public double toDouble() 331 { 332 char []buffer = _buffer; 333 int len = _length; 334 int i = 0; 335 int ch = 0; 336 337 if (i < len && ((ch = buffer[i]) == '+' || ch == '-')) { 338 i++; 339 } 340 341 for (; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 342 } 343 344 if (ch == '.') { 345 for (i++; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 346 } 347 348 if (i == 1) 349 return 0; 350 } 351 352 if (ch == 'e' || ch == 'E') { 353 int e = i++; 354 355 if (i < len && (ch = buffer[i]) == '+' || ch == '-') { 356 i++; 357 } 358 359 for (; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 360 } 361 362 if (i == e + 1) 363 i = e; 364 } 365 366 if (i == 0) 367 return 0; 368 369 try { 370 if (i == len) 371 return Double.parseDouble(toString()); 372 else 373 return Double.parseDouble(new String (_buffer, 0, i)); 374 } catch (NumberFormatException e) { 375 return 0; 376 } 377 } 378 379 382 public String toString() 383 { 384 if (_value == null) 385 _value = new String (_buffer, 0, _length); 386 387 return _value; 388 } 389 390 393 public Object toJavaObject() 394 { 395 if (_value == null) 396 _value = new String (_buffer, 0, _length); 397 398 return _value; 399 } 400 401 404 @Override 405 public StringValue toStringBuilder() 406 { 407 return new StringBuilderValue(_buffer, 0, _length); 408 } 409 410 413 @Override 414 public void appendTo(StringBuilderValue sb) 415 { 416 sb.append(_buffer, 0, _length); 417 } 418 419 422 public Value toKey() 423 { 424 char []buffer = _buffer; 425 int len = _length; 426 427 if (len == 0) 428 return this; 429 430 int sign = 1; 431 long value = 0; 432 433 int i = 0; 434 char ch = buffer[i]; 435 if (ch == '-') { 436 sign = -1; 437 i++; 438 } 439 440 for (; i < len; i++) { 441 ch = buffer[i]; 442 443 if ('0' <= ch && ch <= '9') 444 value = 10 * value + ch - '0'; 445 else 446 return this; 447 } 448 449 return new LongValue(sign * value); 450 } 451 452 457 public byte[] toBytes() 458 { 459 char []buffer = _buffer; 460 461 final int len = _length; 462 byte[] bytes = new byte[len]; 463 464 for (int i = 0; i < len; i++) { 465 bytes[i] = (byte) buffer[i]; 466 } 467 468 return bytes; 469 } 470 471 474 public Value get(Value key) 475 { 476 return charValueAt(key.toLong()); 477 } 478 479 482 public Value getRef(Value key) 483 { 484 return charValueAt(key.toLong()); 485 } 486 487 490 @Override 491 public Value charValueAt(long index) 492 { 493 int len = _length; 494 495 if (index < 0 || len <= index) 496 return StringValue.EMPTY; 497 else 498 return StringValue.create(_buffer[(int) index]); 499 } 500 501 504 @Override 505 public Value setCharValueAt(long index, String value) 506 { 507 int len = _length; 508 509 if (index < 0 || len <= index) 510 return this; 511 else { 512 StringBuilderValue sb = new StringBuilderValue(_buffer, 0, (int) index); 513 sb.append(value); 514 sb.append(_buffer, (int) (index + 1), (int) (len - index - 1)); 515 516 return sb; 517 } 518 } 519 520 524 527 @Override 528 public int length() 529 { 530 return _length; 531 } 532 533 void setLength(int length) 534 { 535 _length = length; 536 } 537 538 541 @Override 542 public final char charAt(int index) 543 { 544 return _buffer[index]; 545 } 546 547 550 @Override 551 public CharSequence subSequence(int start, int end) 552 { 553 if (end <= start) 554 return StringValue.EMPTY; 555 556 char []newBuffer = new char[end - start]; 557 558 System.arraycopy(_buffer, start, newBuffer, 0, end - start); 559 560 return new StringBuilderValue(newBuffer, 0, end - start); 561 } 562 563 567 570 @Override 571 public int indexOf(char match) 572 { 573 int length = _length; 574 char []buffer = _buffer; 575 576 for (int head = 0; head < length; head++) { 577 if (buffer[head] == match) 578 return head; 579 } 580 581 return -1; 582 } 583 584 587 @Override 588 public int indexOf(char match, int head) 589 { 590 int length = _length; 591 char []buffer = _buffer; 592 593 for (; head < length; head++) { 594 if (buffer[head] == match) 595 return head; 596 } 597 598 return -1; 599 } 600 601 604 @Override 605 public int indexOf(CharSequence match, int head) 606 { 607 int length = _length; 608 int matchLength = match.length(); 609 610 if (matchLength <= 0) 611 return -1; 612 else if (head < 0) 613 return -1; 614 615 int end = length - matchLength; 616 char first = match.charAt(0); 617 618 char []buffer = _buffer; 619 620 loop: 621 for (; head <= end; head++) { 622 if (buffer[head] != first) 623 continue; 624 625 for (int i = 1; i < matchLength; i++) { 626 if (buffer[head + i] != match.charAt(i)) 627 continue loop; 628 } 629 630 return head; 631 } 632 633 return -1; 634 } 635 636 639 @Override 640 public char []toCharArray() 641 { 642 char[] dest = new char[_length]; 643 644 System.arraycopy(_buffer, 0, dest, 0, _length); 645 646 return dest; 647 } 648 649 652 public char []getBuffer() 653 { 654 return _buffer; 655 } 656 657 661 public void print(Env env) 662 { 663 env.print(_buffer, 0, _length); 664 } 665 666 669 public void serialize(StringBuilder sb) 670 { 671 sb.append("s:"); 672 sb.append(_length); 673 sb.append(":\""); 674 sb.append(_buffer, 0, _length); 675 sb.append("\";"); 676 } 677 678 682 685 @Override 686 public final StringValue append(String s) 687 { 688 int len = s.length(); 689 690 if (_buffer.length < _length + len) 691 ensureCapacity(_length + len); 692 693 s.getChars(0, len, _buffer, _length); 694 695 _length += len; 696 _value = null; 697 698 return this; 699 } 700 701 704 @Override 705 public final StringValue append(String s, int start, int end) 706 { 707 int len = end - start; 708 709 if (_buffer.length < _length + len) 710 ensureCapacity(_length + len); 711 712 s.getChars(start, end, _buffer, _length); 713 714 _length += len; 715 _value = null; 716 717 return this; 718 } 719 720 723 @Override 724 public final StringValue append(char []buf, int offset, int length) 725 { 726 if (_buffer.length < _length + length) 727 ensureCapacity(_length + length); 728 729 System.arraycopy(buf, offset, _buffer, _length, length); 730 731 _length += length; 732 _value = null; 733 734 return this; 735 } 736 737 740 @Override 741 public final StringValue append(CharSequence buf, int head, int tail) 742 { 743 _value = null; 744 745 int length = tail - head; 746 747 if (_buffer.length < _length + length) 748 ensureCapacity(_length + length); 749 750 if (buf instanceof StringBuilderValue) { 751 StringBuilderValue sb = (StringBuilderValue) buf; 752 753 System.arraycopy(sb._buffer, head, _buffer, _length, tail - head); 754 755 _length += tail - head; 756 } else { 757 for (; head < tail; head++) 758 _buffer[_length++] = buf.charAt(head); 759 } 760 761 return this; 762 } 763 764 767 @Override 768 public final StringValue append(StringBuilderValue sb, int head, int tail) 769 { 770 _value = null; 771 772 int length = tail - head; 773 774 if (_buffer.length < _length + length) 775 ensureCapacity(_length + length); 776 777 System.arraycopy(sb._buffer, head, _buffer, _length, tail - head); 778 779 _length += tail - head; 780 781 return this; 782 } 783 784 787 @Override 788 public final StringValue append(char v) 789 { 790 _value = null; 791 792 if (_buffer.length < _length + 1) 793 ensureCapacity(_length + 1); 794 795 _buffer[_length++] = v; 796 797 return this; 798 } 799 800 803 @Override 804 public final StringValue append(Value v) 805 { 806 _value = null; 807 808 v.appendTo(this); 809 810 return this; 811 } 812 813 817 820 public int hashCode() 821 { 822 int hash = 37; 823 824 int length = _length; 825 char []buffer = _buffer; 826 827 for (int i = 0; i < length; i++) { 828 hash = 65521 * hash + buffer[i]; 829 } 830 831 return hash; 832 } 833 834 837 public boolean equals(Object o) 838 { 839 if (this == o) 840 return true; 841 else if (o instanceof StringBuilderValue) { 842 StringBuilderValue s = (StringBuilderValue) o; 843 844 int aLength = _length; 845 int bLength = s._length; 846 847 if (aLength != bLength) 848 return false; 849 850 char []aBuffer = _buffer; 851 char []bBuffer = s._buffer; 852 853 for (int i = aLength - 1; i >= 0; i--) { 854 if (aBuffer[i] != bBuffer[i]) 855 return false; 856 } 857 858 return true; 859 } 860 else if (o instanceof StringValue) { 861 StringValue s = (StringValue) o; 862 863 int aLength = length(); 864 int bLength = s.length(); 865 866 if (aLength != bLength) 867 return false; 868 869 for (int i = aLength - 1; i >= 0; i--) { 870 if (charAt(i) != s.charAt(i)) 871 return false; 872 } 873 874 return true; 875 } else { 876 return false; 877 } 878 } 879 880 884 889 public void generate(PrintWriter out) 890 throws IOException 891 { 892 out.print("new InternStringValue(\""); 893 printJavaString(out, toString()); 894 out.print("\")"); 895 } 896 897 private void ensureCapacity(int capacity) 898 { 899 if (capacity <= _buffer.length) 900 return; 901 902 int newCapacity; 903 904 if (capacity < 4096) { 905 newCapacity = _buffer.length; 906 907 if (newCapacity < 64) 908 newCapacity = 64; 909 910 while (newCapacity < capacity) 911 newCapacity = 4 * newCapacity; 912 } 913 else 914 newCapacity = (capacity + 4096) & ~4095; 915 916 char []buffer = new char[newCapacity]; 917 System.arraycopy(_buffer, 0, buffer, 0, _length); 918 919 _buffer = buffer; 920 } 921 922 926 private void writeObject(ObjectOutputStream out) 927 throws IOException 928 { 929 out.writeInt(_length); 930 931 for (int i = 0; i < _length; i++) { 932 out.writeChar(_buffer[i]); 933 } 934 } 935 936 private void readObject(ObjectInputStream in) 937 throws ClassNotFoundException , IOException 938 { 939 _length = in.readInt(); 940 941 _buffer = new char[_length]; 942 943 for (int i = 0; i < _length; i++) { 944 _buffer[i] = in.readChar(); 945 } 946 } 947 } 948 949 | Popular Tags |