1 28 package org.jruby.util; 29 import java.math.BigInteger ; 30 31 import org.jruby.RubyNumeric.InvalidIntegerException; 32 import org.jruby.RubyNumeric.NumberTooLargeException; 33 34 40 public class Convert { 41 42 50 public static final ByteList intToByteList(int i) { 51 if (i == Integer.MIN_VALUE) 52 return new ByteList((byte[])MIN_INT_BYTE_ARRAY.clone(),false); 53 int size = (i < 0) ? arraySize(-i) + 1 : arraySize(i); 54 byte[] buf = new byte[size]; 55 getCharBytes(i, size, buf); 56 return new ByteList(buf,false); 57 } 58 59 68 public static final ByteList intToByteList(int i, int radix) { 69 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) 70 radix = 10; 71 if (radix == 10) 72 return intToByteList(i); byte buf[] = new byte[33]; 74 boolean negative = (i < 0); 75 int charPos = 32; 76 if (!negative) { 77 i = -i; 78 } 79 while (i <= -radix) { 80 buf[charPos--] = digits[-(i % radix)]; 81 i = i / radix; 82 } 83 buf[charPos] = digits[-i]; 84 if (negative) { 85 buf[--charPos] = '-'; 86 } 87 return new ByteList(buf, charPos, (33 - charPos)); 88 } 89 90 98 public static final ByteList longToByteList(long i) { 99 if (i == Long.MIN_VALUE) 100 return new ByteList((byte[])MIN_LONG_BYTE_ARRAY.clone(),false); 101 if (i <= Integer.MAX_VALUE && i >= Integer.MIN_VALUE) 103 return intToByteList((int)i); 104 int size = (i < 0) ? arraySize(-i) + 1 : arraySize(i); 105 byte[] buf = new byte[size]; 106 getCharBytes(i, size, buf); 107 return new ByteList(buf,false); 108 } 109 110 public static final ByteList longToByteList(long i, int radix) { 111 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) 112 radix = 10; 113 if (radix == 10) 114 return longToByteList(i); byte[] buf = new byte[65]; 116 int charPos = 64; 117 boolean negative = (i < 0); 118 if (!negative) { 119 i = -i; 120 } 121 while (i <= -radix) { 122 buf[charPos--] = digits[(int)(-(i % radix))]; 123 i = i / radix; 124 } 125 buf[charPos] = digits[(int)(-i)]; 126 if (negative) { 127 buf[--charPos] = '-'; 128 } 129 return new ByteList(buf, charPos, (65 - charPos)); 130 } 131 132 public static final byte[] intToCharBytes(int i) { 133 if (i == Integer.MIN_VALUE) 134 return (byte[])MIN_INT_BYTE_ARRAY.clone(); 135 int size = (i < 0) ? arraySize(-i) + 1 : arraySize(i); 136 byte[] buf = new byte[size]; 137 getCharBytes(i, size, buf); 138 return buf; 139 } 140 141 public static final byte[] longToCharBytes(long i) { 142 int size = (i < 0) ? arraySize(-i) + 1 : arraySize(i); 145 byte[] buf = new byte[size]; 146 getCharBytes(i, size, buf); 147 return buf; 148 } 149 public static final char[] longToChars(long i) { 150 int size = (i < 0) ? arraySize(-i) + 1 : arraySize(i); 153 char[] buf = new char[size]; 154 getChars(i, size, buf); 155 return buf; 156 } 157 158 167 public static final void getCharBytes(int i, int index, byte[] buf) { 168 int q, r; 169 int charPos = index; 170 byte sign = 0; 171 172 if (i < 0) { 173 sign = '-'; 174 i = -i; 175 } 176 177 while (i >= 65536) { 179 q = i / 100; 180 r = i - ((q << 6) + (q << 5) + (q << 2)); 182 i = q; 183 buf [--charPos] = DigitOnes[r]; 184 buf [--charPos] = DigitTens[r]; 185 } 186 187 for (;;) { 190 q = (i * 52429) >>> (16+3); 191 r = i - ((q << 3) + (q << 1)); buf [--charPos] = digits[r]; 193 i = q; 194 if (i == 0) break; 195 } 196 if (sign != 0) { 197 buf [--charPos] = sign; 198 } 199 } 200 201 210 public static final void getCharBytes(long i, int index, byte[] buf) { 211 long q; 212 int r; 213 int charPos = index; 214 byte sign = 0; 215 216 if (i < 0) { 217 sign = '-'; 218 i = -i; 219 } 220 221 while (i > Integer.MAX_VALUE) { 223 q = i / 100; 224 r = (int)(i - ((q << 6) + (q << 5) + (q << 2))); 226 i = q; 227 buf[--charPos] = DigitOnes[r]; 228 buf[--charPos] = DigitTens[r]; 229 } 230 231 int q2; 233 int i2 = (int)i; 234 while (i2 >= 65536) { 235 q2 = i2 / 100; 236 r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); 238 i2 = q2; 239 buf[--charPos] = DigitOnes[r]; 240 buf[--charPos] = DigitTens[r]; 241 } 242 243 for (;;) { 246 q2 = (i2 * 52429) >>> (16+3); 247 r = i2 - ((q2 << 3) + (q2 << 1)); buf[--charPos] = digits[r]; 249 i2 = q2; 250 if (i2 == 0) break; 251 } 252 if (sign != 0) { 253 buf[--charPos] = sign; 254 } 255 } 256 public static final void getChars(long i, int index, char[] buf) { 257 long q; 258 int r; 259 int charPos = index; 260 char sign = 0; 261 262 if (i < 0) { 263 sign = '-'; 264 i = -i; 265 } 266 267 while (i > Integer.MAX_VALUE) { 269 q = i / 100; 270 r = (int)(i - ((q << 6) + (q << 5) + (q << 2))); 272 i = q; 273 buf[--charPos] = cDigitOnes[r]; 274 buf[--charPos] = cDigitTens[r]; 275 } 276 277 int q2; 279 int i2 = (int)i; 280 while (i2 >= 65536) { 281 q2 = i2 / 100; 282 r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); 284 i2 = q2; 285 buf[--charPos] = cDigitOnes[r]; 286 buf[--charPos] = cDigitTens[r]; 287 } 288 289 for (;;) { 292 q2 = (i2 * 52429) >>> (16+3); 293 r = i2 - ((q2 << 3) + (q2 << 1)); buf[--charPos] = cdigits[r]; 295 i2 = q2; 296 if (i2 == 0) break; 297 } 298 if (sign != 0) { 299 buf[--charPos] = sign; 300 } 301 } 302 303 304 309 public static final int arraySize(long x) { 310 long p = 10; 311 for (int i=1; i<19; i++) { 312 if (x < p) 313 return i; 314 p = 10*p; 315 } 316 return 19; 317 } 318 323 public static final int arraySize(int x) { 324 for (int i=0; ; i++) 325 if (x <= sizeTable[i]) 326 return i+1; 327 } 328 public static final byte[] intToBinaryBytes(int i) { 331 return intToUnsignedBytes(i, 1); 332 } 333 public static final byte[] intToOctalBytes(int i) { 334 return intToUnsignedBytes(i, 3); 335 } 336 public static final byte[] intToHexBytes(int i) { 337 return intToUnsignedBytes(i, 4); 338 } 339 340 public static final ByteList intToBinaryByteList(int i) { 341 return new ByteList(intToUnsignedBytes(i, 1)); 342 } 343 public static final ByteList intToOctalByteList(int i) { 344 return new ByteList(intToUnsignedBytes(i, 3)); 345 } 346 public static final ByteList intToHexByteList(int i) { 347 return new ByteList(intToUnsignedBytes(i, 4)); 348 } 349 350 public static final byte[] longToBinaryBytes(long i) { 351 return longToUnsignedBytes(i, 1); 352 } 353 public static final byte[] longToOctalBytes(long i) { 354 return longToUnsignedBytes(i, 3); 355 } 356 public static final byte[] longToHexBytes(long i) { 357 return longToUnsignedBytes(i, 4); 358 } 359 360 public static final ByteList longToBinaryByteList(long i) { 361 return new ByteList(longToUnsignedBytes(i, 1)); 362 } 363 public static final ByteList longToOctalByteList(long i) { 364 return new ByteList(longToUnsignedBytes(i, 3)); 365 } 366 public static final ByteList longToHexByteList(long i) { 367 return new ByteList(longToUnsignedBytes(i, 4)); 368 } 369 373 public static final byte[] intToRawUnsignedBytes(int i, int shift) { 374 byte[] buf = new byte[32]; 375 int charPos = 32; 376 int radix = 1 << shift; 377 int mask = radix - 1; 378 do { 379 buf[--charPos] = digits[i & mask]; 380 i >>>= shift; 381 } while (i != 0); 382 return buf; 383 } 384 388 public static final byte[] intToUnsignedBytes(int i, int shift) { 389 byte[] buf = new byte[32]; 390 int charPos = 32; 391 int radix = 1 << shift; 392 int mask = radix - 1; 393 do { 394 buf[--charPos] = digits[i & mask]; 395 i >>>= shift; 396 } while (i != 0); 397 int length = 32 - charPos; 398 byte[] result = new byte[length]; 399 System.arraycopy(buf,charPos,result,0,length); 400 return result; 401 } 402 403 407 public static final byte[] longToRawUnsignedBytes(long i, int shift) { 408 byte[] buf = new byte[64]; 409 int charPos = 64; 410 int radix = 1 << shift; 411 long mask = radix - 1; 412 do { 413 buf[--charPos] = digits[(int)(i & mask)]; 414 i >>>= shift; 415 } while (i != 0); 416 return buf; 417 } 418 422 public static final byte[] longToUnsignedBytes(long i, int shift) { 423 byte[] buf = new byte[64]; 424 int charPos = 64; 425 int radix = 1 << shift; 426 long mask = radix - 1; 427 do { 428 buf[--charPos] = digits[(int)(i & mask)]; 429 i >>>= shift; 430 } while (i != 0); 431 int length = 64 - charPos; 432 byte[] result = new byte[length]; 433 System.arraycopy(buf,charPos,result,0,length); 434 return result; 435 } 436 437 452 public static final long byteListToLong(ByteList bytes, int base, boolean raise) { 453 return byteArrayToLong(bytes.unsafeBytes(),bytes.length(),base,raise); 454 } 455 public static final long byteListToLong(ByteList bytes, int base) { 456 return byteArrayToLong(bytes.unsafeBytes(),bytes.length(),base,false); 457 } 458 public static final long byteListToLong(ByteList bytes) { 460 return byteArrayToLong(bytes.unsafeBytes(),bytes.length(),10,false); 461 } 462 477 public static final BigInteger byteListToBigInteger(ByteList bytes, int base, boolean raise) { 478 return byteArrayToBigInteger(bytes.unsafeBytes(),bytes.length(),base,raise); 479 } 480 public static final BigInteger byteListToBigInteger(ByteList bytes, int base) { 481 return byteArrayToBigInteger(bytes.unsafeBytes(),bytes.length(),base,false); 482 } 483 public static final BigInteger byteListToBigInteger(ByteList bytes) { 485 return byteArrayToBigInteger(bytes.unsafeBytes(),bytes.length(),10,false); 486 } 487 502 public static final long byteArrayToLong(byte[] bytes, int buflen, int base, boolean strict) { 503 final int SCOMPLETE = 0; 504 final int SBEGIN = 1; 505 final int SSIGN = 2; 506 final int SZERO = 3; 507 final int SPOST_SIGN = 4; 508 final int SDIGITS = 5; 509 final int SDIGIT = 6; 510 final int SDIGIT_STRICT = 7; 511 final int SDIGIT_USC = 8; 512 final int SEOD_STRICT = 13; 513 final int SEOF = 14; 514 final int SERR_NOT_STRICT = 17; 515 final int SERR_TOO_BIG = 18; 516 final int FLAG_NEGATIVE = 1 << 0; 517 final int FLAG_DIGIT = 1 << 1; 518 final int FLAG_UNDERSCORE = 1 << 2; 519 final int FLAG_WHITESPACE = 1 << 3; 520 521 if (bytes == null) { 522 throw new IllegalArgumentException ("null bytes"); 523 } 524 if (buflen < 0 || buflen > bytes.length) { 525 throw new IllegalArgumentException ("invalid buflen specified"); 526 } 527 int radix = base == 0 ? 10 : base; 528 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { 529 throw new IllegalArgumentException ("illegal radix " + radix); 530 } 531 if (buflen == 0) { 532 throw new InvalidIntegerException(); 533 } 534 int i = 0; 535 byte ival; 536 int flags = 0; 537 long limit = -Long.MAX_VALUE; 538 long result = 0; 539 long multmin = 0; 540 int digit; 541 int state = SBEGIN; 542 while (state != SCOMPLETE) { 543 states: 544 switch(state) { 545 case SBEGIN: 546 if (strict) { 547 for (; i < buflen && bytes[i] <= ' '; i++) ; 548 } else { 549 for (; i < buflen && ((ival = bytes[i]) <= ' ' || ival == '_'); i++) ; 550 } 551 state = i < buflen ? SSIGN : SEOF; 552 break; 553 case SSIGN: 554 switch(bytes[i]) { 555 case '-': 556 flags |= FLAG_NEGATIVE; 557 limit = Long.MIN_VALUE; 558 case '+': 559 if (++i >= buflen) { 560 state = SEOF; 561 } else if (bytes[i] == '0') { 562 state = SZERO; 563 } else { 564 state = SPOST_SIGN; 565 } 566 break states; 567 case '0': 568 state = SZERO; 569 break states; 570 default: 571 state = SDIGITS; 572 break states; 573 } 574 case SZERO: 575 if (++i >= buflen) { 576 state = SCOMPLETE; 577 break; 578 } 579 switch (bytes[i]) { 580 case 'x': 581 case 'X': 582 if (base == 0 || base == 16) { 583 radix = 16; 584 state = ++i >= buflen ? SEOF : SPOST_SIGN; 585 } else { 586 state = SDIGITS; 587 } 588 break states; 589 case 'b': 590 case 'B': 591 if (base == 0 || base == 2) { 592 radix = 2; 593 state = ++i >= buflen ? SEOF : SPOST_SIGN; 594 } else { 595 state = SDIGITS; 596 } 597 break states; 598 default: 599 if (base == 0 || base == 8) { 600 radix = 8; 601 } 602 flags |= FLAG_DIGIT; 603 state = SDIGITS; 604 break states; 605 } 606 case SPOST_SIGN: 607 if (strict) { 608 int ibefore = i; 609 for (; i < buflen && bytes[i] <= ' '; i++) ; 610 if (ibefore != i) { 611 flags |= FLAG_WHITESPACE; 614 } 615 } else { 616 for ( ; i < buflen && ((ival = bytes[i]) <= ' ' || ival == '_'); i++) { 617 if (ival == '_') { 618 if ((flags & FLAG_WHITESPACE) != 0) { 619 throw new InvalidIntegerException(); 620 } 621 flags |= FLAG_UNDERSCORE; 622 } else { 623 if ((flags & FLAG_UNDERSCORE) != 0) { 624 throw new InvalidIntegerException(); 625 } 626 flags |= FLAG_WHITESPACE; 627 } 628 } 629 } 630 state = i < buflen ? SDIGITS : SEOF; 631 break; 632 case SDIGITS: 633 digit = Character.digit((char) bytes[i],radix); 634 if (digit < 0) { 635 state = strict ? SEOD_STRICT : SEOF; 636 break; 637 } 638 result = -digit; 639 if (++i >= buflen) { 640 state = SCOMPLETE; 641 break; 642 } 643 multmin = limit / radix; 644 flags = (flags | FLAG_DIGIT) & ~FLAG_UNDERSCORE; 645 state = strict ? SDIGIT_STRICT : SDIGIT; 646 break; 647 648 case SDIGIT: 649 while ((digit = Character.digit((char) bytes[i],radix)) >= 0) { 650 if (result < multmin || ((result *= radix) < limit + digit)) { 651 state = SERR_TOO_BIG; 652 break states; 653 } 654 result -= digit; 655 if (++i >= buflen) { 656 state = SCOMPLETE; 657 break states; 658 } 659 } 660 state = bytes[i++] == '_' ? SDIGIT_USC : SEOF; 661 break; 662 case SDIGIT_USC: 663 for ( ; i < buflen && bytes[i] == '_'; i++) ; 664 state = i < buflen ? SDIGIT : SEOF; 665 break; 666 667 case SDIGIT_STRICT: 668 while ((digit = Character.digit((char) bytes[i],radix)) >= 0) { 669 if (result < multmin || ((result *= radix) < limit + digit)) { 670 state = SERR_TOO_BIG; 671 break states; 672 } 673 result -= digit; 674 if (++i >= buflen) { 675 state = SCOMPLETE; 676 break states; 677 } 678 flags &= ~FLAG_UNDERSCORE; 679 } 680 if (bytes[i] == '_') { 681 if ((flags & (FLAG_UNDERSCORE | FLAG_WHITESPACE)) != 0) { 682 state = SERR_NOT_STRICT; 683 break; 684 } 685 flags |= FLAG_UNDERSCORE; 686 state = ++i >= buflen ? SEOD_STRICT : SDIGIT_STRICT; 687 } else { 688 state = SEOD_STRICT; 689 } 690 break; 691 692 case SEOD_STRICT: 693 if ((flags & FLAG_UNDERSCORE)!= 0) { 694 state = SERR_NOT_STRICT; 695 break; 696 } 697 for ( ; i < buflen && bytes[i] <= ' '; i++ ); 698 state = i < buflen ? SERR_NOT_STRICT : SCOMPLETE; 699 break; 700 701 case SEOF: 702 if ((flags & FLAG_DIGIT) == 0) { 703 throw new InvalidIntegerException("no digits supplied"); 704 } 705 state = SCOMPLETE; 706 break; 707 708 case SERR_TOO_BIG: 709 throw new NumberTooLargeException("can't convert to long"); 710 711 case SERR_NOT_STRICT: 712 throw new InvalidIntegerException("does not meet strict criteria"); 713 714 } } if ((flags & FLAG_NEGATIVE) == 0) { 717 return -result; 718 } else { 719 return result; 720 } 721 } 722 723 738 public static final BigInteger byteArrayToBigInteger(byte[] bytes, int buflen, int base, boolean strict) { 739 final int SCOMPLETE = 0; 740 final int SBEGIN = 1; 741 final int SSIGN = 2; 742 final int SZERO = 3; 743 final int SPOST_SIGN = 4; 744 final int SDIGITS = 5; 745 final int SDIGIT = 6; 746 final int SDIGIT_STRICT = 7; 747 final int SDIGIT_USC = 8; 748 final int SEOD_STRICT = 13; 749 final int SEOF = 14; 750 final int SERR_NOT_STRICT = 17; 751 final int FLAG_NEGATIVE = 1 << 0; 752 final int FLAG_DIGIT = 1 << 1; 753 final int FLAG_UNDERSCORE = 1 << 2; 754 final int FLAG_WHITESPACE = 1 << 3; 755 756 if (bytes == null) { 757 throw new IllegalArgumentException ("null bytes"); 758 } 759 if (buflen < 0 || buflen > bytes.length) { 760 throw new IllegalArgumentException ("invalid buflen specified"); 761 } 762 int radix = base == 0 ? 10 : base; 763 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { 764 throw new IllegalArgumentException ("illegal radix " + radix); 765 } 766 if (buflen == 0) { 767 throw new InvalidIntegerException(); 768 } 769 int i = 0; 770 byte ival; 771 int flags = 0; 772 int digit; 773 int offset = 0; 774 char[] chars = null; 775 int state = SBEGIN; 776 while (state != SCOMPLETE) { 777 states: 778 switch(state) { 779 case SBEGIN: 780 if (strict) { 781 for (; i < buflen && bytes[i] <= ' '; i++) ; 782 } else { 783 for (; i < buflen && ((ival = bytes[i]) <= ' ' || ival == '_'); i++) ; 784 } 785 state = i < buflen ? SSIGN : SEOF; 786 break; 787 case SSIGN: 788 switch(bytes[i]) { 789 case '-': 790 flags |= FLAG_NEGATIVE; 791 case '+': 792 if (++i >= buflen) { 793 state = SEOF; 794 } else if (bytes[i] == '0') { 795 state = SZERO; 796 } else { 797 state = SPOST_SIGN; 798 } 799 break states; 800 case '0': 801 state = SZERO; 802 break states; 803 default: 804 state = SDIGITS; 805 break states; 806 } 807 case SZERO: 808 if (++i >= buflen) { 809 state = SCOMPLETE; 810 break; 811 } 812 switch (bytes[i]) { 813 case 'x': 814 case 'X': 815 if (base == 0 || base == 16) { 816 radix = 16; 817 state = ++i >= buflen ? SEOF : SPOST_SIGN; 818 } else { 819 state = SDIGITS; 820 } 821 break states; 822 case 'b': 823 case 'B': 824 if (base == 0 || base == 2) { 825 radix = 2; 826 state = ++i >= buflen ? SEOF : SPOST_SIGN; 827 } else { 828 state = SDIGITS; 829 } 830 break states; 831 default: 832 if (base == 0 || base == 8) { 833 radix = 8; 834 } 835 flags |= FLAG_DIGIT; 836 state = SDIGITS; 837 break states; 838 } 839 case SPOST_SIGN: 840 if (strict) { 841 int ibefore = i; 842 for (; i < buflen && bytes[i] <= ' '; i++) ; 843 if (ibefore != i) { 844 flags |= FLAG_WHITESPACE; 847 } 848 } else { 849 for ( ; i < buflen && ((ival = bytes[i]) <= ' ' || ival == '_'); i++) { 850 if (ival == '_') { 851 if ((flags & FLAG_WHITESPACE) != 0) { 852 throw new InvalidIntegerException(); 853 } 854 flags |= FLAG_UNDERSCORE; 855 } else { 856 if ((flags & FLAG_UNDERSCORE) != 0) { 857 throw new InvalidIntegerException(); 858 } 859 flags |= FLAG_WHITESPACE; 860 } 861 } 862 } 863 state = i < buflen ? SDIGITS : SEOF; 864 break; 865 case SDIGITS: 866 digit = Character.digit((char) bytes[i],radix); 867 if (digit < 0) { 868 state = strict ? SEOD_STRICT : SEOF; 869 break; 870 } 871 if ((flags & FLAG_NEGATIVE) == 0) { 872 chars = new char[buflen - i]; 873 chars[0] = (char)bytes[i]; 874 offset = 1; 875 } else { 876 chars = new char[buflen - i + 1]; 877 chars[0] = '-'; 878 chars[1] = (char)bytes[i]; 879 offset = 2; 880 } 881 if (++i >= buflen) { 882 state = SCOMPLETE; 883 break; 884 } 885 flags = (flags | FLAG_DIGIT) & ~FLAG_UNDERSCORE; 886 state = strict ? SDIGIT_STRICT : SDIGIT; 887 break; 888 889 case SDIGIT: 890 while ((digit = Character.digit((char) bytes[i],radix)) >= 0) { 891 chars[offset++] = (char)bytes[i]; 892 if (++i >= buflen) { 893 state = SCOMPLETE; 894 break states; 895 } 896 } 897 state = bytes[i++] == '_' ? SDIGIT_USC : SEOF; 898 break; 899 case SDIGIT_USC: 900 for ( ; i < buflen && bytes[i] == '_'; i++) ; 901 state = i < buflen ? SDIGIT : SEOF; 902 break; 903 904 case SDIGIT_STRICT: 905 while ((digit = Character.digit((char)bytes[i],radix)) >= 0) { 906 chars[offset++] = (char)bytes[i]; 907 if (++i >= buflen) { 908 state = SCOMPLETE; 909 break states; 910 } 911 flags &= ~FLAG_UNDERSCORE; 912 } 913 if (bytes[i] == '_') { 914 if ((flags & (FLAG_UNDERSCORE | FLAG_WHITESPACE)) != 0) { 915 state = SERR_NOT_STRICT; 916 break; 917 } 918 flags |= FLAG_UNDERSCORE; 919 state = ++i >= buflen ? SEOD_STRICT : SDIGIT_STRICT; 920 } else { 921 state = SEOD_STRICT; 922 } 923 break; 924 925 case SEOD_STRICT: 926 if ((flags & FLAG_UNDERSCORE)!= 0) { 927 state = SERR_NOT_STRICT; 928 break; 929 } 930 for ( ; i < buflen && bytes[i] <= ' '; i++ ); 931 state = i < buflen ? SERR_NOT_STRICT : SCOMPLETE; 932 break; 933 934 case SEOF: 935 if ((flags & FLAG_DIGIT) == 0) { 936 throw new InvalidIntegerException("no digits supplied"); 937 } 938 state = SCOMPLETE; 939 break; 940 941 case SERR_NOT_STRICT: 942 throw new InvalidIntegerException("does not meet strict criteria"); 943 944 } } if (chars == null) { return BIG_INT_ZERO; 948 } else { 949 return new BigInteger (new String (chars,0,offset),radix); 950 } 951 } 952 953 public static final int skipLeadingWhitespace(byte[] bytes){ 956 int length = bytes.length; 957 int start = 0; 958 for ( ; start < length && bytes[start] <= ' '; start++) ; 959 return start; 960 } 961 public static final int skipTrailingWhitespace(byte[] bytes) { 962 int stop = bytes.length - 1; 963 for ( ; stop >= 0 && bytes[stop] <= ' '; stop-- ) ; 964 return stop + 1; 965 } 966 974 public static final byte[] trim (byte[] bytes) { 975 if (bytes.length == 0) 976 return bytes; 977 int start = skipLeadingWhitespace(bytes); 978 if (start >= bytes.length) { 979 return EMPTY_BYTES; 980 } 981 int stop = skipTrailingWhitespace(bytes); 982 int length = stop - start; 983 if (length == bytes.length) 984 return bytes; 985 byte[] trimmed = new byte[length]; 986 System.arraycopy(bytes,0,trimmed,0,length); 987 return trimmed; 988 } 989 1001 public static final byte[] delete(byte[] bytes, int pos, boolean copy) { 1002 int buflen = bytes.length; 1003 int newlen = buflen - 1; 1004 if (pos < 0 || pos > newlen) { 1005 throw new IllegalArgumentException ("illegal position for delete"); 1006 } 1007 int src = pos + 1; 1008 if (copy) { 1009 if (newlen == 0) { 1010 return EMPTY_BYTES; 1011 } 1012 byte[] newbytes = new byte[newlen]; 1013 if (pos == 0) { 1014 System.arraycopy(bytes,1,newbytes,0,newlen); 1015 } else { 1016 System.arraycopy(bytes,0,newbytes,0,pos); 1017 System.arraycopy(bytes,src,newbytes,pos,newlen-pos); 1018 } 1019 return newbytes; 1020 } else { 1021 if (newlen > 0) { 1022 System.arraycopy(bytes,src,bytes,pos,buflen-src); 1023 bytes[newlen] = 0; 1024 } else { 1025 bytes[newlen-1] = 0; 1026 } 1027 return bytes; 1028 } 1029 } 1030 public static final byte[] delete(byte[] bytes, int pos, int length, boolean copy) { 1031 if (length < 0) { 1032 throw new IllegalArgumentException ("illegal length for delete"); 1033 } 1034 int buflen = bytes.length; 1035 if (length == 0 || buflen == 0 ) { 1036 return bytes; 1037 } 1038 int newlen = buflen - length; 1039 int newpos = pos + length; 1040 if (pos < 0 || newpos > buflen) { 1041 throw new IllegalArgumentException ("illegal position for delete"); 1042 } 1043 if (copy) { 1044 if (newlen == 0) { 1045 return EMPTY_BYTES; 1046 } 1047 byte[] newbytes = new byte[newlen]; 1048 if (pos == 0) { 1049 System.arraycopy(bytes,length,newbytes,0,newlen); 1050 } else if (pos == newlen) { 1051 System.arraycopy(bytes,0,newbytes,0,newlen); 1052 } else { 1053 System.arraycopy(bytes,0,newbytes,0,pos); 1054 System.arraycopy(bytes,newpos,newbytes,pos,buflen-newpos); 1055 } 1056 return newbytes; 1057 } else { 1058 if (newlen > 0) { 1059 System.arraycopy(bytes,newpos,bytes,pos,buflen-newpos); 1060 } 1061 fill(bytes,newlen,buflen-newlen,(byte)0); 1062 return bytes; 1063 } 1064 } 1065 1076 public static final byte[] insert(byte[] bytes, int pos, byte value, boolean copy) { 1077 int buflen = bytes.length; 1078 if (pos < 0 || pos > buflen) { 1079 throw new IllegalArgumentException ("illegal position for insert"); 1080 } 1081 if (copy) { 1082 byte[] newbytes = new byte[buflen+1]; 1083 if (pos == 0) { 1084 System.arraycopy(bytes,0,newbytes,1,buflen); 1085 newbytes[0] = value; 1086 } else if (pos == buflen) { 1087 System.arraycopy(bytes,0,newbytes,0,buflen); 1088 newbytes[buflen] = value; 1089 } else { 1090 System.arraycopy(bytes,0,newbytes,0,pos); 1091 System.arraycopy(bytes,pos,newbytes,pos+1,buflen-pos); 1092 newbytes[pos] = value; 1093 } 1094 return newbytes; 1095 } else { 1096 if (pos == buflen) { 1097 throw new IllegalArgumentException ("illegal position for insert with no copy"); 1098 } 1099 if (pos > buflen - 1) { 1100 System.arraycopy(bytes,pos,bytes,pos+1,buflen-pos-1); 1101 } 1102 bytes[pos] = value; 1103 return bytes; 1104 } 1105 } 1106 1118 public static final byte[] insert(byte[] bytes, int pos, byte[] value, boolean copy) { 1119 int buflen = bytes.length; 1120 if (pos < 0 || pos > buflen) { 1121 throw new IllegalArgumentException ("illegal position for insert"); 1122 } 1123 int vlen = value.length; 1124 if (copy) { 1125 int newlen = buflen + vlen; 1126 byte[] newbytes = new byte[newlen]; 1127 if (pos == 0) { 1128 System.arraycopy(value,0,newbytes,0,vlen); 1129 System.arraycopy(bytes,0,newbytes,vlen,buflen); 1130 } else if (pos == buflen) { 1131 System.arraycopy(bytes,0,newbytes,0,buflen); 1132 System.arraycopy(value,0,newbytes,buflen,vlen); 1133 } else { 1134 System.arraycopy(bytes,0,newbytes,0,pos); 1135 System.arraycopy(value,0,newbytes,pos,vlen); 1136 System.arraycopy(bytes,pos,newbytes,pos+vlen,buflen-pos); 1137 } 1138 return newbytes; 1139 } else { 1140 int displace = pos + vlen; 1141 if (displace > buflen) { 1142 throw new IllegalArgumentException ("inserted array won't fit in target array"); 1143 } 1144 if (pos == 0) { 1145 System.arraycopy(bytes,0,bytes,vlen,buflen-vlen); 1146 System.arraycopy(value,0,bytes,0,vlen); 1147 } else if (displace == buflen) { 1148 System.arraycopy(value,0,bytes,pos,vlen); 1149 } else { 1150 System.arraycopy(bytes,pos,bytes,displace,buflen-displace); 1151 System.arraycopy(value,0,bytes,pos,vlen); 1152 } 1153 return bytes; 1154 } 1155 1156 } 1157 public static final byte[] append(byte[] bytes, byte value) { 1158 int buflen = bytes.length; 1159 byte[] newbytes = new byte[buflen + 1]; 1160 System.arraycopy(bytes,0,newbytes,0,buflen); 1161 bytes[buflen] = value; 1162 return bytes; 1163 } 1164 1175 public static final byte[] fill(byte[] bytes, int pos, int length, byte value) { 1176 if (length < 0) { 1177 throw new IllegalArgumentException ("illegal length for fill"); 1178 } 1179 int buflen = bytes.length; 1180 int stop = pos + length; 1181 if (stop > buflen) 1182 stop = buflen; 1183 for ( ; pos < stop; pos++) { 1184 bytes[pos] = value; 1185 } 1186 return bytes; 1187 } 1188 1194 public static final byte[] copy(byte[] bytes) { 1195 int buflen = bytes.length; 1196 if (buflen == 0) 1197 return bytes; 1198 byte[] newbytes = new byte[buflen]; 1199 System.arraycopy(bytes,0,newbytes,0,buflen); 1200 return newbytes; 1201 } 1202 private static final Long LONG_ZERO = new Long (0); 1203 1204 private static final BigInteger BIG_INT_ZERO = BigInteger.valueOf(0L); 1205 1206 private static final byte[] EMPTY_BYTES = {}; 1207 1208 private static final byte[] MIN_INT_BYTE_ARRAY = { 1209 '-','2','1','4','7','4','8','3','6','4','8' 1210 }; 1211 private static final byte[] MIN_LONG_BYTE_ARRAY = { 1212 '-','9','2','2','3','3','7','2','0','3','6','8','5','4','7','7','5','8','0','8' 1213 }; 1214 private static final int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 1216 99999999, 999999999, Integer.MAX_VALUE }; 1217 1218 private static final byte[] digits = { 1219 '0' , '1' , '2' , '3' , '4' , '5' , 1220 '6' , '7' , '8' , '9' , 'a' , 'b' , 1221 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 1222 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 1223 'o' , 'p' , 'q' , 'r' , 's' , 't' , 1224 'u' , 'v' , 'w' , 'x' , 'y' , 'z' 1225 }; 1226 1227 private static final byte[] DigitTens = { 1228 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 1229 '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', 1230 '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', 1231 '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', 1232 '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', 1233 '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', 1234 '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', 1235 '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', 1236 '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', 1237 '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', 1238 } ; 1239 1240 private static final byte[] DigitOnes = { 1241 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1242 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1243 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1244 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1245 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1246 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1247 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1248 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1249 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1250 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1251 } ; 1252 1253 1254 private static final char[] cdigits = { 1255 '0' , '1' , '2' , '3' , '4' , '5' , 1256 '6' , '7' , '8' , '9' , 'a' , 'b' , 1257 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 1258 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 1259 'o' , 'p' , 'q' , 'r' , 's' , 't' , 1260 'u' , 'v' , 'w' , 'x' , 'y' , 'z' 1261 }; 1262 private static final char [] cDigitTens = { 1263 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 1264 '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', 1265 '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', 1266 '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', 1267 '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', 1268 '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', 1269 '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', 1270 '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', 1271 '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', 1272 '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', 1273 } ; 1274 1275 private static final char [] cDigitOnes = { 1276 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1277 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1278 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1279 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1280 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1281 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1282 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1283 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1284 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1285 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1286 } ; 1287 1288} 1289 | Popular Tags |