Added: 
incubator/derby/code/trunk/java/client/org/apache/derby/client/net/Reply.java
URL: 
http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/Reply.java?rev=165178&view=auto
==============================================================================
--- 
incubator/derby/code/trunk/java/client/org/apache/derby/client/net/Reply.java 
(added)
+++ 
incubator/derby/code/trunk/java/client/org/apache/derby/client/net/Reply.java 
Thu Apr 28 12:05:42 2005
@@ -0,0 +1,1501 @@
+/*
+
+   Derby - Class org.apache.derby.client.net.Reply
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, 
where 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
+
+      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.
+
+*/
+
+package org.apache.derby.client.net;
+
+
+import org.apache.derby.client.am.SqlState;
+import org.apache.derby.client.am.SqlException;
+import org.apache.derby.client.am.SignedBinary;
+import java.io.ByteArrayOutputStream;
+
+public class Reply
+{
+  protected org.apache.derby.client.am.Agent agent_;
+  protected NetAgent netAgent_; //cheat-link to (NetAgent) agent_
+
+  private CcsidManager ccsidManager_;
+  protected final static int DEFAULT_BUFFER_SIZE = 32767;
+  protected byte[] buffer_;
+  protected int pos_;
+  protected int count_;
+
+  private int topDdmCollectionStack_;
+  private final static int MAX_MARKS_NESTING = 10;
+  private int[] ddmCollectionLenStack_;
+  private int ddmScalarLen_; // a value of -1 -> streamed ddm -> length unknown
+  private final static int EMPTY_STACK = -1;
+
+  protected boolean ensuredLengthForDecryption_ = false; // A layer lengths 
have already been ensured in decrypt method.
+  protected byte[] longBufferForDecryption_ = null;
+  protected int longPosForDecryption_ = 0;
+  protected byte[] longValueForDecryption_ = null;
+  protected int longCountForDecryption_ = 0;
+
+  protected int dssLength_;
+  protected boolean dssIsContinued_;
+  private boolean dssIsChainedWithSameID_;
+  private boolean dssIsChainedWithDiffID_;
+  protected int dssCorrelationID_;
+
+  protected int peekedLength_ = 0;
+  protected int peekedCodePoint_ = END_OF_COLLECTION;    // saves the peeked 
codept
+  private int peekedNumOfExtendedLenBytes_ = 0;
+  private int currentPos_ = 0;
+
+  public final static int END_OF_COLLECTION = -1;
+  public final static int END_OF_SAME_ID_CHAIN = -2;
+  Reply (NetAgent netAgent, int bufferSize)
+  {
+    buffer_ = new byte[bufferSize];
+    agent_ = netAgent_ = netAgent;
+    ccsidManager_ = netAgent.targetCcsidManager_;
+    ddmCollectionLenStack_ = new int[Reply.MAX_MARKS_NESTING];
+    initialize ();
+  }
+
+  final void initialize ()
+  {
+    pos_ = 0;
+    count_ = 0;
+    topDdmCollectionStack_ = Reply.EMPTY_STACK;
+    for (int i = 0; i < Reply.MAX_MARKS_NESTING; i++) {
+      ddmCollectionLenStack_[i] = 0;
+    }
+    ddmScalarLen_ = 0;
+    dssLength_ = 0;
+    dssIsContinued_ = false;
+    dssIsChainedWithSameID_ = false;
+    dssIsChainedWithDiffID_ = false;
+    dssCorrelationID_ = 1;
+  }
+
+  final int getDdmLength()
+  {
+    return ddmScalarLen_;
+  }
+
+  // This is a helper method which shifts the buffered bytes from
+  // wherever they are in the current buffer to the beginning of
+  // different buffer (note these buffers could be the same).
+  // State information is updated as needed after the shift.
+  private final void shiftBuffer (byte[] destinationBuffer)
+  {
+    // calculate the size of the data in the current buffer.
+    int sz = count_ - pos_;
+
+    // copy this data to the new buffer starting at position 0.
+    System.arraycopy (buffer_, pos_, destinationBuffer, 0, sz);
+
+    // update the state information for data in the new buffer.
+    pos_ = 0;
+    count_ = sz;
+
+    // replace the old buffer with the new buffer.
+    buffer_ = destinationBuffer;
+  }
+
+  // This method makes sure there is enough room in the buffer
+  // for a certain number of bytes.  This method will allocate
+  // a new buffer if needed and shift the bytes in the current buffer
+  // to make ensure space is available for a fill.  Right now
+  // this method will shift bytes as needed to make sure there is
+  // as much room as possible in the buffer before trying to
+  // do the read.  The idea is to try to have space to get as much data as 
possible
+  // if we need to do a read on the socket's stream.
+  protected final void ensureSpaceInBufferForFill (int desiredSpace)
+  {
+    // calculate the total unused space in the buffer.
+    // this includes any space at the end of the buffer and any free
+    // space at the beginning resulting from bytes already read.
+    int currentAvailableSpace = (buffer_.length - count_) + pos_;
+
+    // check to see if there is enough free space.
+    if (currentAvailableSpace < desiredSpace) {
+
+      // there is not enough free space so we need more storage.
+      // we are going to double the buffer unless that happens to still be too 
small.
+      // if more than double the buffer is needed, use the smallest amount 
over this as possible.
+      int doubleBufferSize = (2 * buffer_.length);
+
+      int minumNewBufferSize = (desiredSpace - currentAvailableSpace) + 
buffer_.length;
+      int newsz = minumNewBufferSize <= doubleBufferSize ? doubleBufferSize : 
minumNewBufferSize;
+
+      byte[] newBuffer = new byte[newsz];
+
+      // shift everything from the old buffer to the new buffer
+      shiftBuffer (newBuffer);
+    }
+    else {
+
+      // there is enough free space in the buffer but let's make sure it is 
all at the end.
+      // this is also important because if we are going to do a read, it would 
be nice
+      // to get as much data as possible and making room at the end if the 
buffer helps to
+      // ensure this.
+      if (pos_ != 0) {
+        shiftBuffer (buffer_);
+      }
+    }
+  }
+
+  // This method will attempt to read a minimum number of bytes
+  // from the underlying stream.  This method will keep trying to
+  // read bytes until it has obtained at least the minimum number.
+  // Now returns the total bytes read for decryption, use to return void.
+  protected int fill (int minimumBytesNeeded) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    // make sure that there is enough space in the buffer to hold
+    // the minimum number of bytes needed.
+    ensureSpaceInBufferForFill (minimumBytesNeeded);
+
+    // read until the minimum number of bytes needed is now in the buffer.
+    // hopefully the read method will return as many bytes as it can.
+    int totalBytesRead = 0;
+    int actualBytesRead = 0;
+    do {
+      try {
+       // oops, we shouldn't expose the agent's input stream here, collapse 
this into a read method on the agent
+        actualBytesRead = netAgent_.getInputStream().read (buffer_, count_, 
buffer_.length - count_);
+      }
+      catch (java.io.IOException ioe) {
+        netAgent_.throwCommunicationsFailure ("Reply.fill()",
+                                             "InputStream.read()",
+                                             ioe.getMessage(),
+                                             "*");
+      }
+      finally {
+        if (agent_.loggingEnabled())
+          ((NetLogWriter) netAgent_.logWriter_).traceProtocolFlow (buffer_,
+                                       count_,
+                                       actualBytesRead,
+                                       NetLogWriter.TYPE_TRACE_RECEIVE,
+                                       "Reply",
+                                       "fill",
+                                       2); // tracepoint
+      }
+      count_ += actualBytesRead;
+      totalBytesRead += actualBytesRead;
+
+    }
+    while ((totalBytesRead < minimumBytesNeeded) && (actualBytesRead != -1));
+
+    if (actualBytesRead == -1) {
+      if (totalBytesRead < minimumBytesNeeded) {
+        netAgent_.throwCommunicationsFailure ("Reply.fill()",
+                                             "InputStream.read()",
+                                             "insufficient data",
+                                             "*");
+      }
+    }
+    return totalBytesRead;
+  }
+
+  // Make sure a certain amount of Layer A data is in the buffer.
+  // The data will be in the buffer after this method is called.
+  // Now returns the total bytes read for decryption, use to return void.
+  protected final int ensureALayerDataInBuffer (int desiredDataSize) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int totalBytesRead = 0;
+    // calulate the the number of bytes in the buffer.
+    int avail = count_ - pos_;
+
+    // read more bytes off the network if the data is not in the buffer 
already.
+    if (avail < desiredDataSize) {
+      totalBytesRead = fill (desiredDataSize - avail);
+    }
+    return totalBytesRead;
+  }
+
+  protected final void ensureBLayerDataInBuffer (int desiredDataSize) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    if (dssIsContinued_ && (desiredDataSize > dssLength_)) {
+      int continueDssHeaderCount =
+        (((desiredDataSize - dssLength_) / 32767) + 1);
+      ensureALayerDataInBuffer (desiredDataSize + (continueDssHeaderCount * 
2));
+      compressBLayerData (continueDssHeaderCount);
+      return;
+    }
+    ensureALayerDataInBuffer (desiredDataSize);
+  }
+
+  // this will probably never be called.
+  // it is included here in the highly unlikely event that a reply object
+  // exceeds 32K.  for opimization purposes, we should consider
+  // removing this.  removing this should be ok since we handle most
+  // big stuff returned from the server (qrydta's for example) by
+  // copying out the data into some other storage.  any extended dss header
+  // info will be removed in the copying process.
+  private final void compressBLayerData (int continueDssHeaderCount) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int tempPos = 0;
+
+    // jump to the last continuation header.
+    for (int i = 0; i < continueDssHeaderCount; i++) {
+      // the first may be less than the size of a full dss
+      if (i == 0) {
+        // only jump by the number of bytes remaining in the current dss
+        tempPos = pos_ + dssLength_;
+      }
+      else {
+        // all other jumps are for a full continued dss
+        tempPos += 32767;
+      }
+    }
+
+    // for each of the dss headers to remove,
+    // read out the continuation header and increment the dss length by the
+    // size of the conitnation bytes,  then shift the continuation data as 
needed.
+    int shiftSize = 0;
+    int bytesToShift = 0;
+    int continueHeaderLength = 0;
+    int newDssLength = 0;
+    for (int i = 0; i < continueDssHeaderCount; i++) {
+
+      continueHeaderLength = ((buffer_[tempPos]&0xFF) << 8) +
+        ((buffer_[tempPos + 1]&0xFF) << 0);
+
+      if (i == 0) {
+        // if this is the last one (farthest down stream and first to strip 
out)
+
+        if ((continueHeaderLength & 0x8000) == 0x8000) {
+          // the last dss header is again continued
+          continueHeaderLength = 32767;
+          dssIsContinued_ = true;
+        }
+        else {
+          // the last dss header was not contiued so update continue state flag
+          dssIsContinued_ = false;
+        }
+        // the very first shift size is 2
+        shiftSize = 2;
+      }
+      else {
+        // already removed the last header so make sure the chaining flag is on
+        if ((continueHeaderLength & 0x8000) == 0x8000) {
+          continueHeaderLength = 32767;
+        }
+        else {
+          // this is a syntax error but not really certain which one.
+          // for now pick 0x02 which is Dss header Length does not match the 
number
+          // of bytes of data found.
+          doSyntaxrmSemantics 
(CodePoint.SYNERRCD_DSS_LENGTH_BYTE_NUMBER_MISMATCH);
+        }
+        // increase the shift size by 2
+        shiftSize += 2;
+      }
+
+      // it is a syntax error if the dss continuation is less than or equal to 
two
+      if (continueHeaderLength <= 2) {
+        doSyntaxrmSemantics (CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2);
+      }
+
+      newDssLength += (continueHeaderLength - 2);
+
+      // calculate the number of bytes to shift
+      if (i != (continueDssHeaderCount - 1))
+        bytesToShift = 32767;
+      else
+        bytesToShift = dssLength_;
+
+      tempPos -= (shiftSize - 1);
+      // perform the compress
+      for (int j = 0; j < bytesToShift; j++) {
+        buffer_[tempPos + shiftSize] = buffer_[tempPos];
+        tempPos--;
+      }
+      tempPos += (shiftSize + 1);
+    }
+    // reposition the start of the data after the final dss shift.
+    pos_ = tempPos;
+    dssLength_ = dssLength_ + newDssLength;
+  }
+
+  protected final void readDssHeader () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int correlationID = 0;
+    int nextCorrelationID = 0;
+    ensureALayerDataInBuffer (6);
+
+    // read out the dss length
+    dssLength_ =
+      ((buffer_[pos_++]&0xFF) << 8) +
+      ((buffer_[pos_++]&0xFF) << 0);
+
+    // Remember the old dss length for decryption only.
+    int oldDssLength = dssLength_;
+
+    // check for the continuation bit and update length as needed.
+    if ((dssLength_ & 0x8000) == 0x8000) {
+      dssLength_ = 32767;
+      dssIsContinued_ = true;
+    }
+    else {
+      dssIsContinued_ = false;
+    }
+
+    if (dssLength_ < 6)
+      doSyntaxrmSemantics (CodePoint.SYNERRCD_DSS_LESS_THAN_6);
+
+    // If the GDS id is not valid, or
+    // if the reply is not an RPYDSS nor
+    // a OBJDSS, then throw an exception.
+    if ((buffer_[pos_++]&0xFF) != 0xd0)
+      doSyntaxrmSemantics (CodePoint.SYNERRCD_CBYTE_NOT_D0);
+
+    int gdsFormatter = buffer_[pos_++]&0xFF;
+    if (((gdsFormatter & 0x02) != 0x02)
+        &&((gdsFormatter & 0x03) != 0x03)
+        &&((gdsFormatter & 0x04) != 0x04)) {
+      doSyntaxrmSemantics (CodePoint.SYNERRCD_FBYTE_NOT_SUPPORTED);
+    }
+
+    // Determine if the current DSS is chained with the
+    // next DSS, with the same or different request ID.
+    if ((gdsFormatter & 0x40) == 0x40) {    // on indicates structure chained 
to next structure
+      if ((gdsFormatter & 0x10) == 0x10) {
+        dssIsChainedWithSameID_ = true;
+        dssIsChainedWithDiffID_ = false;
+        nextCorrelationID = dssCorrelationID_;
+      }
+      else {
+        dssIsChainedWithSameID_ = false;
+        dssIsChainedWithDiffID_ = true;
+        nextCorrelationID = dssCorrelationID_ + 1;
+      }
+    }
+    else {
+      // chaining bit not b'1', make sure DSSFMT bit3 not b'1'
+      if ((gdsFormatter & 0x10) == 0x10)  {  // Next DSS can not have same 
correlator
+        doSyntaxrmSemantics(CodePoint.SYNERRCD_CHAIN_OFF_SAME_NEXT_CORRELATOR);
+      }
+
+      // chaining bit not b'1', make sure no error continuation
+      if ((gdsFormatter & 0x20) == 0x20) { // must be 'do not continue on 
error'
+        doSyntaxrmSemantics(CodePoint.SYNERRCD_CHAIN_OFF_ERROR_CONTINUE);
+      }
+
+      dssIsChainedWithSameID_ = false;
+      dssIsChainedWithDiffID_ = false;
+      nextCorrelationID = 1;
+    }
+
+    correlationID =
+      ((buffer_[pos_++]&0xFF) << 8) +
+      ((buffer_[pos_++]&0xFF) << 0);
+
+    // corrid must be the one expected or a -1 which gets returned in some 
error cases.
+    if ((correlationID != dssCorrelationID_) && (correlationID != 0xFFFF)){
+      doSyntaxrmSemantics (CodePoint.SYNERRCD_INVALID_CORRELATOR);
+    }
+    else {
+      dssCorrelationID_ = nextCorrelationID;
+    }
+    dssLength_ -= 6;
+     if ((gdsFormatter & 0x04) == 0x04 )
+       decryptData (gdsFormatter, oldDssLength);  //we have to decrypt data 
here because
+                                                  //we need the decrypted 
codepoint. If
+                                                  //Data is very long > 32767, 
we have to
+                                                  //get all the data first 
because decrypt
+                                                  //piece by piece doesn't 
work.
+  }
+
+
+
+  private final void decryptData(int gdsFormatter, int oldDssLength) throws 
org.apache.derby.client.am.DisconnectException
+  {
+        boolean readHeader;
+
+        if(dssLength_ == 32761) {
+          ByteArrayOutputStream baos;
+          int copySize = 0;
+
+          baos = new ByteArrayOutputStream ();
+
+          // set the amount to read for the first segment
+          copySize = dssLength_; // note: has already been adjusted for headers
+
+          do {
+            // determine if a continuation header needs to be read after the 
data
+            if (dssIsContinued_)
+              readHeader = true;
+            else
+              readHeader = false;
+
+            // read the segment
+            ensureALayerDataInBuffer (copySize);
+            adjustLengths (copySize);
+            baos.write (buffer_, pos_, copySize);
+            pos_ += copySize;
+
+            // read the continuation header, if necessary
+            if (readHeader)
+              readDSSContinuationHeader ();
+
+            copySize = dssLength_;
+          }
+          while (readHeader == true);
+          byte[] cipherBytes = baos.toByteArray();
+          byte[] clearedByte = null;
+          try{
+            clearedByte = 
netAgent_.netConnection_.getEncryptionManager().decryptData(
+                cipherBytes,
+                NetConfiguration.SECMEC_EUSRIDPWD,
+                netAgent_.netConnection_.getTargetPublicKey(),
+                netAgent_.netConnection_.getTargetPublicKey());
+          }
+          catch (SqlException e)
+          {
+            //throw new SqlException (agent_.logWriter_, "error in decrypting 
data");
+          }
+
+          //The decrypted data is for one codepoint only. We need to save the 
data follows this codepoint
+          longBufferForDecryption_ = new byte[buffer_.length - pos_];
+          longPosForDecryption_ = 0;
+          count_ = count_ - pos_;
+          longCountForDecryption_ = count_;
+          
System.arraycopy(buffer_,pos_,longBufferForDecryption_,0,buffer_.length - pos_);
+
+          //copy the clear data to buffer_
+          if (clearedByte.length >=32767)
+            System.arraycopy(clearedByte,0,buffer_,0,32767);
+         else
+             System.arraycopy(clearedByte,0,buffer_,0,clearedByte.length);
+
+          pos_ = 0;
+          dssLength_ = buffer_.length;
+
+          int lobLength = 0;
+          if(clearedByte.length > 32767) {  //for extended length, length is 
the 4 bytes that follow codepoint
+            lobLength = ( (clearedByte[4] & 0xFF) << 24) +
+                ( (clearedByte[5] & 0xFF) << 16) +
+                ( (clearedByte[6] & 0xFF) << 8) +
+                ( (clearedByte[7] & 0xFF) << 0);
+            longValueForDecryption_ = new byte[lobLength];
+            System.arraycopy (clearedByte, 8, longValueForDecryption_, 0, 
clearedByte.length-8);
+          }
+          else {
+            lobLength = ( (clearedByte[0] & 0xFF) << 8) +
+                ( (clearedByte[1] & 0xFF) << 0);
+            longValueForDecryption_ = new byte[lobLength-4];
+            System.arraycopy (clearedByte, 4, longValueForDecryption_, 0, 
clearedByte.length-4);
+          }
+        }
+
+        else{
+        int bytesRead = ensureALayerDataInBuffer (dssLength_);  //we need to 
get back all the data here, and then decrypt
+        if (bytesRead > 0) //we ensuredALayerDAtaInBuffer here and set the 
flag to true, so we don't need do this again later
+          ensuredLengthForDecryption_ = true;
+        byte[] encryptedByte = new byte[dssLength_];
+        System.arraycopy(buffer_,pos_,encryptedByte,0,dssLength_);
+        byte[] array1 = new byte[pos_];
+        System.arraycopy(buffer_,0,array1,0,pos_);  //save the data before 
encrypted data in array1
+        byte[] array3 = new byte[buffer_.length - dssLength_ - pos_];
+        System.arraycopy(buffer_,pos_+dssLength_,array3,0,buffer_.length - 
dssLength_ - pos_); //save the data follows encrypted data in array3
+        byte[] clearedByte = null;
+        try{
+          clearedByte = 
netAgent_.netConnection_.getEncryptionManager().decryptData(
+              encryptedByte,
+              NetConfiguration.SECMEC_EUSRIDPWD,
+              netAgent_.netConnection_.getTargetPublicKey(),
+              netAgent_.netConnection_.getTargetPublicKey());
+        }
+        catch (SqlException e)
+        {
+          //throw new SqlException (agent_.logWriter_, "error in decrypting 
data");
+        }
+        dssLength_ -= (encryptedByte.length - clearedByte.length);
+        byte[] buffer = new byte[array1.length + clearedByte.length + 
array3.length];
+        System.arraycopy(array1,0,buffer,0,array1.length);
+        
System.arraycopy(clearedByte,0,buffer,array1.length,clearedByte.length);
+        
System.arraycopy(array3,0,buffer,array1.length+clearedByte.length,array3.length);
+        buffer_ = buffer;
+        int oldCount = count_;
+        count_ = count_ - (encryptedByte.length - clearedByte.length);
+        if (((clearedByte[2]& 0xff) << 8) + ((clearedByte[3] & 0xff) << 0) == 
0x146c) {
+          int firstLobLength = ( (clearedByte[0] & 0xFF) << 8) +
+                ( (clearedByte[1] & 0xFF) << 0);
+
+          boolean flag = false;
+          if (gdsFormatter == 0x54)
+            flag = true;
+          if(flag){
+             if (oldCount - oldDssLength < 6) {
+               int totalBytesRead = fill(6); //sometimes the 2nd EXTDTA 
doesn't come back, need to fetch again to get it
+               if (totalBytesRead > 0) {
+                 longBufferForDecryption_ = new byte[totalBytesRead];
+                 longPosForDecryption_ = 0;
+                 System.arraycopy(buffer_, pos_ + firstLobLength, 
longBufferForDecryption_, 0,
+                                  totalBytesRead);
+               }
+
+  }
+             else {
+               longBufferForDecryption_ = new byte[count_ - pos_ - 
firstLobLength];
+               longPosForDecryption_ = 0;
+               System.arraycopy(buffer_, pos_ + firstLobLength, 
longBufferForDecryption_, 0,
+                                longBufferForDecryption_.length);
+
+             }
+         } //end if(flag)
+         int lobLength = ( (clearedByte[0] & 0xFF) << 8) +
+              ( (clearedByte[1] & 0xFF) << 0) - 4;
+
+         longValueForDecryption_ = new byte[lobLength];
+
+         System.arraycopy (clearedByte, 4, longValueForDecryption_, 0, 
clearedByte.length - 4);  //copy the decrypted lob value (excluded length an 
dcodepoint) to longValue_
+        }
+        else if (((clearedByte[2]& 0xff) << 8) + ((clearedByte[3] & 0xff) << 
0) == 0x241B){
+          int length = ( (clearedByte[0] & 0xFF) << 8) +
+              ( (clearedByte[1] & 0xFF) << 0);
+          boolean noData = false;
+          if  (clearedByte[4] == -1 && clearedByte[5] == -1)
+              noData = true; //there is no data, no need to do the copy
+          if (!noData) {
+              if (length == 32776) {
+                length = ( (clearedByte[4] & 0xFF) << 24) +
+                    ( (clearedByte[5] & 0xFF) << 16) +
+                    ( (clearedByte[6] & 0xFF) << 8) +
+                    ( (clearedByte[7] & 0xFF) << 0);
+                longValueForDecryption_ = new byte[length];
+                System.arraycopy (clearedByte, 8, longValueForDecryption_, 0,
+                                  clearedByte.length - 8);
+                longCountForDecryption_ = count_ - (pos_ + length + 8);
+                longBufferForDecryption_ = new byte[buffer_.length - pos_ - 
length - 8];
+                System.arraycopy(buffer_, pos_ + length + 8, 
longBufferForDecryption_, 0,
+                                   longBufferForDecryption_.length);
+
+              }
+              else {
+                longPosForDecryption_ = 0;
+                longCountForDecryption_ = count_ - (pos_ + length);
+                longBufferForDecryption_ = new byte[buffer_.length - pos_ - 
length];
+                System.arraycopy (buffer_, pos_ + length, 
longBufferForDecryption_, 0,
+                                   longBufferForDecryption_.length);
+
+                longValueForDecryption_ = new byte[length - 4];
+
+                System.arraycopy (clearedByte, 4, longValueForDecryption_, 0,
+                                  clearedByte.length - 4);
+              }
+            }
+        }
+      }
+    }
+
+
+  final int readUnsignedShort () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    // should we be checking dss lengths and ddmScalarLengths here 
+    // if yes, i am not sure this is the correct place if we should be 
checking 
+    ensureBLayerDataInBuffer (2);
+    adjustLengths (2);
+    return ((buffer_[pos_++] & 0xff) << 8) +
+      ((buffer_[pos_++] & 0xff) << 0);
+  }
+
+  final short readShort () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    // should we be checking dss lengths and ddmScalarLengths here 
+    ensureBLayerDataInBuffer (2);
+    adjustLengths (2);
+    short s = SignedBinary.getShort (buffer_, pos_);
+
+    pos_ += 2;
+
+    return s;
+  }
+
+  final int readInt () throws org.apache.derby.client.am.DisconnectException
+  {
+    // should we be checking dss lengths and ddmScalarLengths here 
+    ensureBLayerDataInBuffer (4);
+    adjustLengths (4);
+    int i = SignedBinary.getInt (buffer_, pos_);
+    pos_ += 4;
+
+    return i;
+  }
+
+  final void readIntArray (int[] array) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (array.length * 4);
+    adjustLengths (array.length * 4);
+
+    for (int i = 0; i < array.length; i++) {
+      array[i] = SignedBinary.getInt (buffer_, pos_);
+      pos_ += 4;
+    }
+  }
+
+
+  final long readLong () throws org.apache.derby.client.am.DisconnectException
+  {
+    // should we be checking dss lengths and ddmScalarLengths here
+    ensureBLayerDataInBuffer (8);
+    adjustLengths (8);
+    long l = SignedBinary.getLong (buffer_, pos_);
+
+    pos_ += 8;
+
+    return l;
+  }
+
+
+  final int [] readUnsignedShortList()  throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int len = ddmScalarLen_;
+    ensureBLayerDataInBuffer (len);
+    adjustLengths (len);
+
+    int count = len/2;
+    int[] list = new int[count];
+
+    for (int i=0; i < count; i++) {
+      list[i] = ((buffer_[pos_++] & 0xff) << 8) +
+        ((buffer_[pos_++] & 0xff) << 0);
+    }
+
+    return list;
+  }
+
+  final int readUnsignedByte () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (1);
+    adjustLengths (1);
+    return (buffer_[pos_++] & 0xff);
+  }
+
+  final byte readByte () throws org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (1);
+    adjustLengths (1);
+    return (byte) (buffer_[pos_++] & 0xff);
+  }
+
+  final boolean readBoolean () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (1);
+    adjustLengths (1);
+    return buffer_[pos_++] != 0;
+  }
+
+  final String readString (int length) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (length);
+    adjustLengths (length);
+
+    String result = ccsidManager_.convertToUCS2 (buffer_, pos_, length);
+    pos_ += length;
+    return result;
+  }
+
+  final String readString (int length, String encoding) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (length);
+    adjustLengths (length);
+    String s = null;
+
+    try {
+      s = new String (buffer_, pos_, length, encoding);
+    }
+    catch (java.io.UnsupportedEncodingException e) {
+      agent_.accumulateChainBreakingReadExceptionAndThrow (
+        new org.apache.derby.client.am.DisconnectException (
+          e,
+          agent_,
+          "encoding not supported!!"));
+    }
+
+    pos_ += length;
+    return s;
+  }
+
+  final String readString () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int len = ddmScalarLen_;
+    ensureBLayerDataInBuffer (len);
+    adjustLengths (len);
+    String result = ccsidManager_.convertToUCS2 (buffer_, pos_, len);
+    pos_ += len;
+    return result;
+  }
+
+  final byte[] readBytes (int length) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (length);
+    adjustLengths (length);
+
+    byte[] b = new byte[length];
+    System.arraycopy (buffer_, pos_, b, 0, length);
+    pos_ += length;
+    return b;
+  }
+
+  final byte[] readBytes () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int len = ddmScalarLen_;
+    ensureBLayerDataInBuffer (len);
+    adjustLengths (len);
+
+    byte[] b = new byte[len];
+    System.arraycopy (buffer_, pos_, b, 0, len);
+    pos_ += len;
+    return b;
+  }
+
+  final byte[] readLDBytes () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (2);
+    int len = ((buffer_[pos_++] & 0xff) << 8) + ((buffer_[pos_++] & 0xff) << 
0);
+
+    if (len == 0) {
+      adjustLengths (2);
+      return null;
+    }
+
+    ensureBLayerDataInBuffer (len);
+    adjustLengths (len + 2);
+
+    byte [] b = new byte[len];
+    System.arraycopy (buffer_, pos_, b, 0, len);
+    pos_ += len;
+    return b;
+  }
+
+  final void skipBytes (int length) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (length);
+    adjustLengths (length);
+    pos_ += length;
+  }
+
+  final void skipBytes () throws org.apache.derby.client.am.DisconnectException
+  {
+    int len = ddmScalarLen_;
+    ensureBLayerDataInBuffer (len);
+    adjustLengths (len);
+    pos_ += len;
+  }
+
+  // This will be the new and improved getData that handles all QRYDTA/EXTDTA
+  // Returns the stream so that the caller can cache it
+  final ByteArrayOutputStream getData (ByteArrayOutputStream existingBuffer) 
throws org.apache.derby.client.am.DisconnectException
+  {
+    boolean readHeader;
+    int copySize;
+    ByteArrayOutputStream baos;
+
+    // note: an empty baos can yield an allocated and empty byte[]
+    if (existingBuffer != null)
+      baos = existingBuffer;
+    else {
+      if (ddmScalarLen_ != -1) {
+        // allocate a stream based on a known amount of data
+        baos = new ByteArrayOutputStream (ddmScalarLen_);
+      }
+      else {
+        // allocate a stream to hold an unknown amount of data
+        baos = new ByteArrayOutputStream ();
+        //isLengthAndNullabilityUnknown = true;
+      }
+    }
+
+    // set the amount to read for the first segment
+    copySize = dssLength_; // note: has already been adjusted for headers
+
+    do {
+      // determine if a continuation header needs to be read after the data
+      if (dssIsContinued_)
+        readHeader = true;
+      else
+        readHeader = false;
+
+      // read the segment
+      ensureALayerDataInBuffer (copySize);
+      adjustLengths (copySize);
+      baos.write (buffer_, pos_, copySize);
+      pos_ += copySize;
+
+      // read the continuation header, if necessary
+      if (readHeader)
+        readDSSContinuationHeader ();
+
+      copySize = dssLength_;
+    }
+    while (readHeader == true);
+
+    return baos;
+  }
+
+  // reads a DSS continuation header
+  // prereq: pos_ is positioned on the first byte of the two-byte header
+  // post:   dssIsContinued_ is set to true if the continuation bit is on, 
false otherwise
+  //         dssLength_ is set to DssConstants.MAX_DSS_LEN - 2 (don't count 
the header for the next read)
+  // helper method for getEXTDTAData
+  protected final void readDSSContinuationHeader () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureALayerDataInBuffer(2);
+
+    dssLength_ =
+      ((buffer_[pos_++]&0xFF) << 8) +
+      ((buffer_[pos_++]&0xFF) << 0);
+
+    if ((dssLength_ & 0x8000) == 0x8000) {
+      dssLength_ = DssConstants.MAX_DSS_LEN;
+      dssIsContinued_ = true;
+    }
+    else {
+      dssIsContinued_ = false;
+    }
+    // it is a syntax error if the dss continuation header length
+    // is less than or equal to two
+    if (dssLength_ <= 2) {
+      doSyntaxrmSemantics (CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2);
+    }
+
+    dssLength_ -= 2;  // avoid consuming the DSS cont header
+  }
+
+
+  // As part of parsing the reply, the client can detect that the
+  // data sent from the target agent does not structurally
+  // conform to the requirements of the DDM architecture.  These are
+  // the same checks performed by the target server on the messages
+  // it receives from the protocolj code.  Server side detected errors
+  // result in a SYNTAXRM being returned from the AS.  According to the
+  // DDM manual, parsing of the DSS is terminated when the error is
+  // detected.  The Syntax Error Code, SYNERRCD, describes the various errors.
+  //
+  // Note: Not all of these may be valid at the client.  See descriptions for
+  // which ones make sense for client side errors/checks.
+  // Syntax Error Code                  Description of Error
+  // -----------------                  --------------------
+  // 0x01                               Dss header Length is less than 6.
+  // 0x02                               Dss header Length does not match the
+  //                                    number of bytes of data found.
+  // 0x03                               Dss header C-byte not D0.
+  // 0x04                               Dss header f-bytes either not
+  //                                    recognized or not supported.
+  // 0x05                               DSS continuation specified but not 
found.
+  //                                    For example, DSS continuation is 
specified
+  //                                    on the last DSS, and the SNA LU 6.2 
communication
+  //                                    facility returned the SEND indicator.
+  // 0x06                               DSS chaining specified but no DSS 
found.
+  //                                    For example, DSS chaining is specified
+  //                                    on the last DSS, and the SNA LU 6.2 
communication
+  //                                    facility returned the SEND indicator.
+  // 0x07                               Object length less than four.  For 
example,
+  //                                    a command parameter's length is 
specified
+  //                                    as two, or a command's length is 
specified as three.
+  // 0x08                               Object length does not match the 
number of bytes of data
+  //                                    found.  For example, a RQSDSS with a 
length of 150
+  //                                    contains a command whose length is 125 
or a SRVDGN parameter
+  //                                    specifies a length of 200 but there 
are only 50
+  //                                    bytes left in the DSS.
+  // 0x09                               Object length greater than maximum 
allowed.
+  //                                    For example, a RECCNT parameter 
specifies a
+  //                                    length of ten, but the parameter is 
defined
+  //                                    to have a maximum length of eight.
+  // 0x0A                               Object length less than the minimum 
required.
+  //                                    For example, a SVRCOD parameter 
specifies a
+  //                                    length of five, but the parameter is 
defined
+  //                                    to have a fixed length of six.
+  // 0x0B                               Object length not allowed.  For 
example,
+  //                                    a FILEXDPT parameter is specified with 
a length of
+  //                                    11, but this would indicate that only 
half of the hours
+  //                                    field is present instead of the 
complete hours field.
+  // 0x0C                               Incorrect large object extended length 
field (see
+  //                                    description of DSS).  For example, an 
extended
+  //                                    length field is present, but it is 
only three bytes
+  //                                    long when it is defined to be a 
multiple of two bytes.
+  // 0x0D                               Object code point index not supported.
+  //                                    For example, a code point of 8032 is 
encountered
+  //                                    but x'8' is a reserved code point 
index.
+  // 0x0E                               Required object not found.  For 
example, a CLEAR
+  //                                    command does not have a filnam 
parameter present,
+  //                                    or a MODREC command is not followed by 
a RECORD
+  //                                    command data object.
+  // 0x0F                               Too many command data objects sent.  
For example,
+  //                                    a MODREC command is followed by two 
RECORD command
+  //                                    command data objects, or a DECREC 
command is followed
+  //                                    by RECORD object.
+  // 0x10                               Mutually exclusive objects present.
+  //                                    For example, a CRTDIRF command 
specifies both
+  //                                    a DCLNAM and FILNAM parameters.
+  // 0x11                               Too few command data objects sent.
+  //                                    For example, an INSRECEF command that
+  //                                    specified RECCNT95) is followed by only
+  //                                    4 RECORD command data objects.
+  // 0x12                               Duplicate object present.
+  //                                    For example, a LSTFAT command has tow 
FILNAM
+  //                                    parameters specified.
+  // 0x13                               Invalid request correlator specified.
+  //                                    Use PRCCNVRM with PRCCNVDC of 04 or 05 
instead
+  //                                    of this error code.  This error code 
is being retained
+  //                                    for compatibility with Level 1 of the 
architecture.
+  // 0x14                               Required value not found.
+  // 0x15                               Reserved value not allowed.  For 
example,
+  //                                    a INSRECEF command specified a 
RECCNT(0) parameter.
+  // 0x16                               DSS continuation less than or equal to 
two.
+  //                                    For example, the length bytes of the 
DSS continuation
+  //                                    have the value of one.
+  // 0x17                               Objects not in required order.  For 
example, a RECAL
+  //                                    object contains a RECORD object 
followed by a RECNBR
+  //                                    object with is not in the defined 
order.
+  // 0x18                               DSS chaining byt not b'1', but DSSFMT 
bit3 set to b'1'.
+  // 0x19                               Previous DSS indicated current DSS has 
the same
+  //                                    request correlator, but the request 
correlators are
+  //                                    not the same.
+  // 0x1A                               DSS cahining bit not b'1', but error 
continuation requested.
+  // 0x1B                               Mutually exclusive parameter values 
not specified.
+  //                                    For example, an OPEN command specified 
PRPSHD(TRUE)
+  //                                    and FILSHR(READER).
+  // 0x1D                               Code point not valid command.  For 
example, the first
+  //                                    code point in RQSDSS either is not in 
the dictionary
+  //                                    or is not a code point for a command.
+  //
+  // When the client detects these errors, it will be handled as if a SYNTAXRM 
is returned
+  // from the server.  In this SYNTAXRM case, PROTOCOL architects an SQLSTATE 
of 58008 or 58009.
+  //
+  // Messages
+  // SQLSTATE : 58009
+  //     Execution failed due to a distribution protocol error that caused 
deallocation of the conversation.
+  //     SQLCODE : -30020
+  //     Execution failed because of a Distributed Protocol
+  //         Error that will affect the successful execution of subsequent
+  //         commands and SQL statements: Reason Code <reason-code>.
+  //      Some possible reason codes include:
+  //      121C Indicates that the user is not authorized to perform the 
requested command.
+  //      1232 The command could not be completed because of a permanent error.
+  //          In most cases, the server will be in the process of an abend.
+  //      220A The target server has received an invalid data description.
+  //          If a user SQLDA is specified, ensure that the fields are
+  //          initialized correctly. Also, ensure that the length does not
+  //          exceed the maximum allowed length for the data type being used.
+  //
+  //      The command or statement cannot be processed.  The current
+  //          transaction is rolled back and the application is disconnected
+  //          from the remote database.
+  final void doSyntaxrmSemantics (int syntaxErrorCode) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    agent_.accumulateChainBreakingReadExceptionAndThrow (
+      new org.apache.derby.client.am.DisconnectException (
+        agent_,
+        "Execution failed due to a distribution protocol error " +
+        "that caused deallocation of the conversation.  " +
+        "A PROTOCOL Data Stream Syntax Error was detected.  Reason: " +
+        "0x" + Integer.toHexString (syntaxErrorCode),
+        SqlState._58009));
+  }
+
+
+// the names of these methods start with a letter z.
+// the z will be removed when they are finalized...
+
+  protected final void pushLengthOnCollectionStack()
+  {
+    ddmCollectionLenStack_[++topDdmCollectionStack_] = ddmScalarLen_;
+    ddmScalarLen_ = 0;
+  }
+
+  protected final void adjustLengths(int length)
+  {
+    ddmScalarLen_ -= length;
+    adjustCollectionAndDssLengths (length);
+    /*
+    for (int i = 0; i <= topDdmCollectionStack_; i++) {
+      ddmCollectionLenStack_[i] -= length;
+    }
+    dssLength_ -= length;
+    */
+  }
+
+  protected int adjustDdmLength (int ddmLength, int length)
+  {
+    ddmLength -= length;
+    if (ddmLength == 0)
+      adjustLengths (getDdmLength());
+    return ddmLength;
+  }
+
+  // Pop the collection Length stack.
+  // pre:  The collection length stack must not be empty and the top value
+  //       on the stack must be 0.
+  // post: The top 0 value on the stack will be popped.
+  protected final void popCollectionStack()
+  {
+    topDdmCollectionStack_--;
+  }
+
+  protected final int peekCodePoint() throws 
org.apache.derby.client.am.DisconnectException
+  {
+    if (topDdmCollectionStack_ != EMPTY_STACK) {
+      if (ddmCollectionLenStack_[topDdmCollectionStack_] == 0)
+        return END_OF_COLLECTION;
+      else if (ddmCollectionLenStack_[topDdmCollectionStack_] < 4) {
+        // error
+      }
+    }
+
+    // if there is no more data in the current dss, and the dss is not
+    // continued, indicate the end of the same Id chain or read the next dss 
header.
+    if ((dssLength_ == 0) && (!dssIsContinued_)) {
+      if (!dssIsChainedWithSameID_) {
+        return END_OF_SAME_ID_CHAIN;
+      }
+      readDssHeader();
+    }
+
+    if (longBufferForDecryption_ == null)  //we don't need to do this if it's 
data stream encryption
+    ensureBLayerDataInBuffer (4);
+    peekedLength_ = ((buffer_[pos_] & 0xff) << 8) + ((buffer_[pos_+1] & 0xff) 
<< 0);
+    peekedCodePoint_ = ((buffer_[pos_+2] & 0xff) << 8) + ((buffer_[pos_+3] & 
0xff) << 0);
+
+    // check for extended length
+    if ((peekedLength_ & 0x8000) == 0x8000)
+      peekExtendedLength();
+    else
+      peekedNumOfExtendedLenBytes_ = 0;
+    return peekedCodePoint_;
+  }
+
+  // Read out the 2-byte length without moving the pos_ pointer.
+  protected final int peekLength() throws 
org.apache.derby.client.am.DisconnectException
+  {
+    ensureBLayerDataInBuffer (2);
+    return (((buffer_[pos_] & 0xff) << 8) +
+            ((buffer_[pos_ + 1] & 0xff) << 0));
+  }
+
+  // Read "length" number of bytes from the buffer into the byte array b 
starting from offset
+  // "offset".  The current offset in the buffer does not change.
+  protected final int peekFastBytes (byte[] b, int offset, int length) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    for (int i = 0; i < length; i++) {
+      b[offset+i] = buffer_[pos_+i];
+    }
+    return offset+length;
+  }
+
+  protected final void parseLengthAndMatchCodePoint (int expectedCodePoint) 
throws org.apache.derby.client.am.DisconnectException
+  {
+    int actualCodePoint = 0;
+    if (peekedCodePoint_ == END_OF_COLLECTION)
+      actualCodePoint = readLengthAndCodePoint();
+    else {
+      actualCodePoint = peekedCodePoint_;
+      pos_ += (4 + peekedNumOfExtendedLenBytes_);
+      ddmScalarLen_ = peekedLength_;
+      if (peekedNumOfExtendedLenBytes_ == 0 && ddmScalarLen_ != -1) {
+        adjustLengths (4);
+      }
+      else {
+        adjustCollectionAndDssLengths (4+peekedNumOfExtendedLenBytes_);
+      }
+      peekedLength_ = 0;
+      peekedCodePoint_ = END_OF_COLLECTION;
+      peekedNumOfExtendedLenBytes_ = 0;
+    }
+
+    if (actualCodePoint != expectedCodePoint) {
+      zThrowSyntaxError ("actual code point, " + actualCodePoint +
+                         " does not match expected code point, " + 
expectedCodePoint);
+    }
+  }
+  protected final int readLengthAndCodePoint () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    if (topDdmCollectionStack_ != EMPTY_STACK) {
+      if (ddmCollectionLenStack_[topDdmCollectionStack_] == 0)
+        return END_OF_COLLECTION;
+      else if (ddmCollectionLenStack_[topDdmCollectionStack_] < 4) {
+        zThrowSyntaxError ("ddm collection contains less than 4 bytes of 
data");
+      }
+    }
+
+    // if there is no more data in the current dss, and the dss is not
+    // continued, indicate the end of the same Id chain or read the next dss 
header.
+    if ((dssLength_ == 0) && (!dssIsContinued_)) {
+      if (!dssIsChainedWithSameID_) {
+        return END_OF_SAME_ID_CHAIN;
+      }
+      readDssHeader();
+    }
+
+    ensureBLayerDataInBuffer (4);
+    ddmScalarLen_ =
+      ((buffer_[pos_++] & 0xff) << 8) +
+      ((buffer_[pos_++] & 0xff) << 0);
+    int codePoint = ((buffer_[pos_++] & 0xff) << 8) +
+      ((buffer_[pos_++] & 0xff) << 0);
+    adjustLengths (4);
+
+    // check for extended length
+    if ((ddmScalarLen_ & 0x8000) == 0x8000) {
+      readExtendedLength();
+    }
+    return codePoint;
+  }
+
+  private final void readExtendedLength() throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int numberOfExtendedLenBytes = (ddmScalarLen_ - 0x8000); // fix scroll 
problem was - 4
+    int adjustSize = 0;
+    switch (numberOfExtendedLenBytes) {
+    case 4:
+      ensureBLayerDataInBuffer (4);
+      ddmScalarLen_ =
+        ((buffer_[pos_++] & 0xff) << 32) +
+        ((buffer_[pos_++] & 0xff) << 16) +
+        ((buffer_[pos_++] & 0xff) << 8) +
+        ((buffer_[pos_++] & 0xff) << 0);
+      adjustSize = 4;     
+      break;
+    case 0:
+      ddmScalarLen_ = -1; 
+      adjustSize = 0;    
+      break;
+    default:
+      doSyntaxrmSemantics(CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN);
+    }
+
+    adjustCollectionAndDssLengths (adjustSize);
+    /*
+    // adjust the lengths here.  this is a special case since the
+    // extended length bytes do not include their own length.
+    for (int i = 0; i <= topDdmCollectionStack_; i++) {
+      ddmCollectionLenStack_[i] -= adjustSize;
+    }
+    dssLength_ -= adjustSize;
+    */
+  }
+
+  private final void adjustCollectionAndDssLengths (int length)
+  {
+    // adjust the lengths here.  this is a special case since the
+    // extended length bytes do not include their own length.
+    for (int i = 0; i <= topDdmCollectionStack_; i++) {
+      ddmCollectionLenStack_[i] -= length;
+    }
+    dssLength_ -= length;
+  }
+
+  protected final void startSameIdChainParse() throws 
org.apache.derby.client.am.DisconnectException
+  {
+    readDssHeader ();
+    netAgent_.clearSvrcod();
+  }
+
+  protected final void endOfSameIdChainData() throws 
org.apache.derby.client.am.DisconnectException
+  {
+    netAgent_.targetTypdef_ = netAgent_.originalTargetTypdef_;
+    netAgent_.targetSqlam_ = netAgent_.orignalTargetSqlam_;
+
+    if (this.topDdmCollectionStack_ != Reply.EMPTY_STACK) {
+      zThrowSyntaxError ("collection stack not empty at end of same id chain 
parse");
+    }
+    if (this.dssLength_ != 0) {
+      zThrowSyntaxError ("dss length not 0 at end of same id chain parse");
+    }
+    if (dssIsChainedWithSameID_ == true) {
+      zThrowSyntaxError ("dss chained with same id at end of same id chain 
parse");
+    }
+  }
+
+  private final void zThrowSyntaxError (String error) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    agent_.accumulateChainBreakingReadExceptionAndThrow (
+      new org.apache.derby.client.am.DisconnectException (agent_, error));
+  }
+
+  protected final int peekTotalColumnCount (int tripletLength) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int columnCount = 0;
+    int offset = 0;
+    int tripletType = FdocaConstants.CPT_TRIPLET_TYPE;
+    while (tripletType == FdocaConstants.CPT_TRIPLET_TYPE) {
+      columnCount += ((tripletLength-3)/3);
+      // Peek ahead for the next triplet's tripletLength and tripletType.
+      // The number of bytes to skip before the next tripletType is 
tripletLength - 3.
+      ensureBLayerDataInBuffer (tripletLength-3);
+      offset += (tripletLength-3);
+      tripletLength = (buffer_[pos_+offset++] & 0xff);
+      tripletType = (buffer_[pos_+offset++] & 0xff);
+      // Skip the 1-byte tripletId.
+      offset++;
+    }
+    return columnCount;
+  }
+
+  private final void peekExtendedLength () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    peekedNumOfExtendedLenBytes_ = (peekedLength_ - 0x8004);
+    switch (peekedNumOfExtendedLenBytes_) {
+    case 4:
+      // L   L   C   P  Extended Length
+      // -->2-bytes<--  --->4-bytes<---
+      // We are only peeking the length here, the actual pos_ is still before 
LLCP.  We ensured
+      // 4-bytes in peedCodePoint() for the LLCP, and we need to ensure 
4-bytes(of LLCP) + the
+      // extended length bytes here.
+      if (longBufferForDecryption_ == null ) //we ddon't need to do this if 
it's data stream encryption
+      ensureBLayerDataInBuffer (4 + 4);
+      // The ddmScalarLen_ we peek here does not include the LLCP and the 
extended length bytes
+      // themselves.  So we will add those back to the ddmScalarLen_ so it can 
be adjusted
+      // correctly in parseLengthAndMatchCodePoint(). (since the 
adjustLengths() method will
+      // subtract the length from ddmScalarLen_)
+      peekedLength_ =
+        ((buffer_[pos_+4] & 0xff) << 32) +
+        ((buffer_[pos_+5] & 0xff) << 16) +
+        ((buffer_[pos_+6] & 0xff) << 8) +
+        ((buffer_[pos_+7] & 0xff) << 0);
+      break;
+    case 0:
+      peekedLength_ = -1; // this ddm is streamed, so set -1 -> length unknown
+      break;
+    default:
+      doSyntaxrmSemantics(CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN);
+    }
+  }
+
+  final int readFastUnsignedByte () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    return (buffer_[pos_++] & 0xff);
+  }
+
+  final short readFastShort () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    short s = SignedBinary.getShort (buffer_, pos_);
+    pos_ += 2;
+    return s;
+  }
+
+  final int readFastUnsignedShort () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    return ((buffer_[pos_++] & 0xff) << 8) +
+      ((buffer_[pos_++] & 0xff) << 0);
+  }
+
+  final int readFastInt () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int i = SignedBinary.getInt (buffer_, pos_);
+    pos_ += 4;
+    return i;
+  }
+
+  final String readFastString (int length) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    String result = ccsidManager_.convertToUCS2 (buffer_, pos_, length);
+    pos_ += length;
+    return result;
+  }
+
+  final byte[] readFastBytes (int length) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    byte[] b = new byte[length];
+    System.arraycopy (buffer_, pos_, b, 0, length);
+    pos_ += length;
+    return b;
+  }
+
+  protected final int peekFastLength() throws 
org.apache.derby.client.am.DisconnectException
+  {
+    return (((buffer_[pos_] & 0xff) << 8) +
+            ((buffer_[pos_ + 1] & 0xff) << 0));
+  }
+
+  final void skipFastBytes (int length) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    pos_ += length;
+  }
+
+  final void readFastIntArray (int[] array) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    for (int i = 0; i < array.length; i++) {
+      array[i] = SignedBinary.getInt (buffer_, pos_);
+      pos_ += 4;
+    }
+  }
+
+  final String readFastString (int length, String encoding) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    String s = null;
+
+    try {
+      s = new String (buffer_, pos_, length, encoding);
+    }
+    catch (java.io.UnsupportedEncodingException e) {
+      agent_.accumulateChainBreakingReadExceptionAndThrow (
+        new org.apache.derby.client.am.DisconnectException (
+          e,
+          agent_,
+          "encoding not supported!!"));
+    }
+    pos_ += length;
+    return s;
+  }
+
+  final byte[] readFastLDBytes () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int len = ((buffer_[pos_++] & 0xff) << 8) + ((buffer_[pos_++] & 0xff) << 
0);
+    if (len == 0) return null;
+
+    byte [] b = new byte[len];
+    System.arraycopy (buffer_, pos_, b, 0, len);
+    pos_ += len;
+    return b;
+  }
+  final long readFastLong () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    long l = SignedBinary.getLong (buffer_, pos_ );
+    pos_ += 8;
+    return l;
+  }
+
+  final byte readFastByte () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    return (byte) (buffer_[pos_++] & 0xff);
+}
+
+  final void mark()
+  {
+    currentPos_ = pos_;
+  }
+
+  // remove and return the top offset value from mark stack.
+  final int popMark()
+  {
+    return currentPos_;
+  }
+
+  final int getFastSkipSQLCARDrowLength ()
+  {
+    return pos_ - popMark();
+  }
+
+  // The only difference between this method and the original getData() method 
is this method
+  // is not doing an ensureALayerDataInBuffer
+  final ByteArrayOutputStream getFastData (ByteArrayOutputStream 
existingBuffer) throws org.apache.derby.client.am.DisconnectException
+  {
+    boolean readHeader;
+    int copySize;
+    ByteArrayOutputStream baos;
+
+    // note: an empty baos can yield an allocated and empty byte[]
+    if (existingBuffer != null)
+      baos = existingBuffer;
+    else {
+      if (ddmScalarLen_ != -1) {
+        // allocate a stream based on a known amount of data
+        baos = new ByteArrayOutputStream (ddmScalarLen_);
+      }
+      else {
+        // allocate a stream to hold an unknown amount of data
+        baos = new ByteArrayOutputStream ();
+        //isLengthAndNullabilityUnknown = true;
+      }
+    }
+
+    // set the amount to read for the first segment
+    copySize = dssLength_; // note: has already been adjusted for headers
+
+    do {
+      // determine if a continuation header needs to be read after the data
+      if (dssIsContinued_)
+        readHeader = true;
+      else
+        readHeader = false;
+
+      // read the segment
+      //ensureALayerDataInBuffer (copySize);
+      adjustLengths (copySize);
+      baos.write (buffer_, pos_, copySize);
+      pos_ += copySize;
+
+      // read the continuation header, if necessary
+      if (readHeader)
+        readDSSContinuationHeader ();
+
+      copySize = dssLength_;
+    }
+    while (readHeader == true);
+
+    return baos;
+  }
+
+  // This method is only used to match the codePoint for those class instance 
variables
+  // that are embedded in other reply messages.
+  final protected void matchCodePoint (int expectedCodePoint) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int actualCodePoint = 0;
+    actualCodePoint = peekedCodePoint_;
+    pos_ += 4;
+    if (actualCodePoint != expectedCodePoint) {
+      zThrowSyntaxError ("actual code point, " + actualCodePoint +
+                         " does not match expected code point, " + 
expectedCodePoint);
+    }
+  }
+
+
+  protected final int peekNumOfColumns () throws 
org.apache.derby.client.am.DisconnectException
+  {
+    // skip the 4-byte LLCP and any extended length bytes + 1-byte null 
sqlcagrp null indicator
+    int offset = (4 + peekedNumOfExtendedLenBytes_ + 1);
+
+       offset = skipSQLDHROW (offset);
+
+    return SignedBinary.getShort (buffer_, pos_+offset);
+  }
+
+  protected final boolean peekForNullSqlcagrp ()
+  {
+    // skip the 4-byte LLCP and any extended length bytes
+    int offset = (4 + peekedNumOfExtendedLenBytes_);
+    int nullInd = buffer_[pos_+offset] & 0xff;
+    return (nullInd == CodePoint.NULLDATA);
+  }
+
+  private final int skipSQLDHROW (int offset) throws 
org.apache.derby.client.am.DisconnectException
+  {
+    int sqldhrowgrpNullInd = buffer_[pos_+offset++]  & 0xff;
+    if (sqldhrowgrpNullInd == CodePoint.NULLDATA)
+      return offset;
+
+    offset += 12;
+
+    // skip sqldrdbnam
+    int stringLength = ((buffer_[pos_+offset++] & 0xff) << 8) +
+                       ((buffer_[pos_+offset++] & 0xff) << 0);
+    offset += stringLength;
+
+    // skip sqldschema
+    stringLength = ((buffer_[pos_+offset++] & 0xff) << 8) +
+                   ((buffer_[pos_+offset++] & 0xff) << 0);
+    offset += stringLength;
+
+    stringLength = ((buffer_[pos_+offset++] & 0xff) << 8) +
+                   ((buffer_[pos_+offset++] & 0xff) << 0);
+    offset += stringLength;
+
+    return offset;
+  }
+}
+
+
+
+

Propchange: 
incubator/derby/code/trunk/java/client/org/apache/derby/client/net/Reply.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to