1 21 22 package org.apache.derby.impl.drda; 23 import org.apache.derby.iapi.services.sanity.SanityManager; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.ByteArrayOutputStream ; 27 import java.io.ByteArrayInputStream ; 28 import java.math.BigDecimal ; 29 30 92 class DDMReader 93 { 94 private final static int DEFAULT_BUFFER_SIZE = 32767; 95 private final static int MAX_MARKS_NESTING = 10; 96 private final static int NO_CODEPOINT = -1; 97 private final static int EMPTY_STACK = -1; 98 private final static boolean ADJUST_LENGTHS = true; 99 private final static boolean NO_ADJUST_LENGTHS = false; 100 private final static long MAX_EXTDTA_SIZE= Long.MAX_VALUE; 101 private static boolean internalTrace = true; 102 103 private static final int[][] tenRadixMagnitude = { 105 { 0x3b9aca00 }, { 0x0de0b6b3, 0xa7640000 }, { 0x033b2e3c, 0x9fd0803c, 0xe8000000 }, }; 109 110 private DRDAConnThread agent; 111 private CcsidManager ccsidManager; 112 113 private byte[] buffer; 115 private int pos; 116 private int count; 117 118 private int topDdmCollectionStack; 121 private long[] ddmCollectionLenStack; 123 124 private long ddmScalarLen; 126 127 private int dssLength; 129 130 private boolean dssIsContinued; 132 133 private boolean terminateChainOnErr; 134 135 private boolean dssIsChainedWithSameID; 137 138 private boolean dssIsChainedWithDiffID; 140 141 private int dssCorrelationID; 143 144 private int prevCorrelationID; 146 147 private int svrcod; 149 150 private DssTrace dssTrace; 152 153 private InputStream inputStream; 155 156 DDMReader (DRDAConnThread agent, DssTrace dssTrace) 158 { 159 buffer = new byte[DEFAULT_BUFFER_SIZE]; 160 ddmCollectionLenStack = new long[MAX_MARKS_NESTING]; 161 initialize(agent, dssTrace); 162 } 163 168 DDMReader(CcsidManager ccsidManager, InputStream inputStream) 169 { 170 buffer = new byte[DEFAULT_BUFFER_SIZE]; 171 ddmCollectionLenStack = new long[MAX_MARKS_NESTING]; 172 this.ccsidManager = ccsidManager; 173 this.inputStream = inputStream; 174 initialize(null, null); 175 internalTrace = false; 177 } 178 182 protected void initialize(InputStream inputStream) 183 { 184 this.inputStream = inputStream; 185 initialize(null, null); 186 } 187 188 192 protected void initialize(DRDAConnThread agent, DssTrace dssTrace) 193 { 194 this.agent = agent; 195 if (agent != null) 196 { 197 ccsidManager = agent.ccsidManager; 198 inputStream = agent.getInputStream(); 199 } 200 topDdmCollectionStack = EMPTY_STACK; 201 svrcod = 0; 202 pos = 0; 203 count = 0; 204 ddmScalarLen = 0; 205 dssLength = 0; 206 prevCorrelationID = DssConstants.CORRELATION_ID_UNKNOWN; 207 dssCorrelationID = DssConstants.CORRELATION_ID_UNKNOWN; 208 this.dssTrace = dssTrace; 209 } 210 211 protected boolean terminateChainOnErr() 212 { 213 return terminateChainOnErr; 214 } 215 216 221 protected boolean isChainedWithSameID() 222 { 223 return dssIsChainedWithSameID; 224 } 225 226 231 protected boolean isChainedWithDiffID() 232 { 233 return dssIsChainedWithDiffID; 234 } 235 236 241 protected long getDdmLength() 242 { 243 return ddmScalarLen; 244 } 245 246 251 protected boolean moreDdmData() 252 { 253 return ddmScalarLen > 0; 254 } 255 256 261 protected boolean moreDssData() 262 { 263 return dssLength > 0; 264 } 265 266 271 protected boolean moreData() 272 { 273 return (pos - count) > 0; 274 } 275 276 283 protected boolean isCmd() throws DRDAProtocolException, java.io.UnsupportedEncodingException 284 { 285 ensureALayerDataInBuffer(4); 286 String val = new String (buffer, 0, 4, NetworkServerControlImpl.DEFAULT_ENCODING); 287 return NetworkServerControlImpl.isCmd(val); 288 } 289 290 315 protected int readDssHeader () throws DRDAProtocolException 316 { 317 ensureALayerDataInBuffer (6); 318 319 dssLength = ((buffer[pos] & 0xff) << 8) + 321 ((buffer[pos + 1] & 0xff) << 0); 322 pos += 2; 323 if ((dssLength & DssConstants.CONTINUATION_BIT) == 325 DssConstants.CONTINUATION_BIT) 326 { 327 dssLength = DssConstants.MAX_DSS_LENGTH; 328 dssIsContinued = true; 329 } 330 else 331 { 332 dssIsContinued = false; 333 } 334 335 if (dssLength < 6) 336 agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_LESS_THAN_6, 337 DRDAProtocolException.NO_CODPNT_ARG); 338 339 343 if ((buffer[pos++] & 0xff) != DssConstants.DSS_ID) 344 agent.throwSyntaxrm(CodePoint.SYNERRCD_CBYTE_NOT_D0, 345 DRDAProtocolException.NO_CODPNT_ARG); 346 347 int gdsFormatter = buffer[pos++] & 0xff; 348 349 if (((gdsFormatter & 0x0F) != DssConstants.DSSFMT_RQSDSS) 350 &&((gdsFormatter & 0x0F) != DssConstants.DSSFMT_OBJDSS)) 351 { 352 agent.throwSyntaxrm(CodePoint.SYNERRCD_FBYTE_NOT_SUPPORTED, 353 DRDAProtocolException.NO_CODPNT_ARG); 354 } 355 356 if ((gdsFormatter & DssConstants.DSSCHAIN) == DssConstants.DSSCHAIN) 359 { if ((gdsFormatter & DssConstants.DSSCHAIN_SAME_ID) 361 == DssConstants.DSSCHAIN_SAME_ID) 362 { 363 dssIsChainedWithSameID = true; 364 dssIsChainedWithDiffID = false; 365 } 366 else 367 { 368 dssIsChainedWithSameID = false; 369 dssIsChainedWithDiffID = true; 370 } 371 if ((gdsFormatter & DssConstants.DSSCHAIN_ERROR_CONTINUE) 372 == DssConstants.DSSCHAIN_ERROR_CONTINUE) 373 terminateChainOnErr = false; 374 else 375 terminateChainOnErr = true; 376 } 377 else 378 { 379 if ((gdsFormatter & DssConstants.DSSCHAIN_SAME_ID) 381 == DssConstants.DSSCHAIN_SAME_ID) 382 { agent.throwSyntaxrm(CodePoint.SYNERRCD_CHAIN_OFF_SAME_NEXT_CORRELATOR, 384 DRDAProtocolException.NO_CODPNT_ARG); 385 } 386 if ((gdsFormatter & DssConstants.DSSCHAIN_ERROR_CONTINUE) 388 == DssConstants.DSSCHAIN_ERROR_CONTINUE) 389 { agent.throwSyntaxrm(CodePoint.SYNERRCD_CHAIN_OFF_ERROR_CONTINUE, 391 DRDAProtocolException.NO_CODPNT_ARG); 392 } 393 394 dssIsChainedWithSameID = false; 395 dssIsChainedWithDiffID = false; 396 } 397 398 dssCorrelationID = 399 ((buffer[pos] & 0xff) << 8) + 400 ((buffer[pos + 1] & 0xff) << 0); 401 pos += 2; 402 if (SanityManager.DEBUG) 403 trace("dssLength = " + dssLength + " correlationID = " + dssCorrelationID); 404 405 if (prevCorrelationID != DssConstants.CORRELATION_ID_UNKNOWN && 407 dssCorrelationID != prevCorrelationID) 408 { 409 agent.throwSyntaxrm(CodePoint.SYNERRCD_CHAIN_OFF_ERROR_CONTINUE, 410 DRDAProtocolException.NO_CODPNT_ARG); 411 } 412 413 if (dssIsChainedWithSameID) 416 prevCorrelationID = dssCorrelationID; 417 else 418 prevCorrelationID = DssConstants.CORRELATION_ID_UNKNOWN; 419 420 dssLength -= 6; 421 422 return dssCorrelationID; 423 } 424 431 protected void readReplyDss() throws DRDAProtocolException 432 { 433 ensureALayerDataInBuffer (6); 434 435 dssLength = ((buffer[pos++] & 0xff) << 8) + 437 ((buffer[pos++] & 0xff) << 0); 438 439 if ((dssLength & DssConstants.CONTINUATION_BIT) == 441 DssConstants.CONTINUATION_BIT) 442 { 443 dssLength = DssConstants.MAX_DSS_LENGTH; 444 dssIsContinued = true; 445 } 446 else 447 { 448 dssIsContinued = false; 449 } 450 451 if (dssLength < 6) 452 agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_LESS_THAN_6, 453 DRDAProtocolException.NO_CODPNT_ARG); 454 455 457 if ((buffer[pos++] & 0xff) != DssConstants.DSS_ID) 458 agent.throwSyntaxrm(CodePoint.SYNERRCD_CBYTE_NOT_D0, 459 DRDAProtocolException.NO_CODPNT_ARG); 460 461 int gdsFormatter = buffer[pos++] & 0xff; 462 463 if ((gdsFormatter & DssConstants.DSSCHAIN) == DssConstants.DSSCHAIN) 466 { if ((gdsFormatter & DssConstants.DSSCHAIN_SAME_ID) 468 == DssConstants.DSSCHAIN_SAME_ID) 469 { 470 dssIsChainedWithSameID = true; 471 dssIsChainedWithDiffID = false; 472 } 473 else 474 { 475 dssIsChainedWithSameID = false; 476 dssIsChainedWithDiffID = true; 477 } 478 } 479 else 480 { 481 dssIsChainedWithSameID = false; 482 dssIsChainedWithDiffID = false; 483 } 484 485 dssCorrelationID = 486 ((buffer[pos++] & 0xff) << 8) + 487 ((buffer[pos++] & 0xff) << 0); 488 489 if (SanityManager.DEBUG) 490 trace("dssLength = " + dssLength + " correlationID = " + dssCorrelationID); 491 492 dssLength -= 6; 493 494 } 495 496 503 protected int readLengthAndCodePoint() throws DRDAProtocolException 504 { 505 ensureBLayerDataInBuffer (4, NO_ADJUST_LENGTHS); 506 507 ddmScalarLen = readCodePoint(); 508 int codePoint = readCodePoint(); 509 510 if (SanityManager.DEBUG) 511 trace("length = "+ ddmScalarLen + " codepoint = " + java.lang.Integer.toHexString(codePoint)); 512 517 if ((ddmScalarLen & DssConstants.CONTINUATION_BIT) == DssConstants.CONTINUATION_BIT) 519 { 520 int numberOfExtendedLenBytes = ((int)ddmScalarLen - 521 DssConstants.CONTINUATION_BIT) - 4; 522 int adjustSize = 0; 523 ensureBLayerDataInBuffer (numberOfExtendedLenBytes, NO_ADJUST_LENGTHS); 524 switch (numberOfExtendedLenBytes) { 525 case 8: 526 ddmScalarLen = 527 ((buffer[pos++] & 0xff) << 56) + 528 ((buffer[pos++] & 0xff) << 48) + 529 ((buffer[pos++] & 0xff) << 40) + 530 ((buffer[pos++] & 0xff) << 32) + 531 ((buffer[pos++] & 0xff) << 24) + 532 ((buffer[pos++] & 0xff) << 16) + 533 ((buffer[pos++] & 0xff) << 8) + 534 ((buffer[pos++] & 0xff) << 0); 535 adjustSize = 12; 536 break; 537 case 6: 538 ddmScalarLen = 539 ((buffer[pos++] & 0xff) << 40) + 540 ((buffer[pos++] & 0xff) << 32) + 541 ((buffer[pos++] & 0xff) << 24) + 542 ((buffer[pos++] & 0xff) << 16) + 543 ((buffer[pos++] & 0xff) << 8) + 544 ((buffer[pos++] & 0xff) << 0); 545 adjustSize = 10; 546 break; 547 case 4: 548 ddmScalarLen = 549 ((buffer[pos++] & 0xff) << 24) + 550 ((buffer[pos++] & 0xff) << 16) + 551 ((buffer[pos++] & 0xff) << 8) + 552 ((buffer[pos++] & 0xff) << 0); 553 adjustSize = 8; 554 break; 555 default: 556 agent.throwSyntaxrm(CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN, 557 DRDAProtocolException.NO_CODPNT_ARG); 558 } 559 560 for (int i = 0; i <= topDdmCollectionStack; i++) { 563 ddmCollectionLenStack[i] -= adjustSize; 564 } 565 dssLength -= adjustSize; 566 } 567 else { 568 if (ddmScalarLen < 4) 569 agent.throwSyntaxrm(CodePoint.SYNERRCD_OBJ_LEN_LESS_THAN_4, 570 DRDAProtocolException.NO_CODPNT_ARG); 571 adjustLengths (4); 572 } 573 return codePoint; 574 } 575 576 581 protected int readCodePoint() 582 { 583 return( ((buffer[pos++] & 0xff) << 8) + 584 ((buffer[pos++] & 0xff) << 0)); 585 } 586 587 590 protected void markCollection() 591 { 592 ddmCollectionLenStack[++topDdmCollectionStack] = ddmScalarLen; 593 ddmScalarLen = 0; 594 } 595 596 603 protected int getCodePoint() throws DRDAProtocolException 604 { 605 if (topDdmCollectionStack == EMPTY_STACK) 606 { 607 return NO_CODEPOINT; 608 } 609 else 610 { 611 if (ddmCollectionLenStack[topDdmCollectionStack] == 0) 613 { 614 ddmCollectionLenStack[topDdmCollectionStack--] = 0; 616 return NO_CODEPOINT; 617 } 618 else { 619 return readLengthAndCodePoint(); 620 } 621 } 622 } 623 631 protected int getCodePoint(int codePointCheck) throws DRDAProtocolException 632 { 633 int codePoint = getCodePoint(); 634 if (codePoint != codePointCheck) 635 agent.missingCodePoint(codePoint); 636 return codePoint; 637 } 638 644 645 651 protected byte readByte () throws DRDAProtocolException 652 { 653 ensureBLayerDataInBuffer (1, ADJUST_LENGTHS); 654 return buffer[pos++]; 655 } 656 657 661 protected int readUnsignedByte () throws DRDAProtocolException 662 { 663 ensureBLayerDataInBuffer (1, ADJUST_LENGTHS); 664 return (int ) (buffer[pos++] & 0xff); 665 } 666 667 673 protected int readNetworkShort () throws DRDAProtocolException 674 { 675 ensureBLayerDataInBuffer (2, ADJUST_LENGTHS); 676 return ((buffer[pos++] & 0xff) << 8) + 677 ((buffer[pos++] & 0xff) << 0); 678 } 679 680 686 protected int readSignedNetworkShort () throws DRDAProtocolException 687 { 688 ensureBLayerDataInBuffer (2, ADJUST_LENGTHS); 689 return (short)(((buffer[pos++] & 0xff) << 8) + 690 ((buffer[pos++] & 0xff) << 0)); 691 } 692 698 protected short readShort (int byteOrder) throws DRDAProtocolException 699 { 700 ensureBLayerDataInBuffer (2, ADJUST_LENGTHS); 701 short s = SignedBinary.getShort (buffer, pos, byteOrder); 702 703 pos += 2; 704 705 return s; 706 } 707 708 714 protected int readNetworkInt () throws DRDAProtocolException 715 { 716 ensureBLayerDataInBuffer (4, ADJUST_LENGTHS); 717 return ((buffer[pos++] & 0xff) << 24) + 718 ((buffer[pos++] & 0xff) << 16) + 719 ((buffer[pos++] & 0xff) << 8) + 720 ((buffer[pos++] & 0xff) << 0); 721 } 722 723 729 protected int readInt (int byteOrder) throws DRDAProtocolException 730 { 731 ensureBLayerDataInBuffer (4, ADJUST_LENGTHS); 732 int i = SignedBinary.getInt (buffer, pos, byteOrder); 733 734 pos += 4; 735 736 return i; 737 } 738 739 745 protected long readNetworkLong () throws DRDAProtocolException 746 { 747 ensureBLayerDataInBuffer (8, ADJUST_LENGTHS); 748 749 return ((buffer[pos++] & 0xffL) << 56) + 750 ((buffer[pos++] & 0xffL) << 48) + 751 ((buffer[pos++] & 0xffL) << 40) + 752 ((buffer[pos++] & 0xffL) << 32) + 753 ((buffer[pos++] & 0xffL) << 24) + 754 ((buffer[pos++] & 0xffL) << 16) + 755 ((buffer[pos++] & 0xffL) << 8) + 756 ((buffer[pos++] & 0xffL) << 0); 757 } 758 759 760 766 protected long readNetworkSixByteLong() throws DRDAProtocolException 767 { 768 ensureBLayerDataInBuffer (6, ADJUST_LENGTHS); 769 770 return ( 771 ((buffer[pos++] & 0xffL) << 40) + 772 ((buffer[pos++] & 0xffL) << 32) + 773 ((buffer[pos++] & 0xffL) << 24) + 774 ((buffer[pos++] & 0xffL) << 16) + 775 ((buffer[pos++] & 0xffL) << 8) + 776 ((buffer[pos++] & 0xffL) << 0)); 777 } 778 779 785 protected long readLong (int byteOrder) throws DRDAProtocolException 786 { 787 ensureBLayerDataInBuffer (8, ADJUST_LENGTHS); 788 long l = SignedBinary.getLong (buffer, pos, byteOrder); 789 790 pos += 8; 791 792 return l; 793 } 794 795 801 protected float readFloat(int byteOrder) throws DRDAProtocolException 802 { 803 return Float.intBitsToFloat(readInt(byteOrder)); 804 } 805 806 812 protected double readDouble(int byteOrder) throws DRDAProtocolException 813 { 814 return Double.longBitsToDouble(readLong(byteOrder)); 815 } 816 817 825 protected BigDecimal readBigDecimal(int precision, int scale) throws DRDAProtocolException 826 { 827 int length = precision / 2 + 1; 829 830 ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); 831 832 int signum; 834 if ((buffer[pos+length-1] & 0x0F) == 0x0D) 835 signum = -1; 836 else 837 signum = 1; 838 839 if (precision <= 9) { 840 int value = packedNybblesToInt(buffer, pos, 0, length*2-1); 842 843 byte[] magnitude = new byte[4]; 845 magnitude[0] = (byte)(value >>> 24); 846 magnitude[1] = (byte)(value >>> 16); 847 magnitude[2] = (byte)(value >>> 8); 848 magnitude[3] = (byte)(value); 849 850 pos += length; 851 return new java.math.BigDecimal (new java.math.BigInteger (signum, magnitude), scale); 852 } 853 else if (precision <= 18) { 854 long value = packedNybblesToLong(buffer, pos, 0, length*2-1); 856 857 byte[] magnitude = new byte[8]; 859 magnitude[0] = (byte)(value >>> 56); 860 magnitude[1] = (byte)(value >>> 48); 861 magnitude[2] = (byte)(value >>> 40); 862 magnitude[3] = (byte)(value >>> 32); 863 magnitude[4] = (byte)(value >>> 24); 864 magnitude[5] = (byte)(value >>> 16); 865 magnitude[6] = (byte)(value >>> 8); 866 magnitude[7] = (byte)(value); 867 868 pos += length; 869 return new java.math.BigDecimal (new java.math.BigInteger (signum, magnitude), scale); 870 } 871 else if (precision <= 27) { 872 int lo = packedNybblesToInt(buffer, pos, (length-5)*2, 9); 874 int me = packedNybblesToInt(buffer, pos, (length-10)*2+1, 9); 876 int hi = packedNybblesToInt(buffer, pos, 0, (length-10)*2+1); 878 879 int[] value = computeMagnitude(new int[] {hi, me, lo}); 881 882 byte[] magnitude = new byte[12]; 884 magnitude[0] = (byte)(value[0] >>> 24); 885 magnitude[1] = (byte)(value[0] >>> 16); 886 magnitude[2] = (byte)(value[0] >>> 8); 887 magnitude[3] = (byte)(value[0]); 888 magnitude[4] = (byte)(value[1] >>> 24); 889 magnitude[5] = (byte)(value[1] >>> 16); 890 magnitude[6] = (byte)(value[1] >>> 8); 891 magnitude[7] = (byte)(value[1]); 892 magnitude[8] = (byte)(value[2] >>> 24); 893 magnitude[9] = (byte)(value[2] >>> 16); 894 magnitude[10] = (byte)(value[2] >>> 8); 895 magnitude[11] = (byte)(value[2]); 896 897 pos += length; 898 return new java.math.BigDecimal (new java.math.BigInteger (signum, magnitude), scale); 899 } 900 else if (precision <= 31) { 901 int lo = packedNybblesToInt(buffer, pos, (length-5)*2, 9); 903 int meLo = packedNybblesToInt(buffer, pos, (length-10)*2+1, 9); 905 int meHi = packedNybblesToInt(buffer, pos, (length-14)*2, 9); 907 int hi = packedNybblesToInt(buffer, pos, 0, (length-14)*2); 909 910 int[] value = computeMagnitude(new int[] {hi, meHi, meLo, lo}); 912 913 byte[] magnitude = new byte[16]; 915 magnitude[0] = (byte)(value[0] >>> 24); 916 magnitude[1] = (byte)(value[0] >>> 16); 917 magnitude[2] = (byte)(value[0] >>> 8); 918 magnitude[3] = (byte)(value[0]); 919 magnitude[4] = (byte)(value[1] >>> 24); 920 magnitude[5] = (byte)(value[1] >>> 16); 921 magnitude[6] = (byte)(value[1] >>> 8); 922 magnitude[7] = (byte)(value[1]); 923 magnitude[8] = (byte)(value[2] >>> 24); 924 magnitude[9] = (byte)(value[2] >>> 16); 925 magnitude[10] = (byte)(value[2] >>> 8); 926 magnitude[11] = (byte)(value[2]); 927 magnitude[12] = (byte)(value[3] >>> 24); 928 magnitude[13] = (byte)(value[3] >>> 16); 929 magnitude[14] = (byte)(value[3] >>> 8); 930 magnitude[15] = (byte)(value[3]); 931 932 pos += length; 933 return new java.math.BigDecimal (new java.math.BigInteger (signum, magnitude), scale); 934 } 935 else { 936 pos += length; 937 throw new java.lang.IllegalArgumentException ("Decimal may only be up to 31 digits!"); 939 } 940 } 941 942 943 944 byte[] getExtData (boolean checkNullability) throws DRDAProtocolException 945 { 946 return getExtData(ddmScalarLen, checkNullability); 947 } 948 949 950 960 EXTDTAReaderInputStream getEXTDTAReaderInputStream 961 (final boolean checkNullability) 962 throws DRDAProtocolException 963 { 964 if (checkNullability && isEXTDTANull()) { 965 return null; 966 } else { 967 return new EXTDTAReaderInputStream(this); 968 } 969 } 970 971 977 ByteArrayInputStream readLOBInitStream(final long desiredLength) 978 throws DRDAProtocolException 979 { 980 return readLOBChunk(false, desiredLength); 981 } 982 983 989 ByteArrayInputStream readLOBContinuationStream (final long desiredLength) 990 throws IOException 991 { 992 try { 993 return readLOBChunk(true, desiredLength); 994 } catch (DRDAProtocolException e) { 995 e.printStackTrace(agent.getServer().logWriter); 996 throw new IOException (e.getMessage()); 997 } 998 } 999 1000 1007 private ByteArrayInputStream readLOBChunk 1008 (final boolean readHeader, final long desiredLength) 1009 throws DRDAProtocolException 1010 { 1011 if (readHeader) { 1012 readDSSContinuationHeader(); 1013 } 1014 int copySize = (int) Math.min(dssLength, desiredLength); 1015 1016 ensureALayerDataInBuffer (copySize); 1018 adjustLengths (copySize); 1019 1020 ByteArrayInputStream bais = 1023 new ByteArrayInputStream (buffer, pos, copySize); 1024 pos += copySize; 1025 1026 return bais; 1027 } 1028 1029 byte[] getExtData (long desiredLength, boolean checkNullability) throws DRDAProtocolException 1030 { 1031 boolean readHeader; 1032 int copySize; 1033 ByteArrayOutputStream baos; 1034 boolean isLengthAndNullabilityUnknown = false; 1035 1036 1037 if (desiredLength != -1) { 1038 baos = new ByteArrayOutputStream ((int) desiredLength); 1040 } 1041 else { 1042 baos = new ByteArrayOutputStream (); 1044 desiredLength = MAX_EXTDTA_SIZE; 1047 } 1048 1049 1050 if (checkNullability) 1052 if (isEXTDTANull()) 1053 return null; 1054 1055 copySize = (int) Math.min(dssLength,desiredLength); 1058 1059 1062 do { 1063 if (dssIsContinued) 1065 readHeader = true; 1066 else 1067 readHeader = false; 1068 1069 ensureALayerDataInBuffer (copySize); 1071 adjustLengths (copySize); 1072 baos.write (buffer, pos, copySize); 1073 pos += copySize; 1074 desiredLength -= copySize; 1075 1076 if (readHeader) 1078 readDSSContinuationHeader (); 1079 1080 copySize = (int) Math.min(dssLength,desiredLength); 1082 } 1083 while (readHeader == true && desiredLength > 0); 1084 1085 return baos.toByteArray(); 1086 } 1087 1088 1089 private void readDSSContinuationHeader () throws DRDAProtocolException 1095 { 1096 ensureALayerDataInBuffer(2); 1097 1098 dssLength = 1099 ((buffer[pos++]&0xFF) << 8) + 1100 ((buffer[pos++]&0xFF) << 0); 1101 1102 if ((dssLength & 0x8000) == 0x8000) { 1103 dssLength = DssConstants.MAX_DSS_LENGTH; 1104 dssIsContinued = true; 1105 } 1106 else { 1107 dssIsContinued = false; 1108 } 1109 if (dssLength <= 2) { 1112 agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2, 1113 DRDAProtocolException.NO_CODPNT_ARG); 1114 } 1115 1116 dssLength -= 2; } 1118 1119 private boolean isEXTDTANull () throws DRDAProtocolException 1123 { 1124 ensureALayerDataInBuffer (1); 1126 adjustLengths (1); 1127 1128 byte nullByte = buffer[pos++]; 1130 if (nullByte == (byte)0x00) 1131 return false; 1132 1133 return true; 1134 } 1135 1136 1137 1146 private int packedNybblesToInt (byte[] buffer, 1147 int offset, 1148 int startNybble, 1149 int numberOfNybbles) 1150 { 1151 int value = 0; 1152 1153 int i = startNybble / 2; 1154 if ((startNybble % 2) != 0) { 1155 value += buffer[offset+i] & 0x0F; 1157 i++; 1158 } 1159 1160 int endNybble = startNybble + numberOfNybbles -1; 1161 for (; i<(endNybble+1)/2; i++) { 1162 value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); value = value*10 + (buffer[offset+i] & 0x0F); } 1165 1166 if ((endNybble % 2) == 0) { 1167 value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); 1169 } 1170 1171 return value; 1172 } 1173 1174 1183 private long packedNybblesToLong (byte[] buffer, 1184 int offset, 1185 int startNybble, 1186 int numberOfNybbles) 1187 { 1188 long value = 0; 1189 1190 int i = startNybble / 2; 1191 if ((startNybble % 2) != 0) { 1192 value += buffer[offset+i] & 0x0F; 1194 i++; 1195 } 1196 1197 int endNybble = startNybble + numberOfNybbles -1; 1198 for (; i<(endNybble+1)/2; i++) { 1199 value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); value = value*10 + (buffer[offset+i] & 0x0F); } 1202 1203 if ((endNybble % 2) == 0) { 1204 value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); 1206 } 1207 1208 return value; 1209 } 1210 1211 1216 private int[] computeMagnitude(int[] input) 1217 { 1218 int length = input.length; 1219 int[] mag = new int[length]; 1220 1221 mag[length-1] = input[length-1]; 1222 for (int i=0; i<length-1; i++) { 1223 int carry = 0; 1224 int j = tenRadixMagnitude[i].length-1; 1225 int k = length-1; 1226 for (; j>=0; j--, k--) { 1227 long product = (input[length-2-i] & 0xFFFFFFFFL) * (tenRadixMagnitude[i][j] & 0xFFFFFFFFL) 1228 + (mag[k] & 0xFFFFFFFFL) + (carry & 0xFFFFFFFFL); carry = (int) (product >>> 32); 1231 mag[k] = (int) (product & 0xFFFFFFFFL); 1232 } 1233 mag[k] = (int) carry; 1234 } 1235 return mag; 1236 } 1237 1238 1244 protected boolean readBoolean () throws DRDAProtocolException 1245 { 1246 ensureBLayerDataInBuffer (1, ADJUST_LENGTHS); 1247 return buffer[pos++] != 0; 1248 } 1249 1250 1261 protected String readEncryptedString (DecryptionManager decryptM, int securityMechanism, 1262 byte[] initVector, byte[] sourcePublicKey) 1263 throws DRDAProtocolException, java.sql.SQLException 1264 { 1265 byte[] cipherText = readBytes(); 1266 byte[] plainText = null; 1267 plainText = decryptM.decryptData(cipherText, securityMechanism, initVector, 1268 sourcePublicKey); 1269 if (plainText == null) 1270 return null; 1271 else 1272 return ccsidManager.convertToUCS2(plainText); 1273 } 1274 1275 1284 protected String readString (int length) throws DRDAProtocolException 1285 { 1286 ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); 1287 1288 String result = ccsidManager.convertToUCS2 (buffer, pos, length); 1289 pos += length; 1290 return result; 1291 } 1292 1293 1302 protected void readString(DRDAString dst, int size, boolean unpad) 1303 throws DRDAProtocolException 1304 { 1305 ensureBLayerDataInBuffer(size, ADJUST_LENGTHS); 1306 int startPos = pos; 1307 pos += size; 1308 if (unpad) { 1309 while ((size > 0) && 1310 (buffer[startPos + size - 1] == ccsidManager.space)) { 1311 --size; 1312 } 1313 } 1314 dst.setBytes(buffer, startPos, size); 1315 } 1316 1317 1324 protected String readString (int length, String encoding) 1325 throws DRDAProtocolException 1326 { 1327 ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); 1328 String s = null; 1329 1330 try { 1331 s = new String (buffer, pos, length, encoding); 1332 } 1333 catch (java.io.UnsupportedEncodingException e) { 1334 agent.agentError("UnsupportedEncodingException in readString, encoding = " 1335 + encoding); 1336 e.printStackTrace(agent.getServer().logWriter); 1337 } 1338 1339 pos += length; 1340 return s; 1341 } 1342 1343 1349 protected String readStringData() 1350 throws DRDAProtocolException 1351 { 1352 return readString((int)ddmScalarLen, NetworkServerControlImpl.DEFAULT_ENCODING); 1353 } 1354 1355 1362 protected String readStringData(int length) 1363 throws DRDAProtocolException 1364 { 1365 return readString(length, NetworkServerControlImpl.DEFAULT_ENCODING); 1366 } 1367 1368 1374 protected String readLDStringData(String encoding) 1375 throws DRDAProtocolException 1376 { 1377 int length = readNetworkShort(); 1378 return readString(length, encoding); 1379 } 1380 1381 1386 protected String readString () throws DRDAProtocolException 1387 { 1388 return readString((int)ddmScalarLen); 1389 } 1390 1391 1398 protected byte[] readBytes (int length) throws DRDAProtocolException 1399 { 1400 byte[] b; 1401 1402 if (length < DssConstants.MAX_DSS_LENGTH) 1403 { 1404 ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); 1405 b = new byte[length]; 1406 System.arraycopy(buffer,pos,b,0,length); 1407 pos +=length; 1408 } 1409 else 1410 b = getExtData(length,false); 1411 return b; 1412 } 1413 1414 1420 protected byte[] readBytes () throws DRDAProtocolException 1421 { 1422 return readBytes((int)ddmScalarLen); 1423 } 1424 1425 1431 protected void skipBytes (int length) throws DRDAProtocolException 1432 { 1433 ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); 1434 pos += length; 1435 } 1436 1437 1442 protected void skipBytes () throws DRDAProtocolException 1443 { 1444 skipBytes((int)ddmScalarLen); 1445 } 1446 1447 1452 protected void skipDss() throws DRDAProtocolException 1453 { 1454 while (dssIsContinued) 1455 { 1456 skipBytes((int)dssLength); 1457 readDSSContinuationHeader(); 1458 } 1459 skipBytes((int)dssLength); 1460 topDdmCollectionStack = EMPTY_STACK; 1461 ddmScalarLen = 0; 1462 dssLength = 0; 1463 1464 } 1465 1466 protected void clearBuffer() throws DRDAProtocolException 1467 { 1468 skipBytes(java.lang.Math.min(dssLength, count - pos)); 1469 dssIsChainedWithSameID = false; 1470 dssIsChainedWithDiffID = false; 1471 } 1472 1473 1479 protected String convertBytes(byte[] buf) 1480 { 1481 return ccsidManager.convertToUCS2 (buf, 0, buf.length); 1482 } 1483 1484 1490 private void adjustLengths(int length) 1491 { 1492 ddmScalarLen -= length; 1493 for (int i = 0; i <= topDdmCollectionStack; i++) { 1494 ddmCollectionLenStack[i] -= length; 1495 } 1496 dssLength -= length; 1497 } 1498 1499 1500 1502 1503 1510 protected String readCmdString (int length) throws DRDAProtocolException, java.io.UnsupportedEncodingException 1511 { 1512 if (length == 0) 1513 return null; 1514 1515 ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); 1516 String result = new String (buffer, pos, length, 1517 NetworkServerControlImpl.DEFAULT_ENCODING); 1518 pos += length; 1519 return result; 1520 } 1521 1527 protected String readCmdString () throws DRDAProtocolException, java.io.UnsupportedEncodingException 1528 { 1529 int length = readNetworkShort(); 1530 return readCmdString(length); 1531 1532 } 1533 1534 1535 1537 1545 private void ensureALayerDataInBuffer (int desiredDataSize) 1546 throws DRDAProtocolException 1547 { 1548 int avail = count - pos; 1550 1551 if (avail < desiredDataSize) 1553 { 1554 fill (desiredDataSize - avail); 1555 } 1556 } 1557 1566 private void ensureBLayerDataInBuffer (int desiredDataSize, boolean adjustLen) 1567 throws DRDAProtocolException 1568 { 1569 ensureALayerDataInBuffer (desiredDataSize); 1570 if (dssIsContinued) 1571 { 1572 if (desiredDataSize > dssLength) 1573 { 1574 int continueDssHeaderCount = 1575 (((desiredDataSize - dssLength) / DssConstants.MAX_DSS_LENGTH) + 1); 1576 compressBLayerData (continueDssHeaderCount); 1577 } 1578 } 1579 if (adjustLen) 1580 adjustLengths(desiredDataSize); 1581 } 1582 1583 1591 private void compressBLayerData (int continueDssHeaderCount) 1592 throws DRDAProtocolException 1593 { 1594 1595 1596 int tempPos = 0; 1598 for (int i = 0; i < continueDssHeaderCount; i++) 1599 { 1600 if (i == 0) 1602 { 1603 tempPos = pos + dssLength; 1605 } 1606 else 1607 { 1608 tempPos += DssConstants.MAX_DSS_LENGTH; 1610 } 1611 } 1612 1613 1614 int shiftSize = 0; 1618 int bytesToShift = 0; 1619 int continueHeaderLength = 0; 1620 int newdssLength = 0; 1621 1622 1623 for (int i = 0; i < continueDssHeaderCount; i++) 1624 { 1625 continueHeaderLength = ((buffer[tempPos] & 0xff) << 8) + 1626 ((buffer[tempPos + 1] & 0xff) << 0); 1627 1628 if (i == 0) 1629 { 1630 1632 if ((continueHeaderLength & DssConstants.CONTINUATION_BIT) 1633 == DssConstants.CONTINUATION_BIT) 1634 { 1635 continueHeaderLength = DssConstants.MAX_DSS_LENGTH; 1637 dssIsContinued = true; 1638 } 1639 else 1640 { 1641 dssIsContinued = false; 1643 } 1644 shiftSize = 2; 1646 } 1647 else 1648 { 1649 if ((continueHeaderLength & DssConstants.CONTINUATION_BIT) == 1651 DssConstants.CONTINUATION_BIT) 1652 { 1653 continueHeaderLength = DssConstants.MAX_DSS_LENGTH; 1654 } 1655 else 1656 { 1657 agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_LENGTH_BYTE_NUMBER_MISMATCH, 1662 DRDAProtocolException.NO_CODPNT_ARG); 1663 } 1664 shiftSize += 2; 1666 } 1667 1668 if (continueHeaderLength <= 2) 1671 { 1672 agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2, 1673 DRDAProtocolException.NO_CODPNT_ARG); 1674 } 1675 1676 newdssLength += (continueHeaderLength-2); 1677 1678 if (i != (continueDssHeaderCount - 1)) 1680 bytesToShift = DssConstants.MAX_DSS_LENGTH; 1681 else 1682 bytesToShift = dssLength; 1683 1684 tempPos -= (bytesToShift - 2); 1685 System.arraycopy(buffer, tempPos - shiftSize, buffer, tempPos, 1686 bytesToShift); 1687 } 1688 pos = tempPos; 1690 dssLength += newdssLength; 1691 } 1692 1693 1698 1699 1706 private void shiftBuffer (byte[] destinationBuffer) 1707 { 1708 int sz = count - pos; 1710 if (SanityManager.DEBUG) { 1711 if ((sz < 0 || pos < 0) ) 1712 { 1713 SanityManager.THROWASSERT( 1714 "Unexpected data size or position. sz=" + sz + 1715 " count=" + count +" pos=" + pos); 1716 } 1717 } 1718 1719 System.arraycopy (buffer, pos, destinationBuffer, 0, sz); 1721 1722 pos = 0; 1724 count = sz; 1725 1726 buffer = destinationBuffer; 1728 } 1729 1741 private void ensureSpaceInBufferForFill (int desiredSpace) 1742 { 1743 int currentAvailableSpace = (buffer.length - count) + pos; 1747 1748 if (currentAvailableSpace < desiredSpace) { 1750 1751 int doubleBufferSize = (2 * buffer.length); 1756 int minumNewBufferSize = (desiredSpace - currentAvailableSpace) + 1757 buffer.length; 1758 int newsz = minumNewBufferSize <= doubleBufferSize ? 1759 doubleBufferSize : minumNewBufferSize; 1760 1761 byte[] newBuffer = new byte[newsz]; 1762 1763 shiftBuffer (newBuffer); 1765 } 1766 else { 1767 1768 if (pos != 0) { 1775 shiftBuffer (buffer); 1776 } 1777 } 1778 } 1779 1780 1788 private void fill (int minimumBytesNeeded) throws DRDAProtocolException 1789 { 1790 ensureSpaceInBufferForFill (minimumBytesNeeded); 1793 1794 int totalBytesRead = 0; 1797 int actualBytesRead = 0; 1798 do { 1799 try { 1800 actualBytesRead = inputStream.read ( 1801 buffer, count, buffer.length - count); 1802 } 1803 catch (java.io.IOException ioe) { 1804 agent.markCommunicationsFailure ("DDMReader.fill()", 1805 "InputStream.read()", ioe.getMessage(), "*"); 1806 } 1807 finally { 1808 if ((dssTrace != null) && dssTrace.isComBufferTraceOn()) 1809 dssTrace.writeComBufferData (buffer, 1810 count, 1811 actualBytesRead, 1812 DssTrace.TYPE_TRACE_RECEIVE, 1813 "Request", 1814 "fill", 1815 5); 1816 } 1817 if (actualBytesRead != -1) 1818 { 1819 count += actualBytesRead; 1820 totalBytesRead += actualBytesRead; 1821 } 1822 1823 } 1824 while ((totalBytesRead < minimumBytesNeeded) && (actualBytesRead != -1)); 1825 if (actualBytesRead == -1) 1826 { 1827 if (totalBytesRead < minimumBytesNeeded) 1828 { 1829 agent.markCommunicationsFailure ("DDMReader.fill()", 1830 "InputStream.read()", "insufficient data", "*"); 1831 } 1832 } 1833 } 1834 1835 1838 private void trace(String msg) 1839 { 1840 if (agent != null) 1841 agent.trace(msg); 1842 } 1843 1844 protected String toDebugString(String indent) 1845 { 1846 String s = indent + "***** DDMReader toDebugString ******\n"; 1847 int buflen = 0; 1848 if (buffer != null) 1849 buflen = buffer.length; 1850 s += indent + "Reader buffer length = " + buffer.length + "\n"; 1851 return s; 1852 } 1853 1854 1857 protected byte getCurrChainState() { 1858 1859 if (!dssIsChainedWithSameID && !dssIsChainedWithDiffID) 1860 return DssConstants.DSS_NOCHAIN; 1861 1862 if (dssIsChainedWithSameID) 1863 return DssConstants.DSSCHAIN_SAME_ID; 1864 1865 return DssConstants.DSSCHAIN; 1866 1867 } 1868 1869} 1870 | Popular Tags |