1 29 30 package com.caucho.quercus.env; 31 32 import java.io.IOException ; 33 import java.io.InputStream ; 34 import java.io.ObjectInputStream ; 35 import java.io.ObjectOutputStream ; 36 import java.io.OutputStream ; 37 import java.io.PrintWriter ; 38 import java.io.Serializable ; 39 40 43 public class BinaryBuilderValue extends BinaryValue 44 implements Serializable  45 { 46 private byte []_buffer; 47 private int _length; 48 49 private String _value; 50 51 public BinaryBuilderValue() 52 { 53 _buffer = new byte[128]; 54 } 55 56 public BinaryBuilderValue(int capacity) 57 { 58 if (capacity < 64) 59 capacity = 128; 60 else 61 capacity = 2 * capacity; 62 63 _buffer = new byte[capacity]; 64 } 65 66 public BinaryBuilderValue(byte []buffer, int offset, int length) 67 { 68 _buffer = new byte[length]; 69 _length = length; 70 71 System.arraycopy(buffer, offset, _buffer, 0, length); 72 } 73 74 public BinaryBuilderValue(byte []buffer) 75 { 76 this(buffer, 0, buffer.length); 77 } 78 79 public BinaryBuilderValue(Byte []buffer) 80 { 81 int length = buffer.length; 82 83 _buffer = new byte[length]; 84 _length = length; 85 86 for (int i = 0; i < length; i++) { 87 _buffer[i] = buffer[i].byteValue(); 88 } 89 } 90 91 public BinaryBuilderValue(String value) 92 { 93 this(value.getBytes()); 94 } 95 96 99 public String getValue() 100 { 101 return toString(); 102 } 103 104 107 public String getType() 108 { 109 return "string"; 110 } 111 112 115 public boolean isLongConvertible() 116 { 117 byte []buffer = _buffer; 118 int len = _length; 119 120 if (len == 0) 121 return false; 122 123 for (int i = 0; i < len; i++) { 124 int ch = _buffer[i]; 125 126 if (! ('0' <= ch && ch <= '9')) 127 return false; 128 } 129 130 return true; 131 } 132 133 136 public boolean isDouble() 137 { 138 return getNumericType() == IS_DOUBLE; 139 } 140 141 144 public boolean isNumber() 145 { 146 return getNumericType() != IS_STRING; 147 } 148 149 152 public boolean isScalar() 153 { 154 return true; 155 } 156 157 160 protected int getNumericType() 161 { 162 byte []buffer = _buffer; 163 int len = _length; 164 165 if (len == 0) 166 return IS_STRING; 167 168 int i = 0; 169 int ch = 0; 170 boolean hasPoint = false; 171 172 if (i < len && ((ch = buffer[i]) == '+' || ch == '-')) { 173 i++; 174 } 175 176 if (len <= i) 177 return IS_STRING; 178 179 ch = buffer[i]; 180 181 if (ch == '.') { 182 for (i++; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 183 return IS_DOUBLE; 184 } 185 186 return IS_STRING; 187 } 188 else if (! ('0' <= ch && ch <= '9')) 189 return IS_STRING; 190 191 for (; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 192 } 193 194 if (len <= i) 195 return IS_LONG; 196 else if (ch == '.' || ch == 'e' || ch == 'E') { 197 for (i++; 198 i < len && ('0' <= (ch = buffer[i]) && ch <= '9' || 199 ch == '+' || ch == '-' || ch == 'e' || ch == 'E'); 200 i++) { 201 } 202 203 if (i < len) 204 return IS_STRING; 205 else 206 return IS_DOUBLE; 207 } 208 else 209 return IS_STRING; 210 } 211 212 215 public boolean toBoolean() 216 { 217 if (_length == 0) 218 return false; 219 else if (_length == 1 && _buffer[0] == '0') 220 return false; 221 else 222 return true; 223 } 224 225 228 public long toLong() 229 { 230 return toLong(_buffer, 0, _length); 231 } 232 233 236 public double toDouble() 237 { 238 byte []buffer = _buffer; 239 int len = _length; 240 int i = 0; 241 int ch = 0; 242 243 if (i < len && ((ch = buffer[i]) == '+' || ch == '-')) { 244 i++; 245 } 246 247 for (; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 248 } 249 250 if (ch == '.') { 251 for (i++; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 252 } 253 254 if (i == 1) 255 return 0; 256 } 257 258 if (ch == 'e' || ch == 'E') { 259 int e = i++; 260 261 if (i < len && (ch = buffer[i]) == '+' || ch == '-') { 262 i++; 263 } 264 265 for (; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) { 266 } 267 268 if (i == e + 1) 269 i = e; 270 } 271 272 if (i == 0) 273 return 0; 274 275 try { 276 if (i == len) 277 return Double.parseDouble(toString()); 278 else 279 return Double.parseDouble(new String (_buffer, 0, i)); 280 } catch (NumberFormatException e) { 281 return 0; 282 } 283 } 284 285 288 public InputStream toInputStream() 289 { 290 return new BuilderInputStream(); 291 } 292 293 296 public String toString() 297 { 298 if (_value == null) 300 _value = new String (_buffer, 0, _length); 301 302 return _value; 303 } 304 305 308 public Object toJavaObject() 309 { 310 if (_value == null) 311 _value = new String (_buffer, 0, _length); 312 313 return _value; 314 } 315 316 319 public void appendTo(BinaryBuilderValue bb) 320 { 321 bb.append(_buffer, 0, _length); 322 } 323 324 327 public void appendTo(StringBuilderValue sb) 328 { 329 toUnicodeValue(Env.getInstance()).appendTo(sb); 330 } 331 332 335 public Value toKey() 336 { 337 byte []buffer = _buffer; 338 int len = _length; 339 340 if (len == 0) 341 return this; 342 343 int sign = 1; 344 long value = 0; 345 346 int i = 0; 347 int ch = buffer[i]; 348 if (ch == '-') { 349 sign = -1; 350 i++; 351 } 352 353 for (; i < len; i++) { 354 ch = buffer[i]; 355 356 if ('0' <= ch && ch <= '9') 357 value = 10 * value + ch - '0'; 358 else 359 return this; 360 } 361 362 return new LongValue(sign * value); 363 } 364 365 370 public byte[] toBytes() 371 { 372 byte []buffer = _buffer; 373 374 int len = _length; 375 byte[] bytes = new byte[_length]; 376 System.arraycopy(_buffer, 0, bytes, 0, _length); 377 378 return bytes; 379 } 380 381 385 388 public Value get(Value key) 389 { 390 return charValueAt(key.toLong()); 391 } 392 393 396 public Value getRef(Value key) 397 { 398 return charValueAt(key.toLong()); 399 } 400 401 404 @Override  405 public Value charValueAt(long index) 406 { 407 int len = _length; 408 409 if (index < 0 || len <= index) 410 return StringValue.EMPTY; 411 else 412 return StringValue.create((char) (_buffer[(int) index] & 0xff)); 413 } 414 415 418 434 435 439 442 @Override  443 public int length() 444 { 445 return _length; 446 } 447 448 451 @Override  452 public char charAt(int index) 453 { 454 return (char) (_buffer[index] & 0xff); 455 } 456 457 460 @Override  461 public CharSequence subSequence(int start, int end) 462 { 463 if (end <= start) 464 return StringValue.EMPTY; 465 466 byte []newBuffer = new byte[end - start]; 467 468 System.arraycopy(_buffer, start, newBuffer, 0, end - start); 469 470 return new BinaryBuilderValue(newBuffer, 0, end - start); 471 } 472 473 477 481 public void print(Env env) 482 { 483 env.write(_buffer, 0, _length); 484 } 485 486 489 public void serialize(StringBuilder sb) 490 { 491 sb.append("s:"); 492 sb.append(_length); 493 sb.append(":\""); 494 sb.append(toString()); 495 sb.append("\";"); 496 } 497 498 502 505 @Override  506 public final StringValue append(String s) 507 { 508 StringBuilderValue sb = new StringBuilderValue(); 509 510 appendTo(sb); 511 sb.append(s); 512 513 return sb; 514 } 515 516 519 @Override  520 public final StringValue append(String s, int start, int end) 521 { 522 StringBuilderValue sb = new StringBuilderValue(); 523 524 appendTo(sb); 525 sb.append(s, start, end); 526 527 return sb; 528 } 529 530 533 @Override  534 public final StringValue append(char ch) 535 { 536 StringBuilderValue sb = new StringBuilderValue(); 537 538 appendTo(sb); 539 sb.append(ch); 540 541 return sb; 542 } 543 544 547 @Override  548 public final StringValue append(char []buf, int offset, int length) 549 { 550 StringBuilderValue sb = new StringBuilderValue(); 551 552 appendTo(sb); 553 sb.append(buf, offset, length); 554 555 return sb; 556 } 557 558 561 @Override  562 public final StringValue append(CharSequence buf, int head, int tail) 563 { 564 int length = tail - head; 565 566 if (_buffer.length < _length + length) 567 ensureCapacity(_length + length); 568 569 if (buf instanceof BinaryBuilderValue) { 570 BinaryBuilderValue sb = (BinaryBuilderValue) buf; 571 572 System.arraycopy(sb._buffer, head, _buffer, _length, tail - head); 573 574 _length += tail - head; 575 576 return this; 577 } 578 else { 579 StringBuilderValue sb = new StringBuilderValue(); 580 581 appendTo(sb); 582 sb.append(buf, head, tail); 583 584 return sb; 585 } 586 } 587 588 591 public final StringValue append(BinaryBuilderValue sb, int head, int tail) 593 { 594 int length = tail - head; 595 596 if (_buffer.length < _length + length) 597 ensureCapacity(_length + length); 598 599 System.arraycopy(sb._buffer, head, _buffer, _length, tail - head); 600 601 _length += tail - head; 602 603 return this; 604 } 605 606 609 @Override  610 public final StringValue append(Value v) 611 { 612 if (v.isUnicode()) { 613 StringBuilderValue sb = new StringBuilderValue(); 614 615 appendTo(sb); 616 v.appendTo(sb); 617 618 return sb; 619 } 620 else { 621 v.appendTo(this); 622 623 return this; 624 } 625 } 626 627 630 public final StringValue append(byte []buf, int offset, int length) 631 { 632 if (_buffer.length < _length + length) 633 ensureCapacity(_length + length); 634 635 System.arraycopy(buf, offset, _buffer, _length, length); 636 637 _length += length; 638 639 return this; 640 } 641 642 645 public final StringValue append(byte []buf) 646 { 647 return append(buf, 0, buf.length); 648 } 649 650 653 public final StringValue append(byte v) 654 { 655 if (_buffer.length < _length + 1) 656 ensureCapacity(_length + 1); 657 658 _buffer[_length++] = v; 659 660 return this; 661 } 662 663 666 public final StringValue appendByte(int v) 667 { 668 if (_buffer.length < _length + 1) 669 ensureCapacity(_length + 1); 670 671 _buffer[_length++] = (byte) v; 672 673 return this; 674 } 675 676 679 @Override  680 public final StringValue append(boolean v) 681 { 682 return appendBytes(v ? "true" : "false"); 683 } 684 685 688 @Override  689 public StringValue append(long v) 690 { 691 return appendBytes(String.valueOf(v)); 692 } 693 694 697 @Override  698 public StringValue append(double v) 699 { 700 return appendBytes(String.valueOf(v)); 701 } 702 703 706 public StringValue appendBytes(String s) 707 { 708 710 int sublen = s.length(); 711 712 if (_buffer.length < _length + sublen) 713 ensureCapacity(_length + sublen); 714 715 for (int i = 0; i < sublen; i++) { 716 _buffer[_length++] = (byte) s.charAt(i); 717 } 718 719 return this; 720 } 721 722 725 public void prepareReadBuffer() 726 { 727 ensureCapacity(_buffer.length + 1); 728 } 729 730 733 public byte []getBuffer() 734 { 735 return _buffer; 736 } 737 738 741 public int getOffset() 742 { 743 return _length; 744 } 745 746 749 public void setOffset(int offset) 750 { 751 _length = offset; 752 } 753 754 757 public int getLength() 758 { 759 return _buffer.length; 760 } 761 762 765 public OutputStream getOutputStream() 766 { 767 return new BuilderOutputStream(); 768 } 769 770 private void ensureCapacity(int newCapacity) 771 { 772 if (newCapacity <= _buffer.length) 773 return; 774 else if (newCapacity < 4096) 775 newCapacity = 4 * newCapacity; 776 else 777 newCapacity = newCapacity + 4096; 778 779 byte []buffer = new byte[newCapacity]; 780 System.arraycopy(_buffer, 0, buffer, 0, _length); 781 782 _buffer = buffer; 783 } 784 785 788 public int hashCode() 789 { 790 int hash = 37; 791 792 int length = _length; 793 794 byte []buffer = _buffer; 795 for (int i = 0; i < length; i++) { 796 hash = 65521 * hash + (buffer[i] & 0xff); 797 } 798 799 return hash; 800 } 801 802 public boolean equals(Object o) 803 { 804 if (o instanceof BinaryBuilderValue) { 805 BinaryBuilderValue value = (BinaryBuilderValue) o; 806 807 int length = _length; 808 809 if (length != value._length) 810 return false; 811 812 byte []bufferA = _buffer; 813 byte []bufferB = value._buffer; 814 815 for (int i = length - 1; i >= 0; i--) { 816 if (bufferA[i] != bufferB[i]) 817 return false; 818 } 819 820 return true; 821 } 822 else if (o instanceof StringValue) { 823 StringValue value = (StringValue) o; 824 825 int length = _length; 826 if (length != value.length()) 827 return false; 828 829 byte []buffer = _buffer; 830 831 for (int i = length - 1; i >= 0; i--) { 832 if ((buffer[i] & 0xff) != value.charAt(i)) 833 return false; 834 } 835 836 return true; 837 } 838 else 839 return false; 840 } 841 842 846 851 public void generate(PrintWriter out) 852 throws IOException  853 { 854 out.print("new BinaryBuilderValue(\""); 855 printJavaString(out, toString()); 856 out.print("\")"); 857 } 858 859 863 private void writeObject(ObjectOutputStream out) 864 throws IOException  865 { 866 out.writeInt(_length); 867 out.write(_buffer, 0, _length); 868 } 869 870 private void readObject(ObjectInputStream in) 871 throws ClassNotFoundException , IOException  872 { 873 _length = in.readInt(); 874 _buffer = new byte[_length]; 875 876 in.read(_buffer, 0, _length); 877 } 878 879 class BinaryInputStream extends InputStream { 880 private int _offset; 881 882 885 public int read() 886 { 887 if (_offset < _length) 888 return _buffer[_offset++]; 889 else 890 return -1; 891 } 892 893 896 public int read(byte []buffer, int offset, int length) 897 { 898 int sublen = _length - _offset; 899 900 if (length < sublen) 901 sublen = length; 902 903 if (sublen <= 0) 904 return -1; 905 906 System.arraycopy(_buffer, _offset, buffer, offset, sublen); 907 908 _offset += sublen; 909 910 return sublen; 911 } 912 } 913 914 class BuilderInputStream extends InputStream { 915 private int _index; 916 917 920 public int read() 921 { 922 if (_index < _length) 923 return _buffer[_index++] & 0xff; 924 else 925 return -1; 926 } 927 928 931 public int read(byte []buffer, int offset, int length) 932 { 933 int sublen = _length - _index; 934 935 if (length < sublen) 936 sublen = length; 937 938 if (sublen <= 0) 939 return -1; 940 941 System.arraycopy(_buffer, _index, buffer, offset, sublen); 942 943 _index += sublen; 944 945 return sublen; 946 } 947 } 948 949 class BuilderOutputStream extends OutputStream { 950 953 public void write(int ch) 954 { 955 append(ch); 956 } 957 958 961 public void write(byte []buffer, int offset, int length) 962 { 963 append(buffer, offset, length); 964 } 965 } 966 } 967 968 | Popular Tags |