📄 ddmwriter.java
字号:
* Write padded scalar <code>DRDAString</code> object value. The * string is converted into the appropriate codeset. * * @param drdaString string to be written * @param paddedLength length to pad string to */ protected void writeScalarPaddedString (DRDAString drdaString, int paddedLength) { int stringLength = drdaString.length(); int fillLength = paddedLength - stringLength; ensureLength(paddedLength); System.arraycopy(drdaString.getBytes(), 0, bytes, offset, stringLength); offset += stringLength; Arrays.fill(bytes, offset, offset + fillLength, ccsidManager.space); offset += fillLength; } /** * Write padded scalar byte array object includes length, codepoint and value * * @param codePoint - code point to write * @param buf - byte array to be written * @param paddedLength - length to pad string to * @param padByte - byte to be used for padding */ protected void writeScalarPaddedBytes (int codePoint, byte[] buf, int paddedLength, byte padByte) { int bufLength = buf.length; ensureLength (paddedLength + 4); bytes[offset] = (byte) (((paddedLength+4) >>> 8) & 0xff); bytes[offset + 1] = (byte) ((paddedLength+4) & 0xff); bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); bytes[offset + 3] = (byte) (codePoint & 0xff); offset += 4; System.arraycopy(buf,0,bytes,offset,bufLength); offset += bufLength; int fillLength = paddedLength - bufLength; Arrays.fill(bytes,offset,offset + fillLength,padByte); offset += fillLength; } /** * Write padded scalar byte array object value * * @param buf - byte array to be written * @param paddedLength - length to pad string to * @param padByte - byte to be used for padding */ protected void writeScalarPaddedBytes (byte[] buf, int paddedLength, byte padByte) { int bufLength = buf.length; int fillLength = paddedLength - bufLength; ensureLength (paddedLength); System.arraycopy(buf,0,bytes,offset,bufLength); offset +=bufLength; Arrays.fill(bytes,offset,offset + fillLength,padByte); offset += fillLength; } /** * Write scalar byte array object includes length, codepoint and value * * @param codePoint - code point to write * @param buf - byte array to be written */ protected void writeScalarBytes (int codePoint, byte[] buf) { int bufLength = buf.length; ensureLength (bufLength + 4); bytes[offset] = (byte) (((bufLength+4) >>> 8) & 0xff); bytes[offset + 1] = (byte) ((bufLength+4) & 0xff); bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); bytes[offset + 3] = (byte) (codePoint & 0xff); System.arraycopy(buf,0,bytes,offset + 4,bufLength); offset += bufLength + 4; } /** * Write scalar byte array object includes length, codepoint and value * * @param codePoint - code point to write * @param buf - byte array to be written * @param start - starting point * @param length - length to write */ protected void writeScalarBytes (int codePoint, byte[] buf, int start, int length) { if (SanityManager.DEBUG) { if (buf == null && length > start) SanityManager.THROWASSERT("Buf is null"); if (length - start > buf.length) SanityManager.THROWASSERT("Not enough bytes in buffer"); } int numBytes = length - start; ensureLength (numBytes + 4); bytes[offset] = (byte) (((numBytes+4) >>> 8) & 0xff); bytes[offset + 1] = (byte) ((numBytes+4) & 0xff); bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff); bytes[offset + 3] = (byte) (codePoint & 0xff); offset += 4; System.arraycopy(buf,start,bytes,offset,numBytes); offset += numBytes; } // The following methods write data in the platform format // The platform format was indicated during connection time as ASC since // JCC doesn't read JVM platform (yet) /** * Write platform short * * @param v value to be written */ protected void writeShort (int v) { writeNetworkShort(v); } /** * Write boolean as short * @param b boolean value true = 1 false = 0 * */ protected void writeShort(boolean b) { writeNetworkShort(b ? 1 : 0); } /** * Write platform int * * @param v value to be written */ protected void writeInt (int v) { writeNetworkInt(v); } /** * Write platform long * * @param v value to be written */ protected void writeLong (long v) { ensureLength (8); bytes[offset] = (byte) ((v >>> 56) & 0xff); bytes[offset + 1] = (byte) ((v >>> 48) & 0xff); bytes[offset + 2] = (byte) ((v >>> 40) & 0xff); bytes[offset + 3] = (byte) ((v >>> 32) & 0xff); bytes[offset + 4] = (byte) ((v >>> 24) & 0xff); bytes[offset + 5] = (byte) ((v >>> 16) & 0xff); bytes[offset + 6] = (byte) ((v >>> 8) & 0xff); bytes[offset + 7] = (byte) ((v >>> 0) & 0xff); offset += 8; } /** * Write platform float * * @param v value to be written */ protected void writeFloat (float v) { writeInt (Float.floatToIntBits (v)); } /** * Write platform double * * @param v value to be written */ protected void writeDouble (double v) { writeLong (Double.doubleToLongBits (v)); } /** * Write big decimal to buffer * * @param v value to write * @param precision Precison of decimal or numeric type * @param scale declared scale * @exception SQLException thrown if number of digits > 31 */ protected void writeBigDecimal (java.math.BigDecimal v, int precision, int scale) throws SQLException { int length = precision / 2 + 1; ensureLength (offset + length); bigDecimalToPackedDecimalBytes (v,precision, scale); offset += length; } /** * Write platform boolean * * @param v value to be written */ protected void writeBoolean (boolean v) { ensureLength (1); bytes[offset++] = (byte) ((v ? 1 : 0) & 0xff); } /** * Write length delimited string * * @param s value to be written with integer * * @exception DRDAProtocolException */ protected void writeLDString(String s) throws DRDAProtocolException { writeLDString(s,0); } /** * Write length delimited string * * @param s value to be written with integer * @param index column index to put in warning * @exception DRDAProtocolException */ protected void writeLDString(String s, int index) throws DRDAProtocolException { try { byte [] byteval = s.getBytes(NetworkServerControlImpl.DEFAULT_ENCODING); int origLen = byteval.length; boolean multiByteTrunc = false; int writeLen = java.lang.Math.min(FdocaConstants.LONGVARCHAR_MAX_LEN, origLen); /* Need to make sure we truncate on character boundaries. We are assuming http://www.sun.com/developers/gadc/technicalpublications/articles/utf8.html To find the beginning of a multibyte character: 1) Does the current byte start with the bit pattern 10xxxxxx? 2) If yes, move left and go to step #1. 3) Finished We assume that NetworkServerControlImpl.DEFAULT_ENCODING remains UTF-8 */ if (SanityManager.DEBUG) { if (!(NetworkServerControlImpl.DEFAULT_ENCODING.equals("UTF8"))) SanityManager.THROWASSERT("Encoding assumed to be UTF8, but is actually" + NetworkServerControlImpl.DEFAULT_ENCODING); } if (writeLen != origLen) // first position on the first byte of the multibyte char while ((byteval[writeLen -1] & 0xC0) == 0x80) { multiByteTrunc = true; writeLen--; // Then subtract one more to get to the end of the // previous character if (multiByteTrunc == true) { writeLen = writeLen -1; } } writeShort(writeLen); writeBytes(byteval,writeLen); } catch (Exception e) { //this should never happen agent.agentError("Encoding " + NetworkServerControlImpl.DEFAULT_ENCODING + " not supported"); } } /** * Write string with default encoding * * @param s value to be written * * @exception DRDAProtocolException */ protected void writeString(String s) throws DRDAProtocolException { try { writeBytes(s.getBytes(NetworkServerControlImpl.DEFAULT_ENCODING)); } catch (Exception e) { //this should never happen agent.agentError("Encoding " + NetworkServerControlImpl.DEFAULT_ENCODING + " not supported"); } } /** * Write string with default encoding and specified length * * @param s value to be written * @param length number of bytes to be written * * @exception DRDAProtocolException */ protected void writeString(String s, int length) throws DRDAProtocolException { byte[] bs = null; try { bs = s.getBytes(NetworkServerControlImpl.DEFAULT_ENCODING); } catch (Exception e) { //this should never happen agent.agentError("Encoding " + NetworkServerControlImpl.DEFAULT_ENCODING + " not supported"); } int len = bs.length; if (len >= length) writeBytes(bs, length); else { writeBytes(bs); padBytes(NetworkServerControlImpl.SPACE_CHAR, length-len); } } /** * Write pad bytes using spaceChar * * @param val value to be written * @param length length to be written */ protected void padBytes (byte val, int length) { Arrays.fill(bytes,offset, offset + length,val); offset += length; } /** * Flush buffer to outputstream * * * @exception IOException */ protected void flush () throws java.io.IOException { flush(agent.getOutputStream()); } /** * Flush buffer to specified stream * * @param socketOutputStream * * @exception IOException */ protected void flush(OutputStream socketOutputStream) throws java.io.IOException { try { socketOutputStream.write (bytes, 0, offset); socketOutputStream.flush(); } finally { if ((dssTrace != null) && dssTrace.isComBufferTraceOn()) { dssTrace.writeComBufferData (bytes, 0, offset, DssTrace.TYPE_TRACE_SEND, "Reply", "flush", 5); } reset(dssTrace); } } // private methods /** * Write DSS header * DSS Header format is * 2 bytes - length * 1 byte - 'D0' - indicates DDM data * 1 byte - DSS format * |---|---------|----------| * | 0 | flags | type | * |---|---------|----------| * | 0 | 1 2 3 | 4 5 6 7 | * |---|---------|----------| * bit 0 - '0' * bit 1 - '0' - unchained, '1' - chained * bit 2 - '0' - do not continue on error, '1' - continue on error * bit 3 - '0' - next DSS has different correlator, '1' - next DSS has * same correlator * type - 1 - Request DSS * - 2 - Reply DSS * - 3 - Object DSS * - 4 - Communications DSS * - 5 - Request DSS where no reply is expected */ private void beginDss (int dssType, boolean ensureLen) { // save length position, the length will be written at the end dssLengthLocation = offset; // Should this really only be for non-stream DSSes? if (ensureLen) ensureLength(6); // Skip past length; we'll come back and set it later. offset += 2; // write gds info bytes[offset] = (byte) 0xD0; // Write DSS type, and default chain bit to be // DssConstants.DSSCHAIN_SAME_ID. This default // will be overridden by calls to "finalizeChain()" // and/or calls to "beginDss(boolean, int)" for // writing LOB data. bytes[offset + 1] = (byte) dssType; bytes[offset + 1] |= DssConstants.DSSCHAIN_SAME_ID; // save correlationID for use in error messages while processing // this DSS correlationID = getCorrelationID(); // write the reply correlation id bytes[offset + 2] = (byte) ((correlationID >>> 8) & 0xff); bytes[offset + 3] = (byte) (correlationID & 0xff); offset += 4; } /** * Finish a DSS Layer A object. * The length of dss object will be calculated based on the difference between the * start of the dss, saved on the beginDss call, and the current * offset into the buffer which marks the end of the data. In the event * the length requires the use of continuation Dss headers, one for each 32k * chunk of data, the data will be shifted and the continuation headers * will be inserted with the correct values as needed. */ private void finalizeDssLength () { // calculate the total size of the dss and the number of bytes which would // require continuation dss headers. The total length already includes the // the 6 byte dss header located at the beginning of the dss. It does not // include the length of any continuation headers. int totalSize = offset - dssLengthLocation; int bytesRequiringContDssHeader = totalSize - DssConstants.MAX_DSS_LENGTH; // determine if continuation headers are needed if (bytesRequiringContDssHeader > 0) { // the continuation headers are needed, so calculate how many. // after the first 32767 worth of data, a continuation header is // needed for every 32765 bytes (32765 bytes of data + 2 bytes of // continuation header = 32767 Dss Max Size). int contDssHeaderCount = bytesRequiringContDssHeader / 32765; if (bytesRequiringContDssHeader % 32765 != 0) contDssHeaderCount++; // right now the code will shift to the right. In the future we may want // to try something fancier to help reduce the copying (maybe keep // space in the beginning of the buffer??). // the offset points to the next available offset in the buffer to place // a piece of data, so the last dataByte is at offset -1. // various bytes will need to be shifted by different amounts // depending on how many dss headers to insert so the amount to shift // will be calculated and adjusted as needed. ensure there is enough room // for all the conutinuation headers and adjust the offset to point to the // new end of the data. int dataByte = offset - 1; int shiftSize = contDssHeaderCount * 2; ensureLength (shiftSize); offset += shiftSize; // Notes on the behavior of the Layer B segmenting loop below: // // We start with the right most chunk. For a 3-segment object we'd // shift 2 segments: shift the first (rightmost) one 4 bytes and // the second one 2. Note that by 'first' we mean 'first time // through the loop', but that is actually the last segment // of data since we are moving right-to-left. For an object // of K segments we will pass through this loop K-1 times. // The 0th (leftmost) segment is not shifted, as it is // already in the right place. When we are done, we will // have made room in each segment for an additional // 2 bytes for the continuation header. Thus, each // segment K is shifted K*2 bytes to the right. // // Each time through the loop, "dataByte" points to the // last byte in the segment; "dataToShift" is the amount of // data that we need to shift, and "shiftSize" is the // distance that we need to shift it. Since dataByte points // at the last byte, not one byte beyond it (as with the // "offset" variable used elsewhere in DDMWriter), the start // of the segement is actually at (dataByte-dataToShift+1). // // After we have shifted the segment, we move back to the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -