1 21 22 package org.apache.derby.impl.drda; 23 24 import java.io.OutputStream ; 25 import java.io.InputStream ; 26 import java.io.BufferedInputStream ; 27 import java.io.BufferedOutputStream ; 28 import org.apache.derby.iapi.services.sanity.SanityManager; 29 import java.sql.SQLException ; 30 import java.sql.DataTruncation ; 31 import java.math.BigDecimal ; 32 import org.apache.derby.iapi.error.ExceptionSeverity; 33 import java.util.Arrays ; 34 import org.apache.derby.iapi.reference.Property; 35 import org.apache.derby.iapi.services.property.PropertyUtil; 36 37 import java.io.IOException ; 38 39 45 class DDMWriter 46 { 47 48 private final static int MAX_MARKS_NESTING = 10; 52 53 private final static int DEFAULT_BUFFER_SIZE = 32767; 55 56 57 static final BigDecimal ZERO = BigDecimal.valueOf(0L); 58 59 private byte[] bytes; 61 62 private int offset; 64 65 private int[] markStack = new int[MAX_MARKS_NESTING]; 67 68 private int top; 70 71 private CcsidManager ccsidManager; 73 74 private DRDAConnThread agent; 76 77 private int dssLengthLocation; 82 83 private int correlationID; 85 86 private int nextCorrelationID; 88 89 private boolean isDRDAProtocol; 91 private DssTrace dssTrace; 93 94 private int prevHdrLocation; 97 98 private int previousCorrId; 100 101 private byte previousChainByte; 103 104 private boolean isContinuationDss; 106 107 private int lastDSSBeforeMark; 112 113 DDMWriter (int minSize, CcsidManager ccsidManager, DRDAConnThread agent, DssTrace dssTrace) 115 { 116 this.bytes = new byte[minSize]; 117 this.ccsidManager = ccsidManager; 118 this.agent = agent; 119 this.prevHdrLocation = -1; 120 this.previousCorrId = DssConstants.CORRELATION_ID_UNKNOWN; 121 this.previousChainByte = DssConstants.DSS_NOCHAIN; 122 this.isContinuationDss = false; 123 this.lastDSSBeforeMark = -1; 124 reset(dssTrace); 125 } 126 127 DDMWriter (CcsidManager ccsidManager, DRDAConnThread agent, DssTrace dssTrace) 128 { 129 this.bytes = new byte[DEFAULT_BUFFER_SIZE]; 130 this.ccsidManager = ccsidManager; 131 this.agent = agent; 132 this.prevHdrLocation = -1; 133 this.previousCorrId = DssConstants.CORRELATION_ID_UNKNOWN; 134 this.previousChainByte = DssConstants.DSS_NOCHAIN; 135 this.isContinuationDss = false; 136 this.lastDSSBeforeMark = -1; 137 reset(dssTrace); 138 } 139 140 144 protected void reset(DssTrace dssTrace) 145 { 146 offset = 0; 147 top = 0; 148 dssLengthLocation = 0; 149 nextCorrelationID = 1; 150 correlationID = DssConstants.CORRELATION_ID_UNKNOWN; 151 isDRDAProtocol = true; 152 this.dssTrace = dssTrace; 153 } 154 155 158 protected void setCMDProtocol() 159 { 160 isDRDAProtocol = false; 161 } 162 163 166 protected void createDssReply() 167 { 168 beginDss(DssConstants.DSSFMT_RPYDSS, true); 169 } 170 171 179 protected void createDssRequest() 180 { 181 beginDss(DssConstants.DSSFMT_RQSDSS, true); 182 } 183 184 187 protected void createDssObject() 188 { 189 beginDss(DssConstants.DSSFMT_OBJDSS, true); 190 } 191 192 213 private void markDssAsContinued(boolean forLob) 214 { 215 216 if (!forLob) { 217 bytes[dssLengthLocation] |= 0x80; 221 } 222 223 if (!isContinuationDss) 228 endDss(!forLob); 229 230 } 231 232 244 protected void endDss(byte chainByte) 245 { 246 247 endDss(true); 249 250 bytes[dssLengthLocation + 3] &= 0x0F; bytes[dssLengthLocation + 3] |= chainByte; 253 previousChainByte = chainByte; 254 255 } 256 257 261 protected void endDss() { 262 endDss(true); 263 } 264 265 269 private void endDss (boolean finalizeLength) 270 { 271 272 if (finalizeLength) 273 finalizeDssLength(); 274 275 if (isContinuationDss) { 276 isContinuationDss = false; 278 return; 279 } 280 281 previousCorrId = correlationID; 282 prevHdrLocation = dssLengthLocation; 283 previousChainByte = DssConstants.DSSCHAIN_SAME_ID; 284 285 } 286 287 291 protected void endDdmAndDss () 292 { 293 endDdm(); endDss(); 295 } 296 320 protected byte [] copyDSSDataToEnd(int start) 321 { 322 start = start + dssLengthLocation; 323 int length = offset - start; 324 byte [] temp = new byte[length]; 325 System.arraycopy(bytes,start,temp,0,length); 326 return temp; 327 } 328 329 331 336 protected void startDdm (int codePoint) 337 { 338 markStack[top++] = offset; 341 ensureLength (4); offset += 2; bytes[offset] = (byte) ((codePoint >>> 8) & 0xff); 344 bytes[offset + 1] = (byte) (codePoint & 0xff); 345 offset += 2; 346 } 347 348 352 protected void clearDdm () 353 { 354 offset = markStack[top--]; 355 } 356 357 361 protected void clearBuffer() 362 { 363 offset = 0; 364 top = 0; 365 dssLengthLocation = 0; 366 correlationID = DssConstants.CORRELATION_ID_UNKNOWN; 367 nextCorrelationID = 1; 368 isDRDAProtocol = true; 369 } 370 371 375 protected void endDdm () 376 { 377 int lengthLocation = markStack[--top]; 380 int length = offset - lengthLocation; 381 382 int extendedLengthByteCount = calculateExtendedLengthByteCount (length); 386 if (extendedLengthByteCount != 0) 387 { 388 ensureLength (extendedLengthByteCount); 390 391 int extendedLength = length - 4; 394 395 int extendedLengthLocation = lengthLocation + 4; 398 System.arraycopy (bytes, 399 extendedLengthLocation, 400 bytes, 401 extendedLengthLocation + extendedLengthByteCount, 402 extendedLength); 403 404 int shiftSize = (extendedLengthByteCount -1) * 8; 406 for (int i = 0; i < extendedLengthByteCount; i++) 407 { 408 bytes[extendedLengthLocation++] = 409 (byte) ((extendedLength >>> shiftSize ) & 0xff); 410 shiftSize -= 8; 411 } 412 413 offset += extendedLengthByteCount; 415 416 length = extendedLengthByteCount + 4; 421 length |= DssConstants.CONTINUATION_BIT; 422 } 423 424 bytes[lengthLocation] = (byte) ((length >>> 8) & 0xff); 426 bytes[lengthLocation+1] = (byte) (length & 0xff); 427 428 } 429 430 439 protected int getDSSLength() 440 { 441 return offset - dssLengthLocation; 442 } 443 444 451 protected void truncateDSS(int value) 452 { 453 offset = dssLengthLocation + value; 454 } 455 456 457 459 464 protected void writeByte (int value) 465 { 466 if (SanityManager.DEBUG) 467 { 468 if (value > 255) 469 SanityManager.THROWASSERT( 470 "writeByte value: " + value + 471 " may not be > 255"); 472 } 473 474 ensureLength (1); 475 bytes[offset++] = (byte) (value & 0xff); 476 } 477 478 479 484 protected void writeNetworkShort (int value) 485 { 486 ensureLength (2); 487 bytes[offset] = (byte) ((value >>> 8) & 0xff); 488 bytes[offset + 1] = (byte) (value & 0xff); 489 offset += 2; 490 } 491 492 497 protected void writeNetworkInt (int value) 498 { 499 ensureLength (4); 500 bytes[offset] = (byte) ((value >>> 24) & 0xff); 501 bytes[offset + 1] = (byte) ((value >>> 16) & 0xff); 502 bytes[offset + 2] = (byte) ((value >>> 8) & 0xff); 503 bytes[offset + 3] = (byte) (value & 0xff); 504 offset += 4; 505 } 506 507 508 514 protected void writeBytes (byte[] buf, int length) 515 { 516 writeBytes(buf, 0,length); 517 } 518 519 520 521 528 protected void writeBytes (byte[] buf, int start, int length) 529 { 530 531 if (SanityManager.DEBUG) 532 { 533 if (buf == null && length > 0) 534 SanityManager.THROWASSERT("Buf is null"); 535 if (length + start - 1 > buf.length) 536 SanityManager.THROWASSERT("Not enough bytes in buffer"); 537 538 } 539 ensureLength (length); 540 System.arraycopy(buf,start,bytes,offset,length); 541 offset += length; 542 } 543 548 protected void writeBytes (byte[] buf) 549 { 550 writeBytes(buf,buf.length); 551 } 552 553 554 555 protected void writeLDBytes(byte[] buf) 556 { 557 writeLDBytes(buf, 0); 558 } 559 560 protected void writeLDBytes(byte[] buf, int index) 561 { 562 563 int length = buf.length; 564 int writeLen = buf.length; 565 566 writeShort(writeLen); 567 568 writeBytes(buf,0,writeLen); 569 } 570 571 572 578 void writeCodePoint4Bytes (int codePoint, int value) 579 { 580 ensureLength (4); 581 bytes[offset] = (byte) ((codePoint >>> 8) & 0xff); 582 bytes[offset + 1] = (byte) (codePoint & 0xff); 583 bytes[offset + 2] = (byte) ((value >>> 8) & 0xff); 584 bytes[offset + 3] = (byte) (value & 0xff); 585 offset += 4; 586 } 587 588 594 void writeScalar1Byte (int codePoint, int value) 595 { 596 ensureLength (5); 597 bytes[offset] = 0x00; 598 bytes[offset + 1] = 0x05; 599 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 600 bytes[offset + 3] = (byte) (codePoint & 0xff); 601 bytes[offset + 4] = (byte) (value & 0xff); 602 offset += 5; 603 } 604 605 611 protected void writeScalar2Bytes (int codePoint, int value) 612 { 613 ensureLength (6); 614 bytes[offset] = 0x00; 615 bytes[offset + 1] = 0x06; 616 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 617 bytes[offset + 3] = (byte) (codePoint & 0xff); 618 bytes[offset + 4] = (byte) ((value >>> 8) & 0xff); 619 bytes[offset + 5] = (byte) (value & 0xff); 620 offset += 6; 621 } 622 623 protected void writeScalar2Bytes ( int value) 624 { 625 ensureLength (2); 626 bytes[offset] = (byte) ((value >>> 8) & 0xff); 627 bytes[offset + 1] = (byte) (value & 0xff); 628 offset += 2; 629 } 630 631 637 protected void startDdm (int length, int codePoint) 638 { 639 ensureLength (4); 640 bytes[offset] = (byte) ((length >>> 8) & 0xff); 641 bytes[offset + 1] = (byte) (length & 0xff); 642 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 643 bytes[offset + 3] = (byte) (codePoint & 0xff); 644 offset += 4; 645 } 646 647 654 protected void writeScalarBytes (int codePoint, byte[] buf, int length) 655 { 656 if (SanityManager.DEBUG) 657 { 658 if (buf == null && length > 0) 659 SanityManager.THROWASSERT("Buf is null"); 660 if (length > buf.length) 661 SanityManager.THROWASSERT("Not enough bytes in buffer"); 662 } 663 ensureLength (length + 4); 664 bytes[offset] = (byte) (((length+4) >>> 8) & 0xff); 665 bytes[offset + 1] = (byte) ((length+4) & 0xff); 666 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 667 bytes[offset + 3] = (byte) (codePoint & 0xff); 668 System.arraycopy(buf,0,bytes,offset + 4, length); 669 offset += length + 4; 670 } 671 672 673 674 protected void writeScalarStream (boolean chainedWithSameCorrelator, 675 int codePoint, 676 EXTDTAInputStream in, 677 boolean writeNullByte) 678 throws DRDAProtocolException 679 { 680 681 682 683 int spareDssLength = prepScalarStream( chainedWithSameCorrelator, 685 codePoint, 686 writeNullByte); 687 688 int bytesRead = 0; 690 int totalBytesRead = 0; 691 692 try { 693 694 OutputStream out = 695 placeLayerBStreamingBuffer( agent.getOutputStream() ); 696 697 boolean isLastSegment = false; 698 699 while( !isLastSegment ){ 700 701 int spareBufferLength = bytes.length - offset; 702 703 if( SanityManager.DEBUG ){ 704 705 if( PropertyUtil.getSystemProperty("derby.debug.suicideOfLayerBStreaming") != null ) 706 throw new IOException (); 707 } 708 709 bytesRead = in.read(bytes, 710 offset, 711 Math.min(spareDssLength, 712 spareBufferLength)); 713 714 totalBytesRead += bytesRead; 715 offset += bytesRead; 716 spareDssLength -= bytesRead; 717 spareBufferLength -= bytesRead; 718 719 isLastSegment = peekStream(in) < 0; 720 721 if(isLastSegment || 722 spareDssLength == 0){ 723 724 flushScalarStreamSegment (isLastSegment, 725 out); 726 727 if( ! isLastSegment ) 728 spareDssLength = DssConstants.MAX_DSS_LENGTH - 2; 729 730 } 731 732 } 733 734 out.flush(); 735 736 }catch(IOException e){ 737 agent.markCommunicationsFailure ("DDMWriter.writeScalarStream()", 738 "", 739 e.getMessage(), 740 "*"); 741 } 742 743 } 744 745 748 private void beginDss (boolean chainedToNextStructure, 749 int dssType) 750 { 751 beginDss(dssType, false); 753 bytes[dssLengthLocation] = (byte) 0xFF; 756 bytes[dssLengthLocation + 1] = (byte) 0xFF; 757 758 if (chainedToNextStructure) { 762 dssType |= DssConstants.GDSCHAIN_SAME_ID; 763 } 764 765 bytes[dssLengthLocation + 3] = (byte) (dssType & 0xff); 766 } 767 768 769 779 private int prepScalarStream( boolean chainedWithSameCorrelator, 780 int codePoint, 781 boolean writeNullByte) throws DRDAProtocolException 782 { 783 784 ensureLength( DEFAULT_BUFFER_SIZE - offset ); 785 786 final int nullIndicatorSize = writeNullByte ? 1:0; 787 788 789 794 try { 795 sendBytes(agent.getOutputStream()); 798 } 799 catch (java.io.IOException e) { 800 agent.markCommunicationsFailure ("DDMWriter.writeScalarStream()", 801 "OutputStream.flush()", 802 e.getMessage(),"*"); 803 } 804 805 beginDss(chainedWithSameCorrelator, DssConstants.GDSFMT_OBJDSS); 807 808 writeLengthCodePoint(0x8004,codePoint); 809 810 811 if (writeNullByte) 813 writeByte(0x0); 814 815 return DssConstants.MAX_DSS_LENGTH - 6 - 4 - nullIndicatorSize; 818 819 820 } 821 822 823 protected boolean doesRequestContainData() 826 { 827 return offset != 0; 828 } 829 830 831 private void flushScalarStreamSegment ( boolean lastSegment, 834 OutputStream out) 835 throws DRDAProtocolException 836 { 837 838 if (! lastSegment) { 840 841 try { 843 markDssAsContinued(true); sendBytes (out, 847 false); 848 849 }catch (java.io.IOException ioe) { 850 agent.markCommunicationsFailure ("DDMWriter.flushScalarStreamSegment()", 851 "", 852 ioe.getMessage(), 853 "*"); 854 } 855 856 857 dssLengthLocation = offset; 859 bytes[offset++] = (byte) (0xff); 860 bytes[offset++] = (byte) (0xff); 861 isContinuationDss = true; 862 }else{ 863 endDss(); 865 866 } 867 868 } 869 870 871 private void writeExtendedLengthBytes (int extendedLengthByteCount, long length) 872 { 873 int shiftSize = (extendedLengthByteCount -1) * 8; 874 for (int i = 0; i < extendedLengthByteCount; i++) { 875 bytes[offset + i] = (byte) ((length >>> shiftSize) & 0xff); 876 shiftSize -= 8; 877 } 878 offset += extendedLengthByteCount; 879 } 880 881 882 void writeLengthCodePoint (int length, int codePoint) 888 { 889 ensureLength (4); 890 bytes[offset] = (byte) ((length >>> 8) & 0xff); 891 bytes[offset + 1] = (byte) (length & 0xff); 892 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 893 bytes[offset + 3] = (byte) (codePoint & 0xff); 894 offset +=4; 895 } 896 897 903 protected void writeScalarHeader (int codePoint, int dataLength) 904 { 905 ensureLength (dataLength + 4); 906 bytes[offset] = (byte) (((dataLength+4) >>> 8) & 0xff); 907 bytes[offset + 1] = (byte) ((dataLength+4) & 0xff); 908 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 909 bytes[offset + 3] = (byte) (codePoint & 0xff); 910 offset += 4; 911 } 912 913 920 void writeScalarString (int codePoint, String string) 921 { 922 int stringLength = string.length(); 923 ensureLength ((stringLength * 2) + 4); 924 bytes[offset] = (byte) (((stringLength+4) >>> 8) & 0xff); 925 bytes[offset + 1] = (byte) ((stringLength+4) & 0xff); 926 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 927 bytes[offset + 3] = (byte) (codePoint & 0xff); 928 offset = ccsidManager.convertFromUCS2 (string, bytes, offset + 4); 929 } 930 931 939 void writeScalarPaddedString (int codePoint, String string, int paddedLength) 940 { 941 int stringLength = string.length(); 942 int fillLength = paddedLength - stringLength; 943 ensureLength (paddedLength + 4); 944 bytes[offset] = (byte) (((paddedLength+4) >>> 8) & 0xff); 945 bytes[offset + 1] = (byte) ((paddedLength+4) & 0xff); 946 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 947 bytes[offset + 3] = (byte) (codePoint & 0xff); 948 offset = ccsidManager.convertFromUCS2 (string, bytes, offset + 4); 949 Arrays.fill(bytes,offset, offset + fillLength,ccsidManager.space); 950 offset += fillLength; 951 } 952 953 960 protected void writeScalarPaddedString (String string, int paddedLength) 961 { 962 int stringLength = string.length(); 963 964 int fillLength = paddedLength -stringLength; 965 ensureLength (paddedLength); 966 offset = ccsidManager.convertFromUCS2 (string, bytes, offset); 967 Arrays.fill(bytes,offset, offset + fillLength,ccsidManager.space); 968 offset += fillLength; 969 } 970 971 978 protected void writeScalarPaddedString (DRDAString drdaString, int paddedLength) 979 { 980 int stringLength = drdaString.length(); 981 int fillLength = paddedLength - stringLength; 982 ensureLength(paddedLength); 983 System.arraycopy(drdaString.getBytes(), 0, bytes, offset, stringLength); 984 offset += stringLength; 985 Arrays.fill(bytes, offset, offset + fillLength, ccsidManager.space); 986 offset += fillLength; 987 } 988 989 997 protected void writeScalarPaddedBytes (int codePoint, byte[] buf, int paddedLength, byte padByte) 998 { 999 int bufLength = buf.length; 1000 ensureLength (paddedLength + 4); 1001 bytes[offset] = (byte) (((paddedLength+4) >>> 8) & 0xff); 1002 bytes[offset + 1] = (byte) ((paddedLength+4) & 0xff); 1003 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 1004 bytes[offset + 3] = (byte) (codePoint & 0xff); 1005 offset += 4; 1006 System.arraycopy(buf,0,bytes,offset,bufLength); 1007 offset += bufLength; 1008 int fillLength = paddedLength - bufLength; 1009 Arrays.fill(bytes,offset,offset + fillLength,padByte); 1010 offset += fillLength; 1011 } 1012 1013 1020 protected void writeScalarPaddedBytes (byte[] buf, int paddedLength, byte padByte) 1021 { 1022 int bufLength = buf.length; 1023 int fillLength = paddedLength - bufLength; 1024 ensureLength (paddedLength); 1025 System.arraycopy(buf,0,bytes,offset,bufLength); 1026 offset +=bufLength; 1027 Arrays.fill(bytes,offset,offset + fillLength,padByte); 1028 offset += fillLength; 1029 } 1030 1031 1037 protected void writeScalarBytes (int codePoint, byte[] buf) 1038 { 1039 int bufLength = buf.length; 1040 ensureLength (bufLength + 4); 1041 bytes[offset] = (byte) (((bufLength+4) >>> 8) & 0xff); 1042 bytes[offset + 1] = (byte) ((bufLength+4) & 0xff); 1043 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 1044 bytes[offset + 3] = (byte) (codePoint & 0xff); 1045 System.arraycopy(buf,0,bytes,offset + 4,bufLength); 1046 offset += bufLength + 4; 1047 } 1048 1049 1057 protected void writeScalarBytes (int codePoint, byte[] buf, int start, int length) 1058 { 1059 if (SanityManager.DEBUG) 1060 { 1061 if (buf == null && length > start) 1062 SanityManager.THROWASSERT("Buf is null"); 1063 if (length - start > buf.length) 1064 SanityManager.THROWASSERT("Not enough bytes in buffer"); 1065 } 1066 int numBytes = length - start; 1067 ensureLength (numBytes + 4); 1068 bytes[offset] = (byte) (((numBytes+4) >>> 8) & 0xff); 1069 bytes[offset + 1] = (byte) ((numBytes+4) & 0xff); 1070 bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); 1071 bytes[offset + 3] = (byte) (codePoint & 0xff); 1072 offset += 4; 1073 System.arraycopy(buf,start,bytes,offset,numBytes); 1074 offset += numBytes; 1075 } 1076 1080 1085 protected void writeShort (int v) 1086 { 1087 writeNetworkShort(v); 1088 } 1089 1090 1095 protected void writeShort(boolean b) 1096 { 1097 writeNetworkShort(b ? 1 : 0); 1098 } 1099 1100 1105 protected void writeInt (int v) 1106 { 1107 writeNetworkInt(v); 1108 } 1109 1110 1115 protected void writeLong (long v) 1116 { 1117 ensureLength (8); 1118 bytes[offset] = (byte) ((v >>> 56) & 0xff); 1119 bytes[offset + 1] = (byte) ((v >>> 48) & 0xff); 1120 bytes[offset + 2] = (byte) ((v >>> 40) & 0xff); 1121 bytes[offset + 3] = (byte) ((v >>> 32) & 0xff); 1122 bytes[offset + 4] = (byte) ((v >>> 24) & 0xff); 1123 bytes[offset + 5] = (byte) ((v >>> 16) & 0xff); 1124 bytes[offset + 6] = (byte) ((v >>> 8) & 0xff); 1125 bytes[offset + 7] = (byte) ((v >>> 0) & 0xff); 1126 offset += 8; 1127 } 1128 1129 1134 protected void writeFloat (float v) 1135 { 1136 writeInt (Float.floatToIntBits (v)); 1137 } 1138 1139 1144 protected void writeDouble (double v) 1145 { 1146 writeLong (Double.doubleToLongBits (v)); 1147 } 1148 1149 1157 protected void writeBigDecimal (java.math.BigDecimal v, int precision, int scale) 1158 throws SQLException 1159 { 1160 int length = precision / 2 + 1; 1161 ensureLength (offset + length); 1162 bigDecimalToPackedDecimalBytes (v,precision, scale); 1163 offset += length; 1164 } 1165 1166 1171 protected void writeBoolean (boolean v) 1172 { 1173 ensureLength (1); 1174 bytes[offset++] = (byte) ((v ? 1 : 0) & 0xff); 1175 } 1176 1177 1184 protected void writeLDString(String s) throws DRDAProtocolException 1185 { 1186 writeLDString(s,0); 1187 } 1188 1189 1190 1197 protected void writeLDString(String s, int index) throws DRDAProtocolException 1198 { 1199 try { 1200 byte [] byteval = s.getBytes(NetworkServerControlImpl.DEFAULT_ENCODING); 1201 int origLen = byteval.length; 1202 boolean multiByteTrunc = false; 1203 int writeLen = 1204 java.lang.Math.min(FdocaConstants.LONGVARCHAR_MAX_LEN, 1205 origLen); 1206 1216 1217 if (SanityManager.DEBUG) 1218 { 1219 if (!(NetworkServerControlImpl.DEFAULT_ENCODING.equals("UTF8"))) 1220 SanityManager.THROWASSERT("Encoding assumed to be UTF8, but is actually" + NetworkServerControlImpl.DEFAULT_ENCODING); 1221 } 1222 1223 if (writeLen != origLen) 1224 while ((byteval[writeLen -1] & 0xC0) == 0x80) 1226 { 1227 multiByteTrunc = true; 1228 writeLen--; 1229 if (multiByteTrunc == true) 1232 { 1233 writeLen = writeLen -1; 1234 } 1235 } 1236 1237 writeShort(writeLen); 1238 writeBytes(byteval,writeLen); 1239 } 1240 catch (Exception e) { 1241 agent.agentError("Encoding " + NetworkServerControlImpl.DEFAULT_ENCODING + " not supported"); 1243 } 1244 } 1245 1246 1253 protected void writeString(String s) throws DRDAProtocolException 1254 { 1255 try { 1256 writeBytes(s.getBytes(NetworkServerControlImpl.DEFAULT_ENCODING)); 1257 } catch (Exception e) { 1258 agent.agentError("Encoding " + NetworkServerControlImpl.DEFAULT_ENCODING + " not supported"); 1260 } 1261 } 1262 1263 1271 protected void writeString(String s, int length) throws DRDAProtocolException 1272 { 1273 byte[] bs = null; 1274 try { 1275 bs = s.getBytes(NetworkServerControlImpl.DEFAULT_ENCODING); 1276 } catch (Exception e) { 1277 agent.agentError("Encoding " + NetworkServerControlImpl.DEFAULT_ENCODING + " not supported"); 1279 } 1280 int len = bs.length; 1281 if (len >= length) 1282 writeBytes(bs, length); 1283 else 1284 { 1285 writeBytes(bs); 1286 padBytes(NetworkServerControlImpl.SPACE_CHAR, length-len); 1287 } 1288 } 1289 1290 1296 protected void padBytes (byte val, int length) 1297 { 1298 Arrays.fill(bytes,offset, offset + length,val); 1299 offset += length; 1300 } 1301 1302 1308 protected void flush () throws java.io.IOException 1309 { 1310 flush(agent.getOutputStream()); 1311 } 1312 1313 1320 protected void flush(OutputStream socketOutputStream) 1321 throws java.io.IOException 1322 { 1323 try { 1324 socketOutputStream.write (bytes, 0, offset); 1325 socketOutputStream.flush(); 1326 } 1327 finally { 1328 if ((dssTrace != null) && dssTrace.isComBufferTraceOn()) { 1329 dssTrace.writeComBufferData (bytes, 1330 0, 1331 offset, 1332 DssTrace.TYPE_TRACE_SEND, 1333 "Reply", 1334 "flush", 1335 5); 1336 } 1337 reset(dssTrace); 1338 } 1339 } 1340 1341 1343 1365 private void beginDss (int dssType, boolean ensureLen) 1366 { 1367 1368 dssLengthLocation = offset; 1370 1371 if (ensureLen) 1373 ensureLength(6); 1374 1375 offset += 2; 1377 1378 bytes[offset] = (byte) 0xD0; 1380 1381 bytes[offset + 1] = (byte) dssType; 1387 bytes[offset + 1] |= DssConstants.DSSCHAIN_SAME_ID; 1388 1389 correlationID = getCorrelationID(); 1392 1393 bytes[offset + 2] = (byte) ((correlationID >>> 8) & 0xff); 1395 bytes[offset + 3] = (byte) (correlationID & 0xff); 1396 offset += 4; 1397 } 1398 1399 1408 private void finalizeDssLength () 1409 { 1410 int totalSize = offset - dssLengthLocation; 1415 int bytesRequiringContDssHeader = totalSize - DssConstants.MAX_DSS_LENGTH; 1416 1417 if (bytesRequiringContDssHeader > 0) 1419 { 1420 int contDssHeaderCount = bytesRequiringContDssHeader / 32765; 1425 if (bytesRequiringContDssHeader % 32765 != 0) 1426 contDssHeaderCount++; 1427 1428 int dataByte = offset - 1; 1439 int shiftSize = contDssHeaderCount * 2; 1440 ensureLength (shiftSize); 1441 offset += shiftSize; 1442 1443 1491 boolean passOne = true; 1494 do { 1495 int dataToShift = bytesRequiringContDssHeader % 32765; 1497 if (dataToShift == 0) 1498 dataToShift = 32765; 1499 int startOfCopyData = dataByte - dataToShift + 1; 1500 System.arraycopy(bytes,startOfCopyData, bytes, 1501 startOfCopyData + shiftSize, dataToShift); 1502 dataByte -= dataToShift; 1503 1504 1505 int twoByteContDssHeader = dataToShift + 2; 1510 if (passOne) 1511 passOne = false; 1512 else 1513 { 1514 if (twoByteContDssHeader == DssConstants.MAX_DSS_LENGTH) 1515 twoByteContDssHeader = (twoByteContDssHeader | 1516 DssConstants.CONTINUATION_BIT); 1517 1518 } 1519 1520 bytes[dataByte + shiftSize - 1] = (byte) 1522 ((twoByteContDssHeader >>> 8) & 0xff); 1523 bytes[dataByte + shiftSize] = (byte) 1524 (twoByteContDssHeader & 0xff); 1525 1526 bytesRequiringContDssHeader -= dataToShift; 1529 shiftSize -= 2; 1530 1531 } 1533 while (bytesRequiringContDssHeader > 0); 1534 1535 totalSize = (DssConstants.MAX_DSS_LENGTH | 1537 DssConstants.CONTINUATION_BIT); 1538 1539 1540 } 1541 1542 bytes[dssLengthLocation] = (byte) ((totalSize >>> 8) & 0xff); 1544 bytes[dssLengthLocation + 1] = (byte) (totalSize & 0xff); 1545 } 1546 1547 protected void writeExtendedLength(long size) 1548 { 1549 int numbytes = calculateExtendedLengthByteCount(size); 1550 if (size > 0) 1551 writeInt(0x8000 | numbytes); 1552 else 1553 writeInt(numbytes); 1554 } 1555 1556 1557 1565 private int calculateExtendedLengthByteCount (long ddmSize) 1566 { 1567 if (ddmSize <= 0x7fff) 1568 return 0; 1569 else if (ddmSize <= 0xffffffffL) 1574 return 4; 1575 else if (ddmSize <= 0xffffffffffffL) 1576 return 6; 1577 else if (ddmSize <= 0x7fffffffffffffffL) 1578 return 8; 1579 else 1580 return 0; 1583 } 1584 1585 1590 private void ensureLength (int length) 1591 { 1592 length += offset; 1593 if (length > bytes.length) { 1594 if (SanityManager.DEBUG) 1595 { 1596 agent.trace("DANGER - Expensive expansion of buffer"); 1597 } 1598 byte newBytes[] = new byte[Math.max (bytes.length << 1, length)]; 1599 System.arraycopy (bytes, 0, newBytes, 0, offset); 1600 bytes = newBytes; 1601 } 1602 } 1603 1604 1605 1614 private int bigDecimalToPackedDecimalBytes (java.math.BigDecimal b, 1615 int precision, int scale) 1616 throws SQLException 1617 { 1618 int declaredPrecision = precision; 1619 int declaredScale = scale; 1620 1621 if (declaredPrecision > 31) { 1624 clearDdm (); 1625 throw new java.sql.SQLException ("Packed decimal may only be up to 31 digits!"); 1626 } 1627 1628 String unscaledStr = b.unscaledValue().abs().toString(); 1630 1631 int bigPrecision = unscaledStr.length(); 1633 1634 if (bigPrecision > 31) 1635 { 1636 clearDdm (); 1637 throw new SQLException ("The numeric literal \"" + 1638 b.toString() + 1639 "\" is not valid because its value is out of range.", 1640 "42820", 1641 -405); 1642 } 1643 int bigScale = b.scale(); 1644 int bigWholeIntegerLength = bigPrecision - bigScale; 1645 if ( (bigWholeIntegerLength > 0) && (!unscaledStr.equals ("0")) ) { 1646 int declaredWholeIntegerLength = declaredPrecision - declaredScale; 1648 if (bigWholeIntegerLength > declaredWholeIntegerLength) 1649 { 1650 clearDdm (); 1651 throw new SQLException ("Overflow occurred during numeric data type conversion of \"" + 1652 b.toString() + 1653 "\".", 1654 "22003", 1655 -413); 1656 } 1657 } 1658 1659 1661 int zeroBase = '0'; 1663 1664 int packedIndex = declaredPrecision-1; 1666 1667 int bigIndex; 1669 1670 if (bigScale >= declaredScale) { 1671 1674 bigIndex = bigPrecision-1-(bigScale-declaredScale); 1676 1677 if (bigIndex < 0) { 1678 bytes[offset+(packedIndex+1)/2] = 1680 (byte) ( (b.signum()>=0)?12:13 ); } 1682 else { 1683 bytes[offset+(packedIndex+1)/2] = 1685 (byte) ( ( (unscaledStr.charAt(bigIndex)-zeroBase) << 4 ) + ( (b.signum()>=0)?12:13 ) ); } 1688 packedIndex-=2; 1689 bigIndex-=2; 1690 } 1691 else { 1692 1695 bigIndex = declaredScale-bigScale-1; 1697 1698 bytes[offset+(packedIndex+1)/2] = 1700 (byte) ( (b.signum()>=0)?12:13 ); 1702 for (packedIndex-=2, bigIndex-=2; bigIndex>=0; packedIndex-=2, bigIndex-=2) 1703 bytes[offset+(packedIndex+1)/2] = (byte) 0; 1704 1705 if (bigIndex == -1) { 1706 bytes[offset+(packedIndex+1)/2] = 1707 (byte) ( (unscaledStr.charAt(bigPrecision-1)-zeroBase) << 4 ); 1709 packedIndex-=2; 1710 bigIndex = bigPrecision-3; 1711 } 1712 else { 1713 bigIndex = bigPrecision-2; 1714 } 1715 } 1716 1717 for (; bigIndex>=0; packedIndex-=2, bigIndex-=2) { 1719 bytes[offset+(packedIndex+1)/2] = 1720 (byte) ( ( (unscaledStr.charAt(bigIndex)-zeroBase) << 4 ) + ( unscaledStr.charAt(bigIndex+1)-zeroBase ) ); } 1723 1724 if (bigIndex == -1) { 1726 bytes[offset+(packedIndex+1)/2] = 1727 (byte) (unscaledStr.charAt(0) - zeroBase); 1728 1729 packedIndex-=2; 1730 } 1731 1732 for (; packedIndex>=-1; packedIndex-=2) 1734 bytes[offset+(packedIndex+1)/2] = (byte) 0; 1735 1736 return declaredPrecision/2 + 1; 1737 } 1738 1739 1740 1748 public static String zeroPadString(String s, int precision) 1749 { 1750 1751 if (s == null) 1752 return s; 1753 1754 int slen = s.length(); 1755 if (precision == slen) 1756 return s; 1757 else if (precision > slen) 1758 { 1759 char[] ca = new char[precision - slen]; 1760 Arrays.fill(ca,0,precision - slen,'0'); 1761 return new String (ca) + s; 1762 } 1763 else 1764 { 1765 return s.substring(0,precision); 1768 } 1769 1770 } 1771 1772 1773 private void sendBytes (java.io.OutputStream socketOutputStream) 1774 throws java.io.IOException { 1775 1776 sendBytes(socketOutputStream, 1777 true); 1778 1779 } 1780 1781 1782 private void sendBytes (java.io.OutputStream socketOutputStream, 1783 boolean flashStream ) 1784 throws java.io.IOException 1785 { 1786 resetChainState(); 1787 try { 1788 socketOutputStream.write (bytes, 0, offset); 1789 if(flashStream) 1790 socketOutputStream.flush(); 1791 } 1792 finally { 1793 if ((dssTrace != null) && dssTrace.isComBufferTraceOn()) { 1794 dssTrace.writeComBufferData (bytes, 1795 0, 1796 offset, 1797 DssTrace.TYPE_TRACE_SEND, 1798 "Reply", 1799 "flush", 1800 5); 1801 } 1802 clearBuffer(); 1803 } 1804 } 1805 1806 protected String toDebugString(String indent) 1807 { 1808 String s = indent + "***** DDMWriter toDebugString ******\n"; 1809 int byteslen = 0; 1810 if ( bytes != null) 1811 byteslen = bytes.length; 1812 s += indent + "byte array length = " + bytes.length + "\n"; 1813 return s; 1814 } 1815 1816 1820 protected void resetChainState() 1821 { 1822 prevHdrLocation = -1; 1823 } 1824 1825 1830 private int getCorrelationID() { 1831 1832 int cId; 1833 if (previousCorrId != DssConstants.CORRELATION_ID_UNKNOWN) { 1834 if (previousChainByte == DssConstants.DSSCHAIN_SAME_ID) 1835 cId = previousCorrId; 1837 else 1838 cId = nextCorrelationID++; 1840 } 1841 else { 1842 cId = nextCorrelationID++; 1847 } 1848 1849 return cId; 1850 1851 } 1852 1853 1864 protected void finalizeChain(byte currChainByte, 1865 OutputStream socketOutputStream) throws DRDAProtocolException 1866 { 1867 1868 1872 if (prevHdrLocation != -1) { 1873 bytes[prevHdrLocation + 3] &= 0x0F; bytes[prevHdrLocation + 3] |= currChainByte; 1880 } 1881 1882 previousChainByte = currChainByte; 1884 1885 if (currChainByte != DssConstants.DSS_NOCHAIN) 1886 return; 1888 1889 1891 if ((SanityManager.DEBUG) && (agent != null)) 1892 agent.trace("Sending data"); 1893 1894 resetChainState(); 1895 if (doesRequestContainData()) { 1896 try { 1897 flush(socketOutputStream); 1898 } catch (java.io.IOException e) { 1899 agent.markCommunicationsFailure( 1900 "DDMWriter.finalizeChain()", 1901 "OutputStream.flush()", 1902 e.getMessage(),"*"); 1903 } 1904 } 1905 1906 } 1907 1908 1915 protected int markDSSClearPoint() 1916 { 1917 1918 lastDSSBeforeMark = prevHdrLocation; 1919 return offset; 1920 1921 } 1922 1923 1934 protected void clearDSSesBackToMark(int mark) 1935 { 1936 1937 offset = mark; 1939 1940 if (lastDSSBeforeMark == -1) 1948 nextCorrelationID = 1; 1950 else { 1951 nextCorrelationID = 1 + (int) 1955 (((bytes[lastDSSBeforeMark + 4] & 0xff) << 8) + 1956 (bytes[lastDSSBeforeMark + 5] & 0xff)); 1957 } 1958 1959 } 1960 1961 1962 private static int peekStream(InputStream in) throws IOException { 1963 1964 in.mark(1); 1965 1966 try{ 1967 return in.read(); 1968 1969 }finally{ 1970 in.reset(); 1971 1972 } 1973 } 1974 1975 1976 private static int getLayerBStreamingBufferSize(){ 1977 return PropertyUtil.getSystemInt( Property.DRDA_PROP_STREAMOUTBUFFERSIZE , 0 ); 1978 } 1979 1980 1981 private static OutputStream placeLayerBStreamingBuffer(OutputStream original){ 1982 1983 int size = getLayerBStreamingBufferSize(); 1984 1985 if(size < 1) 1986 return original; 1987 else 1988 return new BufferedOutputStream ( original, size ); 1989 1990 } 1991 1992} 1993 1994 | Popular Tags |