db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t...@apache.org
Subject svn commit: r410570 [2/4] - in /db/derby/code/trunk/java: drda/org/apache/derby/impl/drda/ engine/org/apache/derby/iapi/reference/
Date Wed, 31 May 2006 16:07:46 GMT

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java?rev=410570&r1=410569&r2=410570&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java Wed May 31 09:07:45 2006
@@ -1,22 +1,22 @@
 /*
 
-Derby - Class org.apache.derby.impl.drda.DDMWriter
+   Derby - Class org.apache.derby.impl.drda.DDMWriter
 
-Copyright 2001, 2004 The Apache Software Foundation or its licensors, as applicable.
+   Copyright 2001, 2004 The Apache Software Foundation or its licensors, as applicable.
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
 
-http://www.apache.org/licenses/LICENSE-2.0
+      http://www.apache.org/licenses/LICENSE-2.0
 
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
 
-*/
+ */
 
 package org.apache.derby.impl.drda;
 
@@ -36,377 +36,395 @@
 import java.io.IOException;
 
 /**
-   The DDMWriter is used to write DRDA protocol.   The DRDA Protocol is
-   described in the DDMReader class.
-   For more details, see DRDA Volume 3 (Distributed Data Management(DDM)
-   Architecture (DDS definition)
+	The DDMWriter is used to write DRDA protocol.   The DRDA Protocol is
+	described in the DDMReader class.
+	For more details, see DRDA Volume 3 (Distributed Data Management(DDM)
+		Architecture (DDS definition)
 */
-class DDMWriter {
-    
-
-    // number of nesting levels for collections.  We need to mark the length
-    // location of the collection so that we can update it as we add more stuff
-    // to the collection
-    private final static int MAX_MARKS_NESTING = 10;
-
-    // Default buffer size
-    private final static int DEFAULT_BUFFER_SIZE = 32767;
-
-
-    static final BigDecimal ZERO = BigDecimal.valueOf(0L);
-
-    // output buffer
-    private byte[] bytes;
-
-    // offset into output buffer
-    private int offset;
-
-    // A saved mark in the stream is saved temporarily to revisit the location.
-    private int[] markStack = new int[MAX_MARKS_NESTING];
-
-    // top of the stack
-    private int top;
-
-    // CCSID manager for translation of strings in the protocol to EBCDIC
-    private CcsidManager ccsidManager;
-
-    // DRDA connection thread for this writer
-    private DRDAConnThread agent;
-
-    //  This Object tracks the location of the current
-    //  Dss header length bytes.        This is done so
-    //  the length bytes can be automatically
-    //  updated as information is added to this stream.
-    private int dssLengthLocation;
-
-    // Current correlation ID
-    private     int correlationID;
-
-    // Next correlation ID
-    private int nextCorrelationID;
-
-    // is this DRDA protocol or CMD protocol
-    private boolean isDRDAProtocol;
-    // trace object of the associated session
-    private DssTrace dssTrace;
-
-    // Location within the "bytes" array of the start of the header
-    // of the DSS most recently written to the buffer.
-    private int prevHdrLocation;
-
-    // Correlation id of the last DSS that was written to buffer.
-    private int previousCorrId;
-
-    // Chaining bit of the last DSS that was written to buffer.
-    private byte previousChainByte;
-
-    // Whether or not the current DSS is a continuation DSS.
-    private boolean isContinuationDss;
-
-    // In situations where we want to "mark" a buffer location so that
-    // we can "back-out" of a write to handle errors, this holds the
-    // location within the "bytes" array of the start of the header
-    // that immediately precedes the mark.
-    private int lastDSSBeforeMark;
-
-    // Constructors
-    DDMWriter (int minSize, CcsidManager ccsidManager, DRDAConnThread agent, DssTrace dssTrace) {
-        this.bytes = new byte[minSize];
-        this.ccsidManager = ccsidManager;
-        this.agent = agent;
-        this.prevHdrLocation = -1;
-        this.previousCorrId = DssConstants.CORRELATION_ID_UNKNOWN;
-        this.previousChainByte = DssConstants.DSS_NOCHAIN;
-        this.isContinuationDss = false;
-        this.lastDSSBeforeMark = -1;
-        reset(dssTrace);
-    }
-
-    DDMWriter (CcsidManager ccsidManager, DRDAConnThread agent, DssTrace dssTrace) {
-        this.bytes = new byte[DEFAULT_BUFFER_SIZE];
-        this.ccsidManager = ccsidManager;
-        this.agent = agent;
-        this.prevHdrLocation = -1;
-        this.previousCorrId = DssConstants.CORRELATION_ID_UNKNOWN;
-        this.previousChainByte = DssConstants.DSS_NOCHAIN;
-        this.isContinuationDss = false;
-        this.lastDSSBeforeMark = -1;
-        reset(dssTrace);
-    }
-
-    /**
-     * reset values for sending next message
-     *
-     */
-    protected void reset(DssTrace dssTrace) {
-        offset = 0;
-        top = 0;
-        dssLengthLocation = 0;
-        nextCorrelationID = 1;
-        correlationID = DssConstants.CORRELATION_ID_UNKNOWN;
-        isDRDAProtocol = true;
-        this.dssTrace = dssTrace;
-    }
-
-    /**
-     * set protocol to CMD protocol
-     */
-    protected void setCMDProtocol() {
-        isDRDAProtocol = false;
-    }
-
-    /**
-     * Create DSS reply object
-     */
-    protected void createDssReply() {
-        beginDss(DssConstants.DSSFMT_RPYDSS, true);
-    }
-
-    /**
-     * Create DSS request object
-     * NOTE: This is _ONLY_ used for testing the protocol
-     * (via the TestProto.java file in this package)!
-     * We should never create a DSS request in normal
-     * DRDA processing (we should only create DSS replies
-     * and DSS objects).
-     */
-    protected void createDssRequest() {
-        beginDss(DssConstants.DSSFMT_RQSDSS, true);
-    }
+class DDMWriter
+{
 
-    /**
-     * Create DSS data object
-     */
-    protected void createDssObject() {
-        beginDss(DssConstants.DSSFMT_OBJDSS, true);
-    }
+	// number of nesting levels for collections.  We need to mark the length
+	// location of the collection so that we can update it as we add more stuff
+	// to the collection
+	private final static int MAX_MARKS_NESTING = 10;
+
+	// Default buffer size
+	private final static int DEFAULT_BUFFER_SIZE = 32767;
+
+
+	static final BigDecimal ZERO = BigDecimal.valueOf(0L);
+
+	// output buffer
+	private byte[] bytes;
+
+	// offset into output buffer
+	private int offset;
+
+	// A saved mark in the stream is saved temporarily to revisit the location.
+	private int[] markStack = new int[MAX_MARKS_NESTING];
+
+	// top of the stack
+	private int top;
+
+	// CCSID manager for translation of strings in the protocol to EBCDIC
+	private CcsidManager ccsidManager;
+
+	// DRDA connection thread for this writer
+	private DRDAConnThread agent;
+
+	//	This Object tracks the location of the current
+	//	Dss header length bytes.	This is done so
+	//	the length bytes can be automatically
+	//	updated as information is added to this stream.
+	private int dssLengthLocation;
+
+	// Current correlation ID
+	private	int correlationID;
+
+	// Next correlation ID
+	private int nextCorrelationID;
+
+	// is this DRDA protocol or CMD protocol
+	private boolean isDRDAProtocol;
+	// trace object of the associated session
+	private DssTrace dssTrace;
+
+	// Location within the "bytes" array of the start of the header
+	// of the DSS most recently written to the buffer.
+	private int prevHdrLocation;
+
+	// Correlation id of the last DSS that was written to buffer.
+	private int previousCorrId;
+
+	// Chaining bit of the last DSS that was written to buffer.
+	private byte previousChainByte;
+
+	// Whether or not the current DSS is a continuation DSS.
+	private boolean isContinuationDss;
+
+	// In situations where we want to "mark" a buffer location so that
+	// we can "back-out" of a write to handle errors, this holds the
+	// location within the "bytes" array of the start of the header
+	// that immediately precedes the mark.
+	private int lastDSSBeforeMark;
+
+	// Constructors
+	DDMWriter (int minSize, CcsidManager ccsidManager, DRDAConnThread agent, DssTrace dssTrace)
+	{
+		this.bytes = new byte[minSize];
+		this.ccsidManager = ccsidManager;
+		this.agent = agent;
+		this.prevHdrLocation = -1;
+		this.previousCorrId = DssConstants.CORRELATION_ID_UNKNOWN;
+		this.previousChainByte = DssConstants.DSS_NOCHAIN;
+		this.isContinuationDss = false;
+		this.lastDSSBeforeMark = -1;
+		reset(dssTrace);
+	}
+
+	DDMWriter (CcsidManager ccsidManager, DRDAConnThread agent, DssTrace dssTrace)
+	{
+		this.bytes = new byte[DEFAULT_BUFFER_SIZE];
+		this.ccsidManager = ccsidManager;
+		this.agent = agent;
+		this.prevHdrLocation = -1;
+		this.previousCorrId = DssConstants.CORRELATION_ID_UNKNOWN;
+		this.previousChainByte = DssConstants.DSS_NOCHAIN;
+		this.isContinuationDss = false;
+		this.lastDSSBeforeMark = -1;
+		reset(dssTrace);
+	}
+
+	/**
+	 * reset values for sending next message
+	 *
+	 */
+	protected void reset(DssTrace dssTrace)
+	{
+		offset = 0;
+		top = 0;
+		dssLengthLocation = 0;
+		nextCorrelationID = 1;
+		correlationID = DssConstants.CORRELATION_ID_UNKNOWN;
+		isDRDAProtocol = true;
+		this.dssTrace = dssTrace;
+	}
+
+	/**
+	 * set protocol to CMD protocol
+	 */
+	protected void setCMDProtocol()
+	{
+		isDRDAProtocol = false;
+	}
+
+	/**
+	 * Create DSS reply object
+	 */
+	protected void createDssReply()
+	{
+		beginDss(DssConstants.DSSFMT_RPYDSS, true);
+	}
+
+	/**
+	 * Create DSS request object
+	 * NOTE: This is _ONLY_ used for testing the protocol
+	 * (via the TestProto.java file in this package)!
+	 * We should never create a DSS request in normal
+	 * DRDA processing (we should only create DSS replies
+	 * and DSS objects).
+	 */
+	protected void createDssRequest()
+	{
+		beginDss(DssConstants.DSSFMT_RQSDSS, true);
+	}
+
+	/**
+	 * Create DSS data object
+	 */
+	protected void createDssObject()
+	{
+		beginDss(DssConstants.DSSFMT_OBJDSS, true);
+	}
+
+	/**
+	 * Mark the DSS that we're currently writing as
+	 * a continued DSS, which is done by setting
+	 * the high-order bit to "1", per DDM spec.
+	 * This means:
+	 *
+	 *	1. One or more continuation DSSes will immediately
+	 * 		follow the current (continued) DSS.
+	 *	2. All continuation DSSes will have a 2-byte
+	 * 		continuation header, followed by data; in
+	 * 		other words, chaining state, correlation
+	 *		id, dss format info, and code point will
+	 * 		NOT be included.  All of that info is 
+	 * 		present ONLY in the FIRST DSS in the
+	 *		list of continued DSSes.
+	 *
+	 *	NOTE: A DSS can be a "continuation" DSS _and_
+	 * 	a "continued" DSS at the same time.  However,
+	 * 	the FIRST DSS to be continued canNOT be
+	 *	a continuation DSS.
+	 */
+	private void markDssAsContinued(boolean forLob)
+	{
+
+		if (!forLob) {
+		// continuation bit defaults to '1' for lobs, so
+		// we only have to switch it if we're not writing
+		// lobs.
+			bytes[dssLengthLocation] |= 0x80;
+		}
+
+		// We need to set the chaining state, but ONLY
+		// IF this is the FIRST DSS in the continuation
+		// list (only the first one has chaining state
+		// in it's header; the others do not).
+		if (!isContinuationDss)
+			endDss(!forLob);
+
+	}
+
+	/**
+	 * End DSS header by writing the length in the length location
+	 * and setting the chain bit.  Unlike the other two endDss
+	 * methods, this one overrides the default chaining byte
+	 * (which is set in beginDss) with the chaining byte that
+	 * is passed in.  NOTE: This method is only used in
+	 * association with createDssRequest, and thus is for
+	 * TESTING purposes only (via TestProto.java).  No calls
+	 * should be made to this method in normal DRDA processing
+	 * (because for normal processing, chaining must be
+	 * determined automatically based on DSS requests).
+	 */
+	protected void endDss(byte chainByte)
+	{
+
+		// Do regular endDss processing.
+		endDss(true);
+
+		// Now override default chain state.
+		bytes[dssLengthLocation + 3] &= 0x0F;	// Zero out default
+		bytes[dssLengthLocation + 3] |= chainByte;
+		previousChainByte = chainByte;
+
+	}
+
+	/**
+	 * End DSS header by writing the length in the length location
+	 * and setting the chain bit.
+	 */
+	protected void endDss() {
+		endDss(true);
+	}
+
+	/**
+	 * End DSS header by writing the length in the length location
+	 * and setting the chain bit.
+	 */
+	private void endDss (boolean finalizeLength)
+	{
+
+		if (finalizeLength)
+			finalizeDssLength();
+
+		if (isContinuationDss) {
+		// no chaining information for this DSS; so we're done.
+			isContinuationDss = false;
+			return;
+		}
+
+		previousCorrId = correlationID;
+		prevHdrLocation = dssLengthLocation;
+		previousChainByte = DssConstants.DSSCHAIN_SAME_ID;
+
+	}
+
+	/**
+	 * End final DDM and DSS header by writing the length in the length location
+	 *
+	 */
+	protected void endDdmAndDss ()
+	{
+		endDdm();	// updates last DDM object
+		endDss();
+	}
+	/**
+	 * Copy Data to End
+	 * Create a buffer and copy from the position given to the end of data
+	 *
+	 * Note that the position given is treated as relative to the
+	 * current DSS, for there may be other DSS blocks (chained, presumably)
+	 * which are sitting unwritten in the buffer. The caller doesn't
+	 * know this, though, and works only with the current DSS.
+	 *
+	 * getDSSLength, copyDSSDataToEnd, and truncateDSS work together to
+	 * provide a sub-protocol for DRDAConnThread to use in its
+	 * implementation of the LMTBLKPRC protocol. They enable the caller
+	 * to determine when it has written too much data into the current
+	 * DSS, to reclaim the extra data that won't fit, and to truncate
+	 * that extra data once it has been reclaimed and stored elsewhere.
+	 * Note that this support only works for the current DSS. Earlier,
+	 * chained DSS blocks cannot be accessed using these methods. For
+	 * additional background information, the interested reader should
+	 * investigate bugs DERBY-491 and 492 at:
+	 * http://issues.apache.org/jira/browse/DERBY-491 and
+	 * http://issues.apache.org/jira/browse/DERBY-492
+	 *
+	 * @param start
+	 */
+	protected byte [] copyDSSDataToEnd(int start)
+	{
+		start = start + dssLengthLocation;
+		int length = offset - start;
+		byte [] temp = new byte[length];
+		System.arraycopy(bytes,start,temp,0,length);
+		return temp;
+	}
+
+	// Collection methods
+
+	/**
+	 * Mark the location of the length bytes for the collection so they
+	 * can be updated later
+	 *
+	 */
+	protected void startDdm (int codePoint)
+	{
+		// save the location of the beginning of the collection so
+		// that we can come back and fill in the length bytes
+		markStack[top++] = offset;
+		ensureLength (4); // verify space for length bytes and code point
+		offset += 2; // move past the length bytes before writing the code point
+		bytes[offset] = (byte) ((codePoint >>> 8) & 0xff);
+		bytes[offset + 1] = (byte) (codePoint & 0xff);
+		offset += 2;
+	}
+
+	/**
+	 * Erase all writes for the current ddm and reset the
+	 * top
+	 */
+	protected void clearDdm ()
+	{
+		offset = markStack[top--];
+	}
+
+	/**
+	 * Clear the entire send buffer
+	 *
+	 */
+	protected void clearBuffer()
+	{
+		offset = 0;
+		top = 0;
+		dssLengthLocation = 0;
+		correlationID = DssConstants.CORRELATION_ID_UNKNOWN;
+		nextCorrelationID = 1;
+		isDRDAProtocol = true;
+	}
+
+	/**
+	 * End the current DDM
+	 *
+	 */
+	protected void endDdm ()
+	{
+		// remove the top length location offset from the mark stack
+		// calculate the length based on the marked location and end of data.
+		int lengthLocation = markStack[--top];
+		int length = offset - lengthLocation;
+
+		// determine if any extended length bytes are needed.	the value returned
+		// from calculateExtendedLengthByteCount is the number of extended length
+		// bytes required. 0 indicates no exteneded length.
+		int extendedLengthByteCount = calculateExtendedLengthByteCount (length);
+		if (extendedLengthByteCount != 0)
+		{
+			// ensure there is enough room in the buffer for the extended length bytes.
+			ensureLength (extendedLengthByteCount);
+
+			// calculate the length to be placed in the extended length bytes.
+			// this length does not include the 4 byte llcp.
+			int extendedLength = length - 4;
+
+			// shift the data to the right by the number of extended
+			// length bytes needed.
+			int extendedLengthLocation = lengthLocation + 4;
+			System.arraycopy (bytes,
+					              extendedLengthLocation,
+					              bytes,
+					              extendedLengthLocation + extendedLengthByteCount,
+					              extendedLength);
+
+			// write the extended length
+			int shiftSize = (extendedLengthByteCount -1) * 8;
+			for (int i = 0; i < extendedLengthByteCount; i++)
+			{
+				bytes[extendedLengthLocation++] =
+					(byte) ((extendedLength >>> shiftSize ) & 0xff);
+				shiftSize -= 8;
+			}
+
+			// adjust the offset to account for the shift and insert
+			offset += extendedLengthByteCount;
+
+			// the two byte length field before the codepoint contains the length
+			// of itself, the length of the codepoint, and the number of bytes used
+			// to hold the extended length.	the 2 byte length field also has the first
+			// bit on to indicate extended length bytes were used.
+			length = extendedLengthByteCount + 4;
+			length |= DssConstants.CONTINUATION_BIT;
+		}
+
+		// write the 2 byte length field (2 bytes before codepoint).
+		bytes[lengthLocation] = (byte) ((length >>> 8) & 0xff);
+		bytes[lengthLocation+1] = (byte) (length & 0xff);
 
-    /**
-     * Mark the DSS that we're currently writing as
-     * a continued DSS, which is done by setting
-     * the high-order bit to "1", per DDM spec.
-     * This means:
-     *
-     *  1. One or more continuation DSSes will immediately
-     *          follow the current (continued) DSS.
-     *  2. All continuation DSSes will have a 2-byte
-     *          continuation header, followed by data; in
-     *          other words, chaining state, correlation
-     *          id, dss format info, and code point will
-     *          NOT be included.  All of that info is 
-     *          present ONLY in the FIRST DSS in the
-     *          list of continued DSSes.
-     *
-     *  NOTE: A DSS can be a "continuation" DSS _and_
-     *  a "continued" DSS at the same time.  However,
-     *  the FIRST DSS to be continued canNOT be
-     *  a continuation DSS.
-     */
-    private void markDssAsContinued(boolean forLob) {
-
-        if (!forLob) {
-            // continuation bit defaults to '1' for lobs, so
-            // we only have to switch it if we're not writing
-            // lobs.
-            bytes[dssLengthLocation] |= 0x80;
-        }
-
-        // We need to set the chaining state, but ONLY
-        // IF this is the FIRST DSS in the continuation
-        // list (only the first one has chaining state
-        // in it's header; the others do not).
-        if (!isContinuationDss)
-            endDss(!forLob);
-
-    }
-
-    /**
-     * End DSS header by writing the length in the length location
-     * and setting the chain bit.  Unlike the other two endDss
-     * methods, this one overrides the default chaining byte
-     * (which is set in beginDss) with the chaining byte that
-     * is passed in.  NOTE: This method is only used in
-     * association with createDssRequest, and thus is for
-     * TESTING purposes only (via TestProto.java).  No calls
-     * should be made to this method in normal DRDA processing
-     * (because for normal processing, chaining must be
-     * determined automatically based on DSS requests).
-     */
-    protected void endDss(byte chainByte) {
-
-        // Do regular endDss processing.
-        endDss(true);
-
-        // Now override default chain state.
-        bytes[dssLengthLocation + 3] &= 0x0F;   // Zero out default
-        bytes[dssLengthLocation + 3] |= chainByte;
-        previousChainByte = chainByte;
-
-    }
-
-    /**
-     * End DSS header by writing the length in the length location
-     * and setting the chain bit.
-     */
-    protected void endDss() {
-        endDss(true);
-    }
-
-    /**
-     * End DSS header by writing the length in the length location
-     * and setting the chain bit.
-     */
-    private void endDss (boolean finalizeLength) {
-
-        if (finalizeLength)
-            finalizeDssLength();
-
-        if (isContinuationDss) {
-            // no chaining information for this DSS; so we're done.
-            isContinuationDss = false;
-            return;
-        }
-
-        previousCorrId = correlationID;
-        prevHdrLocation = dssLengthLocation;
-        previousChainByte = DssConstants.DSSCHAIN_SAME_ID;
-
-    }
-
-    /**
-     * End final DDM and DSS header by writing the length in the length location
-     *
-     */
-    protected void endDdmAndDss () {
-        endDdm();       // updates last DDM object
-        endDss();
-    }
-    /**
-     * Copy Data to End
-     * Create a buffer and copy from the position given to the end of data
-     *
-     * Note that the position given is treated as relative to the
-     * current DSS, for there may be other DSS blocks (chained, presumably)
-     * which are sitting unwritten in the buffer. The caller doesn't
-     * know this, though, and works only with the current DSS.
-     *
-     * getDSSLength, copyDSSDataToEnd, and truncateDSS work together to
-     * provide a sub-protocol for DRDAConnThread to use in its
-     * implementation of the LMTBLKPRC protocol. They enable the caller
-     * to determine when it has written too much data into the current
-     * DSS, to reclaim the extra data that won't fit, and to truncate
-     * that extra data once it has been reclaimed and stored elsewhere.
-     * Note that this support only works for the current DSS. Earlier,
-     * chained DSS blocks cannot be accessed using these methods. For
-     * additional background information, the interested reader should
-     * investigate bugs DERBY-491 and 492 at:
-     * http://issues.apache.org/jira/browse/DERBY-491 and
-     * http://issues.apache.org/jira/browse/DERBY-492
-     *
-     * @param start
-     */
-    protected byte [] copyDSSDataToEnd(int start) {
-        start = start + dssLengthLocation;
-        int length = offset - start;
-        byte [] temp = new byte[length];
-        System.arraycopy(bytes,start,temp,0,length);
-        return temp;
-    }
-
-    // Collection methods
-
-    /**
-     * Mark the location of the length bytes for the collection so they
-     * can be updated later
-     *
-     */
-    protected void startDdm (int codePoint) {
-        // save the location of the beginning of the collection so
-        // that we can come back and fill in the length bytes
-        markStack[top++] = offset;
-        ensureLength (4); // verify space for length bytes and code point
-        offset += 2; // move past the length bytes before writing the code point
-        bytes[offset] = (byte) ((codePoint >>> 8) & 0xff);
-        bytes[offset + 1] = (byte) (codePoint & 0xff);
-        offset += 2;
-    }
-
-    /**
-     * Erase all writes for the current ddm and reset the
-     * top
-     */
-    protected void clearDdm () {
-        offset = markStack[top--];
-    }
-
-    /**
-     * Clear the entire send buffer
-     *
-     */
-    protected void clearBuffer() {
-        offset = 0;
-        top = 0;
-        dssLengthLocation = 0;
-        correlationID = DssConstants.CORRELATION_ID_UNKNOWN;
-        nextCorrelationID = 1;
-        isDRDAProtocol = true;
-    }
-
-    /**
-     * End the current DDM
-     *
-     */
-    protected void endDdm () {
-        // remove the top length location offset from the mark stack
-        // calculate the length based on the marked location and end of data.
-        int lengthLocation = markStack[--top];
-        int length = offset - lengthLocation;
-
-        // determine if any extended length bytes are needed.   the value returned
-        // from calculateExtendedLengthByteCount is the number of extended length
-        // bytes required. 0 indicates no exteneded length.
-        int extendedLengthByteCount = calculateExtendedLengthByteCount (length);
-        if (extendedLengthByteCount != 0) {
-            // ensure there is enough room in the buffer for the extended length bytes.
-            ensureLength (extendedLengthByteCount);
-
-            // calculate the length to be placed in the extended length bytes.
-            // this length does not include the 4 byte llcp.
-            int extendedLength = length - 4;
-
-            // shift the data to the right by the number of extended
-            // length bytes needed.
-            int extendedLengthLocation = lengthLocation + 4;
-            System.arraycopy (bytes,
-                              extendedLengthLocation,
-                              bytes,
-                              extendedLengthLocation + extendedLengthByteCount,
-                              extendedLength);
-
-            // write the extended length
-            int shiftSize = (extendedLengthByteCount -1) * 8;
-            for (int i = 0; i < extendedLengthByteCount; i++) {
-                bytes[extendedLengthLocation++] =
-                    (byte) ((extendedLength >>> shiftSize ) & 0xff);
-                shiftSize -= 8;
-            }
-
-            // adjust the offset to account for the shift and insert
-            offset += extendedLengthByteCount;
-
-            // the two byte length field before the codepoint contains the length
-            // of itself, the length of the codepoint, and the number of bytes used
-            // to hold the extended length.     the 2 byte length field also has the first
-            // bit on to indicate extended length bytes were used.
-            length = extendedLengthByteCount + 4;
-            length |= DssConstants.CONTINUATION_BIT;
-        }
-
-        // write the 2 byte length field (2 bytes before codepoint).
-        bytes[lengthLocation] = (byte) ((length >>> 8) & 0xff);
-        bytes[lengthLocation+1] = (byte) (length & 0xff);
-
-    }
+	}
 
     /**
      * Get the length of the current DSS block we're working on. This is
@@ -416,8 +434,9 @@
      * DSS block when splitting a QRYDTA response.
      *
      * @return current DSS block length
-     */
-    protected int getDSSLength() {
+    */
+    protected int getDSSLength()
+    {
         return offset - dssLengthLocation;
     }
  
@@ -427,301 +446,323 @@
      * calling copyDSSDataToEnd
      *
      * @param value DSS length
-     */
-    protected void truncateDSS(int value) {
+    */
+    protected void truncateDSS(int value)
+    {
         offset = dssLengthLocation + value;
     }
 
 
-    // Write routines
+	// Write routines
 
-    /**
-     * Write byte
-     *
-     * @param   value   byte to be written
-     */
-    protected void writeByte (int value) {
-        if (SanityManager.DEBUG) {
-            if (value > 255)
-                SanityManager.THROWASSERT(
-                                          "writeByte value: " + value +
-                                          " may not be > 255");
-        }
-
-        ensureLength (1);
-        bytes[offset++] = (byte) (value & 0xff);
-    }
-
-
-    /**
-     * Write network short
-     *
-     * @param   value   value to be written
-     */
-    protected void writeNetworkShort (int value) {
-        ensureLength (2);
-        bytes[offset] = (byte) ((value >>> 8) & 0xff);
-        bytes[offset + 1] = (byte) (value & 0xff);
-        offset += 2;
-    }
-
-    /**
-     * Write network int
-     *
-     * @param   value   value to be written
-     */
-    protected void writeNetworkInt (int value) {
-        ensureLength (4);
-        bytes[offset] = (byte) ((value >>> 24) & 0xff);
-        bytes[offset + 1] = (byte) ((value >>> 16) & 0xff);
-        bytes[offset + 2] = (byte) ((value >>> 8) & 0xff);
-        bytes[offset + 3] = (byte) (value & 0xff);
-        offset += 4;
-    }
-
-
-    /**
-     * Write byte array
-     *
-     * @param   buf     byte array to be written
-     * @param   length  - length to write
-     */
-    protected void writeBytes (byte[] buf, int length) {
-        writeBytes(buf, 0,length);
-    }
-
-
-
-    /**
-     * Write byte array
-     *
-     * @param   buf     byte array to be written
-     * @param   start  - starting position
-     * @param   length  - length to write
-     */
-    protected void writeBytes (byte[] buf, int start, int length) {
-
-        if (SanityManager.DEBUG) {
-            if (buf == null && length > 0)
-                SanityManager.THROWASSERT("Buf is null");
-            if (length + start - 1 > buf.length)
-                SanityManager.THROWASSERT("Not enough bytes in buffer");
-
-        }
-        ensureLength (length);
-        System.arraycopy(buf,start,bytes,offset,length);
-        offset += length;
-    }
-    /**
-     * Write byte array
-     *
-     * @param   buf     byte array to be written
-     **/
-    protected void writeBytes (byte[] buf) {
-        writeBytes(buf,buf.length);
-    }
-
-
-
-    protected void writeLDBytes(byte[] buf) {
-        writeLDBytes(buf, 0);
-    }
-
-    protected void writeLDBytes(byte[] buf, int index) {
-
-        int length = buf.length;
-        int writeLen =  buf.length;
-
-        writeShort(writeLen);
-
-        writeBytes(buf,0,writeLen);
-    }
-
-
-    /**
-     * Write code point and 4 bytes
-     *
-     * @param   codePoint - code point to write
-     * @param   value  - value to write after code point
-     */
-    void writeCodePoint4Bytes (int codePoint, int value) {
-        ensureLength (4);
-        bytes[offset] = (byte) ((codePoint >>> 8) & 0xff);
-        bytes[offset + 1] = (byte) (codePoint & 0xff);
-        bytes[offset + 2] = (byte) ((value >>> 8) & 0xff);
-        bytes[offset + 3] = (byte) (value & 0xff);
-        offset += 4;
-    }
-
-    /**
-     * Write scalar 1 byte object includes length, codepoint and value
-     *
-     * @param   codePoint - code point to write
-     * @param   value  - value to write after code point
-     */
-    void writeScalar1Byte (int codePoint, int value) {
-        ensureLength (5);
-        bytes[offset] = 0x00;
-        bytes[offset + 1] = 0x05;
-        bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
-        bytes[offset + 3] = (byte) (codePoint & 0xff);
-        bytes[offset + 4] = (byte) (value & 0xff);
-        offset += 5;
-    }
-
-    /**
-     * Write scalar 2 byte object includes length, codepoint and value
-     *
-     * @param   codePoint - code point to write
-     * @param   value  - value to write after code point
-     */
-    protected void writeScalar2Bytes (int codePoint, int value) {
-        ensureLength (6);
-        bytes[offset] = 0x00;
-        bytes[offset + 1] = 0x06;
-        bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
-        bytes[offset + 3] = (byte) (codePoint & 0xff);
-        bytes[offset + 4] = (byte) ((value >>> 8) & 0xff);
-        bytes[offset + 5] = (byte) (value & 0xff);
-        offset += 6;
-    }
-
-    protected void writeScalar2Bytes ( int value) {
-        ensureLength (2);
-        bytes[offset] = (byte) ((value >>> 8) & 0xff);
-        bytes[offset + 1] = (byte) (value & 0xff);
-        offset += 2;
-    }
-
-    /**
-     * Write length and codepoint
-     *
-     * @param   length - length of object
-     * @param   codePoint - code point to write
-     */
-    protected void startDdm (int length, int codePoint) {
-        ensureLength (4);
-        bytes[offset] = (byte) ((length >>> 8) & 0xff);
-        bytes[offset + 1] = (byte) (length & 0xff);
-        bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
-        bytes[offset + 3] = (byte) (codePoint & 0xff);
-        offset += 4;
-    }
-
-    /**
-     * Write scalar byte array object includes length, codepoint and value
-     *
-     * @param   codePoint - code point to write
-     * @param   buf  - value to write after code point
-     * @param   length - number of bytes to write
-     */
-    protected void writeScalarBytes (int codePoint, byte[] buf, int length) {
-        if (SanityManager.DEBUG) {
-            if (buf == null && length > 0)
-                SanityManager.THROWASSERT("Buf is null");
-            if (length > buf.length)
-                SanityManager.THROWASSERT("Not enough bytes in buffer");
-        }
-        ensureLength (length + 4);
-        bytes[offset] = (byte) (((length+4) >>> 8) & 0xff);
-        bytes[offset + 1] = (byte) ((length+4) & 0xff);
-        bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
-        bytes[offset + 3] = (byte) (codePoint & 0xff);
-        System.arraycopy(buf,0,bytes,offset + 4, length);
-        offset += length + 4;
-    }
+	/**
+	 * Write byte
+	 *
+	 * @param 	value	byte to be written
+	 */
+	protected void writeByte (int value)
+	{
+		if (SanityManager.DEBUG)
+		{
+			if (value > 255)
+				SanityManager.THROWASSERT(
+									   "writeByte value: " + value +
+									   " may not be > 255");
+		}
+
+		ensureLength (1);
+		bytes[offset++] = (byte) (value & 0xff);
+	}
+
+
+	/**
+	 * Write network short
+	 *
+	 * @param 	value	value to be written
+	 */
+	protected void writeNetworkShort (int value)
+	{
+		ensureLength (2);
+		bytes[offset] = (byte) ((value >>> 8) & 0xff);
+		bytes[offset + 1] = (byte) (value & 0xff);
+		offset += 2;
+	}
+
+	/**
+	 * Write network int
+	 *
+	 * @param 	value	value to be written
+	 */
+	protected void writeNetworkInt (int value)
+	{
+		ensureLength (4);
+		bytes[offset] = (byte) ((value >>> 24) & 0xff);
+		bytes[offset + 1] = (byte) ((value >>> 16) & 0xff);
+		bytes[offset + 2] = (byte) ((value >>> 8) & 0xff);
+		bytes[offset + 3] = (byte) (value & 0xff);
+		offset += 4;
+	}
+
+
+	/**
+	 * Write byte array
+	 *
+	 * @param 	buf	byte array to be written
+	 * @param	length  - length to write
+	 */
+	protected void writeBytes (byte[] buf, int length)
+	{
+		writeBytes(buf, 0,length);
+	}
+
+
+
+	/**
+	 * Write byte array
+	 *
+	 * @param 	buf	byte array to be written
+	 * @param	start  - starting position
+	 * @param	length  - length to write
+	 */
+	protected void writeBytes (byte[] buf, int start, int length)
+	{
+
+		if (SanityManager.DEBUG)
+		{
+			if (buf == null && length > 0)
+		    	SanityManager.THROWASSERT("Buf is null");
+			if (length + start - 1 > buf.length)
+		    	SanityManager.THROWASSERT("Not enough bytes in buffer");
+
+		}
+		ensureLength (length);
+		System.arraycopy(buf,start,bytes,offset,length);
+		offset += length;
+	}
+	/**
+	 * Write byte array
+	 *
+	 * @param 	buf	byte array to be written
+	 **/
+	protected void writeBytes (byte[] buf)
+	{
+		writeBytes(buf,buf.length);
+	}
+
+
+
+	protected void writeLDBytes(byte[] buf)
+	{
+		writeLDBytes(buf, 0);
+	}
+
+	protected void writeLDBytes(byte[] buf, int index)
+	{
+
+		int length = buf.length;
+		int writeLen =  buf.length;
+
+		writeShort(writeLen);
+
+		writeBytes(buf,0,writeLen);
+	}
+
+
+	/**
+	 * Write code point and 4 bytes
+	 *
+	 * @param 	codePoint - code point to write
+	 * @param	value  - value to write after code point
+	 */
+	void writeCodePoint4Bytes (int codePoint, int value)
+	{
+		ensureLength (4);
+		bytes[offset] = (byte) ((codePoint >>> 8) & 0xff);
+		bytes[offset + 1] = (byte) (codePoint & 0xff);
+		bytes[offset + 2] = (byte) ((value >>> 8) & 0xff);
+		bytes[offset + 3] = (byte) (value & 0xff);
+		offset += 4;
+	}
+
+	/**
+	 * Write scalar 1 byte object includes length, codepoint and value
+	 *
+	 * @param 	codePoint - code point to write
+	 * @param	value  - value to write after code point
+	 */
+	void writeScalar1Byte (int codePoint, int value)
+	{
+		ensureLength (5);
+		bytes[offset] = 0x00;
+		bytes[offset + 1] = 0x05;
+		bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
+		bytes[offset + 3] = (byte) (codePoint & 0xff);
+		bytes[offset + 4] = (byte) (value & 0xff);
+		offset += 5;
+	}
+
+	/**
+	 * Write scalar 2 byte object includes length, codepoint and value
+	 *
+	 * @param 	codePoint - code point to write
+	 * @param	value  - value to write after code point
+	 */
+	protected void writeScalar2Bytes (int codePoint, int value)
+	{
+		ensureLength (6);
+		bytes[offset] = 0x00;
+		bytes[offset + 1] = 0x06;
+		bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
+		bytes[offset + 3] = (byte) (codePoint & 0xff);
+		bytes[offset + 4] = (byte) ((value >>> 8) & 0xff);
+		bytes[offset + 5] = (byte) (value & 0xff);
+		offset += 6;
+	}
+
+	protected void writeScalar2Bytes ( int value)
+	{
+		ensureLength (2);
+		bytes[offset] = (byte) ((value >>> 8) & 0xff);
+		bytes[offset + 1] = (byte) (value & 0xff);
+		offset += 2;
+	}
+
+	/**
+	 * Write length and codepoint
+	 *
+	 * @param 	length - length of object
+	 * @param 	codePoint - code point to write
+	 */
+	protected void startDdm (int length, int codePoint)
+	{
+		ensureLength (4);
+		bytes[offset] = (byte) ((length >>> 8) & 0xff);
+		bytes[offset + 1] = (byte) (length & 0xff);
+		bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
+		bytes[offset + 3] = (byte) (codePoint & 0xff);
+		offset += 4;
+	}
+
+	/**
+	 * Write scalar byte array object includes length, codepoint and value
+	 *
+	 * @param 	codePoint - code point to write
+	 * @param	buf  - value to write after code point
+	 * @param	length - number of bytes to write
+	 */
+	protected void writeScalarBytes (int codePoint, byte[] buf, int length)
+	{
+		if (SanityManager.DEBUG)
+		{
+			if (buf == null && length > 0)
+		    	SanityManager.THROWASSERT("Buf is null");
+			if (length > buf.length)
+		    	SanityManager.THROWASSERT("Not enough bytes in buffer");
+		}
+		ensureLength (length + 4);
+		bytes[offset] = (byte) (((length+4) >>> 8) & 0xff);
+		bytes[offset + 1] = (byte) ((length+4) & 0xff);
+		bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
+		bytes[offset + 3] = (byte) (codePoint & 0xff);
+		System.arraycopy(buf,0,bytes,offset + 4, length);
+		offset += length + 4;
+	}
 
 
     
     protected void writeScalarStream (boolean chainedWithSameCorrelator,
-                                      int codePoint,
-                                      EXTDTAInputStream in,
-                                      boolean writeNullByte) 
-        throws DRDAProtocolException {
-        
-        // Stream equivalent of "beginDss"...
-        int spareDssLength = prepScalarStream( chainedWithSameCorrelator,
-                                               codePoint,
-                                               writeNullByte);
-            
-        // write the data
-        int bytesRead = 0;
-        int totalBytesRead = 0;
-
-        try {
-                                    
-            OutputStream out = 
-                placeLayerBStreamingBuffer( agent.getOutputStream() );
-                
-            boolean isLastSegment = false;
-                
-            while( !isLastSegment ){
-                    
-                int spareBufferLength = bytes.length - offset;
-                    
-                if( SanityManager.DEBUG ){
-                
-                    if( PropertyUtil.getSystemProperty("derby.debug.suicideOfLayerBStreaming") != null )
-                        throw new IOException();
-                }
-                    
-                bytesRead = in.read(bytes,
-                                    offset,
-                                    Math.min(spareDssLength,
-                                             spareBufferLength));
-                    
-                totalBytesRead += bytesRead;
-                offset += bytesRead;
-                spareDssLength -= bytesRead;
-                spareBufferLength -= bytesRead;
-
-                isLastSegment = peekStream(in) < 0;
-                    
-                if(isLastSegment || 
-                   spareDssLength == 0){
-                        
-                    flushScalarStreamSegment (isLastSegment, 
-                                              out);
-                        
-                    if( ! isLastSegment )
-                        spareDssLength = DssConstants.MAX_DSS_LENGTH - 2;
-
-                }
-                    
-            }
-                
-            out.flush();
-                
-        }catch(IOException e){
-            agent.markCommunicationsFailure ("DDMWriter.writeScalarStream()",
-                                             "",
-                                             e.getMessage(),
-                                             "*");
-        }
-                                
-    }
-        
-    /**
-     * Begins a DSS stream (for writing LOB data).
-     */
-    private void beginDss (boolean chainedToNextStructure,
-                           int dssType) {
-        beginDss(dssType, false);       // false => don't ensure length.
-
-        // always turn on continuation flags... this is helpful for lobs...
-        // these bytes will get rest if dss lengths are finalized.
-        bytes[dssLengthLocation] = (byte) 0xFF;
-        bytes[dssLengthLocation + 1] = (byte) 0xFF;
-
-        // Set whether or not this DSS should be chained to
-        // the next one.  If it's chained, it has to be chained
-        // with same id (that's the nature of EXTDTA chaining).
-        if (chainedToNextStructure) {
-            dssType |= DssConstants.GDSCHAIN_SAME_ID;
-        }
+									  int codePoint,
+				      EXTDTAInputStream in,
+									  boolean writeNullByte) 
+		throws DRDAProtocolException
+	{
+
+	    
+
+		// Stream equivalent of "beginDss"...
+	    int spareDssLength = prepScalarStream( chainedWithSameCorrelator,
+											codePoint,
+											writeNullByte);
+	    
+		// write the data
+		int bytesRead = 0;
+		int totalBytesRead = 0;
+
+				try {
+				    
+		OutputStream out = 
+		    placeLayerBStreamingBuffer( agent.getOutputStream() );
+		
+		boolean isLastSegment = false;
+		
+		while( !isLastSegment ){
+		    
+		    int spareBufferLength = bytes.length - offset;
+		    
+		    if( SanityManager.DEBUG ){
+		
+			if( PropertyUtil.getSystemProperty("derby.debug.suicideOfLayerBStreaming") != null )
+			    throw new IOException();
+				}
+		    
+		    bytesRead = in.read(bytes,
+					offset,
+					Math.min(spareDssLength,
+						 spareBufferLength));
+		    
+					totalBytesRead += bytesRead;
+					offset += bytesRead;
+		    spareDssLength -= bytesRead;
+		    spareBufferLength -= bytesRead;
+
+		    isLastSegment = peekStream(in) < 0;
+		    
+		    if(isLastSegment || 
+		       spareDssLength == 0){
+			
+			flushScalarStreamSegment (isLastSegment, 
+						  out);
+			
+			if( ! isLastSegment )
+			    spareDssLength = DssConstants.MAX_DSS_LENGTH - 2;
+
+			}
+		    
+		}
+		
+		out.flush();
+		
+	    }catch(IOException e){
+		agent.markCommunicationsFailure ("DDMWriter.writeScalarStream()",
+						 "",
+						 e.getMessage(),
+						 "*");
+		}
+				
+	}
+	
+	/**
+	 * Begins a DSS stream (for writing LOB data).
+	 */
+	private void beginDss (boolean chainedToNextStructure,
+						   int dssType)
+	{
+		beginDss(dssType, false);	// false => don't ensure length.
+
+		// always turn on continuation flags... this is helpful for lobs...
+		// these bytes will get rest if dss lengths are finalized.
+  		bytes[dssLengthLocation] = (byte) 0xFF;
+  		bytes[dssLengthLocation + 1] = (byte) 0xFF;
+
+		// Set whether or not this DSS should be chained to
+		// the next one.  If it's chained, it has to be chained
+		// with same id (that's the nature of EXTDTA chaining).
+		if (chainedToNextStructure) {
+			dssType |= DssConstants.GDSCHAIN_SAME_ID;
+		}
 
-        bytes[dssLengthLocation + 3] = (byte) (dssType & 0xff);
-    }
+		bytes[dssLengthLocation + 3] = (byte) (dssType & 0xff);
+	}
 
 
     /**
@@ -734,837 +775,884 @@
      * cf. page 315 of specification of DRDA, Version 3, Volume 3 
      *
      */
-    private int prepScalarStream( boolean chainedWithSameCorrelator,
-                                  int codePoint,
-                                  boolean writeNullByte) 
-        throws DRDAProtocolException {
+  private int prepScalarStream( boolean chainedWithSameCorrelator,
+                                   int codePoint,
+                                   boolean writeNullByte) throws DRDAProtocolException
+  {
 
-        ensureLength( DEFAULT_BUFFER_SIZE - offset );
+      ensureLength( DEFAULT_BUFFER_SIZE - offset );
       
-        final int nullIndicatorSize = writeNullByte ? 1:0;
+      final int nullIndicatorSize = writeNullByte ? 1:0;
 
     
-        // flush the existing DSS segment ,
-        // if this stream will not fit in the send buffer or 
-        // length of this stream is unknown.
-        // Here, 10 stands for sum of headers of layer A and B.
-
-        try {
-            // The existing DSS segment was finalized by endDss; all
-            // we have to do is send it across the wire.
-            sendBytes(agent.getOutputStream());
-        } catch (java.io.IOException e) {
-            agent.markCommunicationsFailure ("DDMWriter.writeScalarStream()",
-                                             "OutputStream.flush()",
-                                             e.getMessage(),"*");
-        }
-
-        // buildStreamDss should not call ensure length.
-        beginDss(chainedWithSameCorrelator, DssConstants.GDSFMT_OBJDSS);
-
-        writeLengthCodePoint(0x8004,codePoint);
-
-
-        // write the null byte, if necessary
-        if (writeNullByte)
-            writeByte(0x0);
-
-        //Here, 6 stands for header of layer A and 
-        //4 stands for header of layer B.
-        return DssConstants.MAX_DSS_LENGTH - 6 - 4 - nullIndicatorSize;
-
-
-    }
-
-
-    // method to determine if any data is in the request.
-    // this indicates there is a dss object already in the buffer.
-    protected boolean doesRequestContainData() {
-        return offset != 0;
-    }
-
-
-    // Writes out a scalar stream DSS segment, along with DSS continuation
-    // headers if necessary.
-    private void flushScalarStreamSegment ( boolean lastSegment,
-                                            OutputStream out)
-        throws DRDAProtocolException {
-
-        // either at end of data, end of dss segment, or both.
-        if (! lastSegment) {
-
-            // 32k segment filled and not at end of data.
-            try {
-                // Mark current DSS as continued, set its chaining state,
-                // then send the data across.
-                markDssAsContinued(true);       // true => for lobs
-                sendBytes (out,
-                           false);
-                            
-            }catch (java.io.IOException ioe) {
-                agent.markCommunicationsFailure ("DDMWriter.flushScalarStreamSegment()",
-                                                 "",
-                                                 ioe.getMessage(),
-                                                 "*");
-            }
-
-
-            // Prepare a DSS continuation header for next DSS.
-            dssLengthLocation = offset;
-            bytes[offset++] = (byte) (0xff);
-            bytes[offset++] = (byte) (0xff);
-            isContinuationDss = true;
-        }else{
-            // we're done writing the data, so end the DSS.
-            endDss();
-
-        }
-
-    }
-
-
-    private void writeExtendedLengthBytes (int extendedLengthByteCount, long length) {
-        int shiftSize = (extendedLengthByteCount -1) * 8;
-        for (int i = 0; i < extendedLengthByteCount; i++) {
-            bytes[offset + i] = (byte) ((length >>> shiftSize) & 0xff);
-            shiftSize -= 8;
-        }
-        offset += extendedLengthByteCount;
-    }
-
-
-    // insert a 4 byte length/codepoint pair into the buffer.
-    // total of 4 bytes inserted in buffer.
-    // Note: the length value inserted in the buffer is the same as the value
-    // passed in as an argument (this value is NOT incremented by 4 before being
-    // inserted).
-    void writeLengthCodePoint (int length, int codePoint) {
-        ensureLength (4);
-        bytes[offset] = (byte) ((length >>> 8) & 0xff);
-        bytes[offset + 1] = (byte) (length & 0xff);
-        bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
-        bytes[offset + 3] = (byte) (codePoint & 0xff);
-        offset +=4;
-    }
-
-    /**
-     * Write scalar object header includes length and codepoint
-     *
-     * @param   codePoint - code point to write
-     * @param   dataLength - length of object data
-     */
-    protected void writeScalarHeader (int codePoint, int dataLength) {
-        ensureLength (dataLength + 4);
-        bytes[offset] = (byte) (((dataLength+4) >>> 8) & 0xff);
-        bytes[offset + 1] = (byte) ((dataLength+4) & 0xff);
-        bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
-        bytes[offset + 3] = (byte) (codePoint & 0xff);
-        offset += 4;
-    }
-
-    /**
-     * Write scalar string object includes length, codepoint and value
-     * the string is converted into the appropriate codeset (EBCDIC)
-     *
-     * @param   codePoint - code point to write
-     * @param   string - string to be written
-     */
-    void writeScalarString (int codePoint, String string) {
-        int stringLength = string.length();
-        ensureLength ((stringLength * 2)  + 4);
-        bytes[offset] = (byte) (((stringLength+4) >>> 8) & 0xff);
-        bytes[offset + 1] = (byte) ((stringLength+4) & 0xff);
-        bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
-        bytes[offset + 3] = (byte) (codePoint & 0xff);
-        offset = ccsidManager.convertFromUCS2 (string, bytes, offset + 4);
-    }
-
-    /**
-     * Write padded scalar string object includes length, codepoint and value
-     * the string is converted into the appropriate codeset (EBCDIC)
-     *
-     * @param   codePoint - code point to write
-     * @param   string - string to be written
-     * @param   paddedLength - length to pad string to
-     */
-    void writeScalarPaddedString (int codePoint, String string, int paddedLength) {
-        int stringLength = string.length();
-        int fillLength = paddedLength - stringLength;
-        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 = ccsidManager.convertFromUCS2 (string, bytes, offset + 4);
-        Arrays.fill(bytes,offset, offset + fillLength,ccsidManager.space);
-        offset += fillLength;
-    }
-
-    /**
-     * Write padded scalar string object value
-     * the string is converted into the appropriate codeset (EBCDIC)
-     *
-     * @param   string - string to be written
-     * @param   paddedLength - length to pad string to
-     */
-    protected void writeScalarPaddedString (String string, int paddedLength) {
-        int stringLength = string.length();
-
-        int fillLength = paddedLength -stringLength;
-        ensureLength (paddedLength);
-        offset = ccsidManager.convertFromUCS2 (string, bytes, offset);
-        Arrays.fill(bytes,offset, offset + fillLength,ccsidManager.space);
-        offset += fillLength;
-    }
+      // flush the existing DSS segment ,
+      // if this stream will not fit in the send buffer or 
+      // length of this stream is unknown.
+      // Here, 10 stands for sum of headers of layer A and B.
+
+      try {
+	    // The existing DSS segment was finalized by endDss; all
+	    // we have to do is send it across the wire.
+        sendBytes(agent.getOutputStream());
+      }
+      catch (java.io.IOException e) {
+         agent.markCommunicationsFailure ("DDMWriter.writeScalarStream()",
+                                              "OutputStream.flush()",
+                                              e.getMessage(),"*");
+      }
+
+    // buildStreamDss should not call ensure length.
+	beginDss(chainedWithSameCorrelator, DssConstants.GDSFMT_OBJDSS);
+
+      writeLengthCodePoint(0x8004,codePoint);
+
+
+    // write the null byte, if necessary
+    if (writeNullByte)
+      writeByte(0x0);
+
+      //Here, 6 stands for header of layer A and 
+      //4 stands for header of layer B.
+      return DssConstants.MAX_DSS_LENGTH - 6 - 4 - nullIndicatorSize;
+
+
+  }
+
+
+  // method to determine if any data is in the request.
+  // this indicates there is a dss object already in the buffer.
+	protected boolean doesRequestContainData()
+	{
+		return offset != 0;
+	}
+
+
+	// Writes out a scalar stream DSS segment, along with DSS continuation
+	// headers if necessary.
+	private void flushScalarStreamSegment ( boolean lastSegment,
+					        OutputStream out)
+		throws DRDAProtocolException
+	{
+
+		// either at end of data, end of dss segment, or both.
+	    if (! lastSegment) {
+
+		// 32k segment filled and not at end of data.
+				try {
+				// Mark current DSS as continued, set its chaining state,
+				// then send the data across.
+					markDssAsContinued(true); 	// true => for lobs
+					sendBytes (out,
+						   false);
+			    
+			}catch (java.io.IOException ioe) {
+					agent.markCommunicationsFailure ("DDMWriter.flushScalarStreamSegment()",
+                                               "",
+                                               ioe.getMessage(),
+                                               "*");
+				}
+
+
+			// Prepare a DSS continuation header for next DSS.
+			dssLengthLocation = offset;
+			bytes[offset++] = (byte) (0xff);
+			bytes[offset++] = (byte) (0xff);
+			isContinuationDss = true;
+	    }else{
+		// we're done writing the data, so end the DSS.
+			endDss();
+
+	}
+
+  }
+
+
+	private void writeExtendedLengthBytes (int extendedLengthByteCount, long length)
+	{
+	int shiftSize = (extendedLengthByteCount -1) * 8;
+    for (int i = 0; i < extendedLengthByteCount; i++) {
+      bytes[offset + i] = (byte) ((length >>> shiftSize) & 0xff);
+      shiftSize -= 8;
+    }
+	offset += extendedLengthByteCount;
+  }
+
+
+  // insert a 4 byte length/codepoint pair into the buffer.
+  // total of 4 bytes inserted in buffer.
+  // Note: the length value inserted in the buffer is the same as the value
+  // passed in as an argument (this value is NOT incremented by 4 before being
+  // inserted).
+  void writeLengthCodePoint (int length, int codePoint)
+  {
+    ensureLength (4);
+    bytes[offset] = (byte) ((length >>> 8) & 0xff);
+    bytes[offset + 1] = (byte) (length & 0xff);
+    bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
+    bytes[offset + 3] = (byte) (codePoint & 0xff);
+	offset +=4;
+  }
+
+	/**
+	 * Write scalar object header includes length and codepoint
+	 *
+	 * @param 	codePoint - code point to write
+	 * @param	dataLength - length of object data
+	 */
+	protected void writeScalarHeader (int codePoint, int dataLength)
+	{
+		ensureLength (dataLength + 4);
+		bytes[offset] = (byte) (((dataLength+4) >>> 8) & 0xff);
+		bytes[offset + 1] = (byte) ((dataLength+4) & 0xff);
+		bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
+		bytes[offset + 3] = (byte) (codePoint & 0xff);
+		offset += 4;
+	}
+
+	/**
+	 * Write scalar string object includes length, codepoint and value
+	 * the string is converted into the appropriate codeset (EBCDIC)
+	 *
+	 * @param 	codePoint - code point to write
+	 * @param	string - string to be written
+	 */
+	void writeScalarString (int codePoint, String string)
+	{
+		int stringLength = string.length();
+		ensureLength ((stringLength * 2)  + 4);
+		bytes[offset] = (byte) (((stringLength+4) >>> 8) & 0xff);
+		bytes[offset + 1] = (byte) ((stringLength+4) & 0xff);
+		bytes[offset + 2] = (byte) ((codePoint >>> 8) & 0xff);
+		bytes[offset + 3] = (byte) (codePoint & 0xff);
+		offset = ccsidManager.convertFromUCS2 (string, bytes, offset + 4);
+	}
+
+	/**
+	 * Write padded scalar string object includes length, codepoint and value
+	 * the string is converted into the appropriate codeset (EBCDIC)
+	 *
+	 * @param 	codePoint - code point to write
+	 * @param	string - string to be written
+	 * @param 	paddedLength - length to pad string to
+	 */
+	void writeScalarPaddedString (int codePoint, String string, int paddedLength)
+	{
+		int stringLength = string.length();
+		int fillLength = paddedLength - stringLength;
+		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 = ccsidManager.convertFromUCS2 (string, bytes, offset + 4);
+		Arrays.fill(bytes,offset, offset + fillLength,ccsidManager.space);
+		offset += fillLength;
+	}
+
+	/**
+	 * Write padded scalar string object value
+	 * the string is converted into the appropriate codeset (EBCDIC)
+	 *
+	 * @param	string - string to be written
+	 * @param 	paddedLength - length to pad string to
+	 */
+	protected void writeScalarPaddedString (String string, int paddedLength)
+	{
+		int stringLength = string.length();
+
+		int fillLength = paddedLength -stringLength;
+		ensureLength (paddedLength);
+		offset = ccsidManager.convertFromUCS2 (string, bytes, offset);
+		Arrays.fill(bytes,offset, offset + fillLength,ccsidManager.space);
+		offset += fillLength;
+	}
+
+	/**
+	 * 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;
+	}
 
-    /**
-     * 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
-            // start of the segment and set the value of the 2-byte DSS
-            // continuation header, which needs to hold the length of
-            // this segment's data, together with the continuation flag
-            // if this is not the rightmost (passOne) segment.
-            //
-            // In general, each segment except the rightmost will contain
-            // 32765 bytes of data, plus the 2-byte header, and its
-            // continuation flag will be set, so the header value will
-            // be 0xFFFF. The rightmost segment will not have the
-            // continuation flag set, so its value may be anything from
-            // 0x0001 to 0x7FFF, depending on the amount of data in that
-            // segment.
-            //
-            // Note that the 0th (leftmost) segment also has a 2-byte
-            // DSS header, which needs to have its continuation flag set.
-            // This is done by resetting the "totalSize" variable below,
-            // at which point that variable no longer holds the total size

[... 1013 lines stripped ...]


Mime
View raw message