db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t...@apache.org
Subject svn commit: r407547 [2/4] - in /db/derby/code/trunk/java: drda/org/apache/derby/impl/drda/ engine/org/apache/derby/iapi/reference/
Date Thu, 18 May 2006 13:34:12 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=407547&r1=407546&r2=407547&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 Thu May 18 06:34:11 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,396 +36,396 @@
 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);
-	}
-
-	/**
-	 * 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;
-		}
+    // 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;
 
-		// 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);
+    // Default buffer size
+    private final static int DEFAULT_BUFFER_SIZE = 32767;
 
-	}
 
-	/**
-	 * 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;
+    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;
 	}
 
-	/**
-	 * 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;
-		}
+	// 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);
 
-		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;
-			}
+    /**
+     * 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)
+    {
 
-			// adjust the offset to account for the shift and insert
-			offset += extendedLengthByteCount;
+	// Do regular endDss processing.
+	endDss(true);
 
-			// 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;
-		}
+	// 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);
+    }
 
-		// write the 2 byte length field (2 bytes before codepoint).
-		bytes[lengthLocation] = (byte) ((length >>> 8) & 0xff);
-		bytes[lengthLocation+1] = (byte) (length & 0xff);
+    /**
+     * 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
      * used by the LMTBLKPRC protocol, which does its own conversational
@@ -434,7 +434,7 @@
      * DSS block when splitting a QRYDTA response.
      *
      * @return current DSS block length
-    */
+     */
     protected int getDSSLength()
     {
         return offset - dssLengthLocation;
@@ -446,324 +446,324 @@
      * calling copyDSSDataToEnd
      *
      * @param value DSS length
-    */
+     */
     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");
-		}
+    /**
+     * 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);
-	}
+	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 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	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");
+    /**
+     * 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)
+    {
 
-		}
-		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;
-	}
+	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,
+				      int codePoint,
 				      EXTDTAInputStream in,
-									  boolean writeNullByte) 
-		throws DRDAProtocolException
-	{
+				      boolean writeNullByte) 
+	throws DRDAProtocolException
+    {
 
 	    
 
-		// Stream equivalent of "beginDss"...
-	    int spareDssLength = prepScalarStream( chainedWithSameCorrelator,
-											codePoint,
-											writeNullByte);
+	// Stream equivalent of "beginDss"...
+	int spareDssLength = prepScalarStream( chainedWithSameCorrelator,
+					       codePoint,
+					       writeNullByte);
 	    
-		// write the data
-		int bytesRead = 0;
-		int totalBytesRead = 0;
+	// write the data
+	int bytesRead = 0;
+	int totalBytesRead = 0;
 
-				try {
+	try {
 				    
-		OutputStream out = 
-		    placeLayerBStreamingBuffer( agent.getOutputStream() );
+	    OutputStream out = 
+		placeLayerBStreamingBuffer( agent.getOutputStream() );
 		
-		boolean isLastSegment = false;
+	    boolean isLastSegment = false;
 		
-		while( !isLastSegment ){
+	    while( !isLastSegment ){
 		    
-		    int spareBufferLength = bytes.length - offset;
+		int spareBufferLength = bytes.length - offset;
 		    
-		    if( SanityManager.DEBUG ){
+		if( SanityManager.DEBUG ){
 		
-			if( PropertyUtil.getSystemProperty("derby.debug.suicideOfLayerBStreaming") != null )
-			    throw new IOException();
-				}
+		    if( PropertyUtil.getSystemProperty("derby.debug.suicideOfLayerBStreaming") != null )
+			throw new IOException();
+		}
 		    
-		    bytesRead = in.read(bytes,
-					offset,
-					Math.min(spareDssLength,
-						 spareBufferLength));
+		bytesRead = in.read(bytes,
+				    offset,
+				    Math.min(spareDssLength,
+					     spareBufferLength));
 		    
-					totalBytesRead += bytesRead;
-					offset += bytesRead;
-		    spareDssLength -= bytesRead;
-		    spareBufferLength -= bytesRead;
+		totalBytesRead += bytesRead;
+		offset += bytesRead;
+		spareDssLength -= bytesRead;
+		spareBufferLength -= bytesRead;
 
-		    isLastSegment = peekStream(in) < 0;
+		isLastSegment = peekStream(in) < 0;
 		    
-		    if(isLastSegment || 
-		       spareDssLength == 0){
+		if(isLastSegment || 
+		   spareDssLength == 0){
 			
-			flushScalarStreamSegment (isLastSegment, 
-						  out);
+		    flushScalarStreamSegment (isLastSegment, 
+					      out);
 			
-			if( ! isLastSegment )
-			    spareDssLength = DssConstants.MAX_DSS_LENGTH - 2;
+		    if( ! isLastSegment )
+			spareDssLength = DssConstants.MAX_DSS_LENGTH - 2;
 
-			}
-		    
 		}
+		    
+	    }
 		
-		out.flush();
+	    out.flush();
 		
-	    }catch(IOException e){
-		agent.markCommunicationsFailure ("DDMWriter.writeScalarStream()",
-						 "",
-						 e.getMessage(),
-						 "*");
-		}
-				
+	}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;
-		}
+    /**
+     * 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;
 
-		bytes[dssLengthLocation + 3] = (byte) (dssType & 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);
+    }
+
 
     /**
      * prepScalarStream does the following prep for writing stream data:
@@ -775,884 +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.
+	// 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 {
+	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(),"*");
-      }
+	    sendBytes(agent.getOutputStream());
+	}
+	catch (java.io.IOException e) {
+	    agent.markCommunicationsFailure ("DDMWriter.writeScalarStream()",
+					     "OutputStream.flush()",
+					     e.getMessage(),"*");
+	}
 
-    // buildStreamDss should not call ensure length.
+	// buildStreamDss should not call ensure length.
 	beginDss(chainedWithSameCorrelator, DssConstants.GDSFMT_OBJDSS);
 
-      writeLengthCodePoint(0x8004,codePoint);
+	writeLengthCodePoint(0x8004,codePoint);
 
 
-    // write the null byte, if necessary
-    if (writeNullByte)
-      writeByte(0x0);
+	// 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;
+	//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;
-	}
+    // 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
-	{
+    // 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) {
+	// 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);
+	    // 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(),
-                                               "*");
-				}
+	    }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();
+	    // 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)
-	{
+    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;
-    }
+	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);
+    // 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
-			*/
+    /**
+     * 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;
+    }
 
-			if (SanityManager.DEBUG)
-			{
-				if (!(NetworkServerControlImpl.DEFAULT_ENCODING.equals("UTF8")))
-					SanityManager.THROWASSERT("Encoding assumed to be UTF8, but is actually" + NetworkServerControlImpl.DEFAULT_ENCODING);
-			}
+    /**
+     * 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);
+    }
 
-			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;
-					}
-				}
+    /**
+     * 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;
+    }
 
-			writeShort(writeLen);
-			writeBytes(byteval,writeLen);
-		}
-		catch (Exception e) {
-			//this should never happen
-			agent.agentError("Encoding " + NetworkServerControlImpl.DEFAULT_ENCODING + " not supported");
-		}
-	}
+    /**
+     * 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();
 
-	/**
-	 * 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");
-		}
-	}
+	int fillLength = paddedLength -stringLength;
+	ensureLength (paddedLength);
+	offset = ccsidManager.convertFromUCS2 (string, bytes, offset);
+	Arrays.fill(bytes,offset, offset + fillLength,ccsidManager.space);
+	offset += fillLength;
+    }
 
-	/**
-	 * 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
+    /**
+     * 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)
 		{
-			writeBytes(bs);
-			padBytes(NetworkServerControlImpl.SPACE_CHAR, length-len);
+		    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 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);
-		}
+    /**
+     * 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");
 	}
+    }
 
-	// private methods
+    /**
+     * 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());
+    }
 
-	/**
-	 * 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;
+    /**
+     * 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);
 	}
+    }
 
-	/**
-     * 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;
+    // private methods
 
-		// 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
-			// of the object, but rather just the length of segment 0. The
-			// total size of the object was written using extended length
-			// bytes by the endDdm() method earlier.
-			//
-			// Additional information about this routine is available in the
-			// bug notes for DERBY-125:
-			// http://issues.apache.org/jira/browse/DERBY-125
+    /**
+     * 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
+		// of the object, but rather just the length of segment 0. The
+		// total size of the object was written using extended length
+		// bytes by the endDdm() method earlier.
+		//
+		// Additional information about this routine is available in the
+		// bug notes for DERBY-125:
+		// http://issues.apache.org/jira/browse/DERBY-125
 			
-			// mark passOne to help with calculating the length of the final (first or
-			// rightmost) continuation header.
-			boolean passOne = true;
-			do {
-				// calculate chunk of data to shift
-				int dataToShift = bytesRequiringContDssHeader % 32765;
-				if (dataToShift == 0)
-					dataToShift = 32765;
-				int startOfCopyData = dataByte - dataToShift + 1;
-				System.arraycopy(bytes,startOfCopyData, bytes, 
-								 startOfCopyData + shiftSize, dataToShift);
-				dataByte -= dataToShift;
-
-
-				// calculate the value the value of the 2 byte continuation dss
-				// header which includes the length of itself.  On the first pass,
-				// if the length is 32767
-				// we do not want to set the continuation dss header flag.
-				int twoByteContDssHeader = dataToShift + 2;
-				if (passOne)
-					passOne = false;
-				else
-				{
-					if (twoByteContDssHeader == DssConstants.MAX_DSS_LENGTH)
-					twoByteContDssHeader = (twoByteContDssHeader |
-						DssConstants.CONTINUATION_BIT);
-
-				}
-
-				// insert the header's length bytes
-				bytes[dataByte + shiftSize - 1] = (byte)
-					((twoByteContDssHeader >>> 8) & 0xff);
-				bytes[dataByte + shiftSize] = (byte)
-					(twoByteContDssHeader & 0xff);
-
-				// adjust the bytesRequiringContDssHeader and the amount to shift for
-				// data in upstream headers.
-				bytesRequiringContDssHeader -= dataToShift;
-				shiftSize -= 2;
+		// mark passOne to help with calculating the length of the final (first or

[... 807 lines stripped ...]


Mime
View raw message