1 21 22 package org.apache.derby.iapi.services.io; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 26 import java.io.*; 27 28 37 38 public abstract class CompressedNumber { 39 40 public static final int MAX_INT_STORED_SIZE = 4; 42 43 public static final int MAX_LONG_STORED_SIZE = 8; 45 46 public static final int MAX_COMPRESSED_INT_ONE_BYTE = 0x3f; 48 49 public static final int MAX_COMPRESSED_INT_TWO_BYTES = 0x3fff; 51 52 53 65 public static final int writeInt(DataOutput out, int value) throws IOException { 66 67 if (value < 0) 68 throw new IOException(); 69 70 if (value <= 0x3f) { 71 72 out.writeByte(value); 73 return 1; 74 } 75 76 if (value <= 0x3fff) { 77 78 out.writeByte(0x40 | (value >>> 8)); 79 out.writeByte(value & 0xff); 80 return 2; 81 } 82 83 out.writeByte(((value >>> 24) | 0x80) & 0xff); 84 out.writeByte((value >>> 16) & 0xff); 85 out.writeByte((value >>> 8) & 0xff); 86 out.writeByte((value) & 0xff); 87 return 4; 88 } 89 90 94 public static final int writeInt(OutputStream out, int value) throws IOException { 95 96 if (value < 0) 97 throw new IOException(); 98 99 if (value <= 0x3f) { 100 101 out.write(value); 102 return 1; 103 } 104 105 if (value <= 0x3fff) { 106 107 out.write(0x40 | (value >>> 8)); 108 out.write(value & 0xff); 109 return 2; 110 } 111 112 out.write(((value >>> 24) | 0x80) & 0xff); 113 out.write((value >>> 16) & 0xff); 114 out.write((value >>> 8) & 0xff); 115 out.write((value) & 0xff); 116 return 4; 117 } 118 119 120 125 public static final int readInt(DataInput in) throws IOException { 126 127 int value = in.readUnsignedByte(); 128 129 if ((value & ~0x3f) == 0) 130 { 131 135 return(value); 137 } 138 else if ((value & 0x80) == 0) 139 { 140 142 if (SanityManager.DEBUG) 143 { 144 SanityManager.ASSERT((value & 0x40) == 0x40); 145 } 146 147 153 return(((value & 0x3f) << 8) | in.readUnsignedByte()); 154 } 155 else 156 { 157 159 if (SanityManager.DEBUG) 160 { 161 SanityManager.ASSERT((value & 0x80) == 0x80); 162 } 163 164 return( 171 ((value & 0x7f) << 24) | 172 (in.readUnsignedByte() << 16) | 173 (in.readUnsignedByte() << 8) | 174 (in.readUnsignedByte() )); 175 } 176 } 177 178 183 public static final int readInt(InputStream in) throws IOException { 184 185 int value = InputStreamUtil.readUnsignedByte(in); 186 187 if ((value & ~0x3f) == 0) 188 { 189 return(value); 190 } 191 else if ((value & 0x80) == 0) 192 { 193 return( 194 ((value & 0x3f) << 8) | InputStreamUtil.readUnsignedByte(in)); 195 } 196 else 197 { 198 return( 199 ((value & 0x7f) << 24) | 200 (InputStreamUtil.readUnsignedByte(in) << 16) | 201 (InputStreamUtil.readUnsignedByte(in) << 8) | 202 (InputStreamUtil.readUnsignedByte(in) )); 203 } 204 } 205 206 public static final int readInt( 207 byte[] data, 208 int offset) 209 { 210 int value = data[offset++]; 211 212 if ((value & ~0x3f) == 0) 213 { 214 218 return(value); 219 } 220 else if ((value & 0x80) == 0) 221 { 222 224 if (SanityManager.DEBUG) 225 { 226 SanityManager.ASSERT((value & 0x40) == 0x40); 227 } 228 229 235 return(((value & 0x3f) << 8) | (data[offset] & 0xff)); 236 } 237 else 238 { 239 241 if (SanityManager.DEBUG) 242 { 243 SanityManager.ASSERT((value & 0x80) == 0x80); 244 } 245 246 return( 253 ((value & 0x7f) << 24) | 254 ((data[offset++] & 0xff) << 16) | 255 ((data[offset++] & 0xff) << 8) | 256 ((data[offset] & 0xff) )); 257 } 258 } 259 260 283 public static final int readIntAndReturnIntPlusOverhead( 284 byte[] data, 285 int offset) 286 { 287 int value = data[offset]; 288 289 if ((value & ~0x3f) == 0) 290 { 291 295 return(value + 2); 297 } 298 else if ((value & 0x80) == 0) 299 { 300 302 if (SanityManager.DEBUG) 303 { 304 SanityManager.ASSERT((value & 0x40) == 0x40); 305 } 306 307 313 315 return((((value & 0x3f) << 8) | (data[offset + 1] & 0xff)) + 3); 316 } 317 else 318 { 319 321 if (SanityManager.DEBUG) 322 { 323 SanityManager.ASSERT((value & 0x80) == 0x80); 324 } 325 326 332 333 return( 335 (((value & 0x7f) << 24) | 336 ((data[offset + 1] & 0xff) << 16) | 337 ((data[offset + 2] & 0xff) << 8) | 338 (data[offset + 3] & 0xff)) + 5); 339 } 340 } 341 342 343 348 public static final int skipInt(DataInput in) throws IOException { 349 350 int value = in.readUnsignedByte(); 351 352 if ((value & 0x80) == 0x80) { 353 in.skipBytes(3); 354 return 4; 355 } 356 357 if ((value & 0x40) == 0x40) { 358 in.skipBytes(1); 359 return 2; 360 } 361 362 return 1; 363 } 364 365 370 public static final int skipInt(InputStream in) throws IOException { 371 372 int value = InputStreamUtil.readUnsignedByte(in); 373 374 int skipBytes = 0; 375 376 if ((value & 0x80) == 0x80) { 377 skipBytes = 3; 378 } 379 else if ((value & 0x40) == 0x40) { 380 skipBytes = 1; 381 } 382 383 if (skipBytes != 0) { 384 if (in.skip(skipBytes) != skipBytes) 385 throw new EOFException(); 386 } 387 388 389 return skipBytes + 1; 390 } 391 392 395 public static final int sizeInt(int value) { 396 if (value <= 0x3f) { 397 return 1; 398 } 399 if (value <= 0x3fff) { 400 return 2; 401 } 402 return 4; 403 } 404 405 418 public static final int writeLong(DataOutput out, long value) throws IOException { 419 420 if (value < 0) 421 throw new IOException(); 422 423 if (value <= 0x3fff) { 424 425 out.writeByte((int) ((value >>> 8) & 0xff)); 426 out.writeByte((int) ((value ) & 0xff)); 427 return 2; 428 } 429 430 if (value <= 0x3fffffff) { 431 432 out.writeByte((int) (((value >>> 24) | 0x40) & 0xff)); 433 out.writeByte((int) ( (value >>> 16) & 0xff)); 434 out.writeByte((int) ( (value >>> 8) & 0xff)); 435 out.writeByte((int) ( (value ) & 0xff)); 436 return 4; 437 } 438 439 out.writeByte((int) (((value >>> 56) | 0x80) & 0xff)); 440 out.writeByte((int) ( (value >>> 48) & 0xff)); 441 out.writeByte((int) ( (value >>> 40) & 0xff)); 442 out.writeByte((int) ( (value >>> 32) & 0xff)); 443 out.writeByte((int) ( (value >>> 24) & 0xff)); 444 out.writeByte((int) ( (value >>> 16) & 0xff)); 445 out.writeByte((int) ( (value >>> 8) & 0xff)); 446 out.writeByte((int) ( (value ) & 0xff)); 447 return 8; 448 } 449 454 public static final int writeLong(OutputStream out, long value) throws IOException { 455 456 if (value < 0) 457 throw new IOException(); 458 459 if (value <= 0x3fff) { 460 461 out.write((int) ((value >>> 8) & 0xff)); 462 out.write((int) ((value ) & 0xff)); 463 return 2; 464 } 465 466 if (value <= 0x3fffffff) { 467 468 out.write((int) (((value >>> 24) | 0x40) & 0xff)); 469 out.write((int) ( (value >>> 16) & 0xff)); 470 out.write((int) ( (value >>> 8) & 0xff)); 471 out.write((int) ( (value ) & 0xff)); 472 return 4; 473 } 474 475 out.write((int) (((value >>> 56) | 0x80) & 0xff)); 476 out.write((int) ( (value >>> 48) & 0xff)); 477 out.write((int) ( (value >>> 40) & 0xff)); 478 out.write((int) ( (value >>> 32) & 0xff)); 479 out.write((int) ( (value >>> 24) & 0xff)); 480 out.write((int) ( (value >>> 16) & 0xff)); 481 out.write((int) ( (value >>> 8) & 0xff)); 482 out.write((int) ( (value ) & 0xff)); 483 return 8; 484 } 485 486 491 public static final long readLong(DataInput in) throws IOException { 492 493 int int_value = in.readUnsignedByte(); 494 495 if ((int_value & ~0x3f) == 0) 496 { 497 500 return((int_value << 8) | in.readUnsignedByte()); 501 } 502 else if ((int_value & 0x80) == 0) 503 { 504 506 return( 507 ((int_value & 0x3f) << 24) | 508 (in.readUnsignedByte() << 16) | 509 (in.readUnsignedByte() << 8) | 510 (in.readUnsignedByte())); 511 } 512 else 513 { 514 return( 516 (((long) (int_value & 0x7f) ) << 56) | 517 (((long) in.readUnsignedByte()) << 48) | 518 (((long) in.readUnsignedByte()) << 40) | 519 (((long) in.readUnsignedByte()) << 32) | 520 (((long) in.readUnsignedByte()) << 24) | 521 (((long) in.readUnsignedByte()) << 16) | 522 (((long) in.readUnsignedByte()) << 8) | 523 (((long) in.readUnsignedByte()) )); 524 } 525 } 526 527 532 public static final long readLong(InputStream in) throws IOException { 533 534 int int_value = InputStreamUtil.readUnsignedByte(in); 535 536 if ((int_value & ~0x3f) == 0) 537 { 538 541 return((int_value << 8) | InputStreamUtil.readUnsignedByte(in)); 542 } 543 else if ((int_value & 0x80) == 0) 544 { 545 547 return( 548 ((int_value & 0x3f) << 24) | 549 (InputStreamUtil.readUnsignedByte(in) << 16) | 550 (InputStreamUtil.readUnsignedByte(in) << 8) | 551 (InputStreamUtil.readUnsignedByte(in) )); 552 553 } 554 else 555 { 556 long value = int_value; 558 559 return( 560 (((long) (value & 0x7f) ) << 56) | 561 (((long) InputStreamUtil.readUnsignedByte(in)) << 48) | 562 (((long) InputStreamUtil.readUnsignedByte(in)) << 40) | 563 (((long) InputStreamUtil.readUnsignedByte(in)) << 32) | 564 (((long) InputStreamUtil.readUnsignedByte(in)) << 24) | 565 (((long) InputStreamUtil.readUnsignedByte(in)) << 16) | 566 (((long) InputStreamUtil.readUnsignedByte(in)) << 8) | 567 (((long) InputStreamUtil.readUnsignedByte(in)) )); 568 } 569 } 570 571 public static final long readLong( 572 byte[] data, 573 int offset) 574 { 575 int int_value = data[offset++]; 576 577 if ((int_value & ~0x3f) == 0) 578 { 579 582 return((int_value << 8) | (data[offset] & 0xff)); 583 } 584 else if ((int_value & 0x80) == 0) 585 { 586 588 return( 589 ((int_value & 0x3f) << 24) | 590 ((data[offset++] & 0xff) << 16) | 591 ((data[offset++] & 0xff) << 8) | 592 ((data[offset] & 0xff) )); 593 594 } 595 else 596 { 597 return( 599 (((long) (int_value & 0x7f)) << 56) | 600 (((long) (data[offset++] & 0xff)) << 48) | 601 (((long) (data[offset++] & 0xff)) << 40) | 602 (((long) (data[offset++] & 0xff)) << 32) | 603 (((long) (data[offset++] & 0xff)) << 24) | 604 (((long) (data[offset++] & 0xff)) << 16) | 605 (((long) (data[offset++] & 0xff)) << 8) | 606 (((long) (data[offset] & 0xff)) )); 607 608 } 609 } 610 611 616 public static final int skipLong(DataInput in) throws IOException { 617 618 long value = in.readUnsignedByte(); 619 620 if ((value & 0x80) == 0x80) 621 { 622 in.skipBytes(7); 623 return 8; 624 } 625 626 627 if ((value & 0x40) == 0x40) 628 { 629 in.skipBytes(3); 630 return 4; 631 632 } 633 634 in.skipBytes(1); 635 return 2; 636 } 637 638 643 public static final int skipLong(InputStream in) throws IOException { 644 645 int value = InputStreamUtil.readUnsignedByte(in); 646 647 int skipBytes; 648 649 if ((value & 0x80) == 0x80) { 650 skipBytes = 7; 651 } 652 else if ((value & 0x40) == 0x40) { 653 skipBytes = 3; 654 } 655 else 656 skipBytes = 1; 657 658 if (in.skip(skipBytes) != skipBytes) 659 throw new EOFException(); 660 661 return skipBytes + 1; 662 } 663 664 public static final int sizeLong(long value) { 665 666 if (value <= 0x3fff) { 667 668 return 2; 669 } 670 671 if (value <= 0x3fffffff) { 672 return 4; 673 } 674 675 return 8; 676 } 677 678 681 private static byte[] holder = new byte[8]; 682 private static ArrayOutputStream aos = new ArrayOutputStream(holder); 683 private static DataOutput out = new DataOutputStream(aos); 684 685 private static ArrayInputStream ais = new ArrayInputStream(holder); 686 private static DataInput in = new DataInputStream(ais); 687 private static InputStream in_stream = ais; 688 689 690 private static short checkInt(int i, short oldLength) throws IOException { 691 692 aos.setPosition(0); 693 int length = CompressedNumber.writeInt(out, i); 694 if (length != oldLength) { 695 System.out.println("changing length to " + length + " at value " + i + " 0x" + Integer.toHexString(i)); 696 697 oldLength = (short) length; 698 } 699 700 int writtenBytes = aos.getPosition(); 701 if (writtenBytes != length) { 702 System.out.println("MISMATCH written bytes expected " + length + " got " + writtenBytes); 703 System.exit(1); 704 } 705 706 if (length != CompressedNumber.sizeInt(i)) { 707 System.out.println("MISMATCH sizeInt() bytes expected " + length + " got " + CompressedNumber.sizeInt(i)); 708 System.exit(1); 709 } 710 711 ais.setPosition(0); 712 int value = CompressedNumber.readInt(in); 713 if (value != i) { 714 System.out.println("MISMATCH value readInt(DataInput) expected " + i + " got " + value); 715 System.exit(1); 716 } 717 718 ais.setPosition(0); 719 value = ais.readCompressedInt(); 720 if (value != i) { 721 System.out.println("MISMATCH value readInt(DataInput) expected " + i + " got " + value); 722 System.exit(1); 723 } 724 725 ais.setPosition(0); 726 value = CompressedNumber.readInt(in_stream); 727 if (value != i) { 728 System.out.println("MISMATCH value in readInt(InputStream) expected " + i + " got " + value); 729 System.exit(1); 730 } 731 732 733 value = CompressedNumber.readInt(holder, 0); 734 if (value != i) { 735 System.out.println( 736 "MISMATCH frome readInt(byte[], offset) value expected " + 737 i + " got " + value); 738 System.exit(1); 739 } 740 741 ais.setPosition(0); 742 int skipLength = CompressedNumber.skipInt(in); 743 if (skipLength != length) { 744 System.out.println("MISMATCH skip length expected " + length + " got " + skipLength); 745 System.exit(1); 746 } 747 748 int value_plus_int_length = readIntAndReturnIntPlusOverhead(holder, 0); 749 if (value_plus_int_length != (length + i + 1)) { 750 System.out.println("MISMATCH readIntAndReturnIntPlusOverhead() return expected " + (length + i) + " got " + value_plus_int_length); 751 System.exit(1); 752 } 753 754 int skipPosition = ais.getPosition(); 755 if (skipPosition != length) { 756 System.out.println("MISMATCH skip position expected " + length + " got " + skipPosition); 757 System.exit(1); 758 } 759 760 return oldLength; 761 } 762 763 private static short checkLong(long i, short oldLength) throws IOException { 764 765 aos.setPosition(0); 766 int length = CompressedNumber.writeLong(out, i); 767 if (length != oldLength) { 768 System.out.println("changing length to " + length + " at value " + i + " 0x" + Long.toHexString(i)); 769 oldLength = (short) length; 770 } 771 772 int writtenBytes = aos.getPosition(); 773 if (writtenBytes != length) { 774 System.out.println("MISMATCH written bytes expected " + length + " got " + writtenBytes); 775 System.exit(1); 776 } 777 778 if (length != CompressedNumber.sizeLong(i)) { 779 System.out.println("MISMATCH sizeLong() bytes expected " + length + " got " + CompressedNumber.sizeLong(i)); 780 System.exit(1); 781 } 782 783 long value = CompressedNumber.readLong(holder, 0); 784 if (value != i) { 785 for (int j = 0; j < 8; j++) { 786 787 System.out.println(Integer.toHexString((int) holder[j])); 788 } 789 790 System.out.println( 791 "MISMATCH in readLong(byte[], offset) value expected " + 792 Long.toHexString(i) + " got " + value); 793 System.exit(1); 794 } 795 796 ais.setPosition(0); 797 value = CompressedNumber.readLong(in_stream); 798 if (value != i) { 799 for (int j = 0; j < 8; j++) { 800 801 System.out.println(Integer.toHexString((int) holder[j])); 802 } 803 System.out.println("MISMATCH value in readLong(InputStream) expected " + Long.toHexString(i) + " got " + value); 804 System.exit(1); 805 } 806 807 ais.setPosition(0); 808 value = ais.readCompressedLong(); 809 if (value != i) { 810 for (int j = 0; j < 8; j++) { 811 812 System.out.println(Integer.toHexString((int) holder[j])); 813 } 814 System.out.println("MISMATCH value in readLong(InputStream) expected " + Long.toHexString(i) + " got " + value); 815 System.exit(1); 816 } 817 818 819 ais.setPosition(0); 820 value = CompressedNumber.readLong(in); 821 if (value != i) { 822 for (int j = 0; j < 8; j++) { 823 824 System.out.println(Integer.toHexString((int) holder[j])); 825 } 826 System.out.println("MISMATCH value in readLong(DataInput) expected " + Long.toHexString(i) + " got " + value); 827 System.exit(1); 828 } 829 830 ais.setPosition(0); 831 int skipLength = CompressedNumber.skipLong(in); 832 if (skipLength != length) { 833 System.out.println("MISMATCH skip length expected " + length + " got " + skipLength); 834 System.exit(1); 835 } 836 837 int skipPosition = ais.getPosition(); 838 if (skipPosition != length) { 839 System.out.println("MISMATCH skip position expected " + length + " got " + skipPosition); 840 System.exit(1); 841 } 842 843 return oldLength; 844 } 845 846 public static void main(String [] args) throws IOException { 847 848 short oldLength = -1; 849 850 System.out.println("** Testing Int"); 851 852 oldLength = checkInt(0, oldLength); 853 oldLength = checkInt(1, oldLength); 854 oldLength = checkInt(2, oldLength); 855 856 oldLength = checkInt(0x3f - 4, oldLength); 857 oldLength = checkInt(0x3f - 3, oldLength); 858 oldLength = checkInt(0x3f - 2, oldLength); 859 oldLength = checkInt(0x3f - 1, oldLength); 860 oldLength = checkInt(0x3f , oldLength); 861 oldLength = checkInt(0x3f + 1, oldLength); 862 oldLength = checkInt(0x3f + 2, oldLength); 863 oldLength = checkInt(0x3f + 3, oldLength); 864 oldLength = checkInt(0x3f + 4, oldLength); 865 866 oldLength = checkInt(0x3f80 - 4, oldLength); 867 oldLength = checkInt(0x3f80 - 3, oldLength); 868 oldLength = checkInt(0x3f80 - 2, oldLength); 869 oldLength = checkInt(0x3f80 - 1, oldLength); 870 oldLength = checkInt(0x3f80 , oldLength); 871 oldLength = checkInt(0x3f80 + 1, oldLength); 872 oldLength = checkInt(0x3f80 + 2, oldLength); 873 oldLength = checkInt(0x3f80 + 3, oldLength); 874 oldLength = checkInt(0x3f80 + 4, oldLength); 875 876 oldLength = checkInt(0x3fff - 4, oldLength); 877 oldLength = checkInt(0x3fff - 3, oldLength); 878 oldLength = checkInt(0x3fff - 2, oldLength); 879 oldLength = checkInt(0x3fff - 1, oldLength); 880 oldLength = checkInt(0x3fff , oldLength); 881 oldLength = checkInt(0x3fff + 1, oldLength); 882 oldLength = checkInt(0x3fff + 2, oldLength); 883 oldLength = checkInt(0x3fff + 3, oldLength); 884 oldLength = checkInt(0x3fff + 4, oldLength); 885 886 oldLength = checkInt(Integer.MAX_VALUE - 4, oldLength); 887 oldLength = checkInt(Integer.MAX_VALUE - 3, oldLength); 888 oldLength = checkInt(Integer.MAX_VALUE - 2, oldLength); 889 oldLength = checkInt(Integer.MAX_VALUE - 1, oldLength); 890 oldLength = checkInt(Integer.MAX_VALUE , oldLength); 891 892 oldLength = -1; 893 for (int i = 0; i < 0xf0000; i++) 894 { 895 oldLength = checkInt(i, oldLength); 896 } 897 898 908 909 System.out.println("** Testing Long"); 910 911 oldLength = -1; 912 for (int i = 0; i < 0xf0000; i++) 913 { 914 oldLength = checkLong(i, oldLength); 915 } 916 917 oldLength = -1; 918 919 oldLength = checkLong(0, oldLength); 920 oldLength = checkLong(1, oldLength); 921 oldLength = checkLong(2, oldLength); 922 923 oldLength = checkLong(0x3fff - 2, oldLength); 924 oldLength = checkLong(0x3fff - 1, oldLength); 925 oldLength = checkLong(0x3fff , oldLength); 926 oldLength = checkLong(0x3fff + 1, oldLength); 927 oldLength = checkLong(0x3fff + 2, oldLength); 928 929 oldLength = checkLong(0x3fffffff - 4, oldLength); 930 oldLength = checkLong(0x3fffffff - 3, oldLength); 931 oldLength = checkLong(0x3fffffff - 2, oldLength); 932 oldLength = checkLong(0x3fffffff - 1, oldLength); 933 oldLength = checkLong(0x3fffffff , oldLength); 934 oldLength = checkLong(0x3fffffff + 1, oldLength); 935 oldLength = checkLong(0x3fffffff + 2, oldLength); 936 oldLength = checkLong(0x3fffffff + 3, oldLength); 937 oldLength = checkLong(0x3fffffff + 4, oldLength); 938 939 oldLength = checkLong(0x70000000 - 2, oldLength); 940 oldLength = checkLong(0x70000000 - 1, oldLength); 941 oldLength = checkLong(0x70000000 , oldLength); 942 oldLength = checkLong(0x70000000 + 1, oldLength); 943 oldLength = checkLong(0x70000000 + 2, oldLength); 944 945 946 oldLength = checkLong(Long.MAX_VALUE - 2, oldLength); 947 oldLength = checkLong(Long.MAX_VALUE - 1, oldLength); 948 oldLength = checkLong(Long.MAX_VALUE , oldLength); 949 950 951 } 952 } 954 | Popular Tags |