EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.client.net]

COVERAGE SUMMARY FOR SOURCE FILE [Reply.java]

nameclass, %method, %block, %line, %
Reply.java100% (1/1)75%  (51/68)55%  (1769/3201)61%  (345.1/569)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Reply100% (1/1)75%  (51/68)55%  (1769/3201)61%  (345.1/569)
Reply (NetAgent, int): void 100% (1/1)100% (50/50)100% (16/16)
adjustCollectionAndDssLengths (int): void 100% (1/1)100% (23/23)100% (4/4)
adjustDdmLength (int, int): int 100% (1/1)100% (12/12)100% (4/4)
adjustLengths (int): void 100% (1/1)100% (10/10)100% (3/3)
compressBLayerData (int): void 100% (1/1)92%  (139/151)89%  (31/35)
decryptData (int, int): void 0%   (0/1)0%   (0/694)0%   (0/97)
doSyntaxrmSemantics (int): void 0%   (0/1)0%   (0/19)0%   (0/2)
endOfSameIdChainData (): void 100% (1/1)73%  (24/33)67%  (6/9)
ensureALayerDataInBuffer (int): int 100% (1/1)100% (19/19)100% (5/5)
ensureBLayerDataInBuffer (int): void 100% (1/1)100% (33/33)100% (7/7)
ensureSpaceInBufferForFill (int): void 100% (1/1)98%  (48/49)100% (10/10)
fill (int): int 100% (1/1)72%  (65/90)69%  (11.7/17)
getData (ByteArrayOutputStream): ByteArrayOutputStream 100% (1/1)94%  (59/63)94%  (17/18)
getDdmLength (): int 100% (1/1)100% (3/3)100% (1/1)
getFastData (ByteArrayOutputStream): ByteArrayOutputStream 100% (1/1)66%  (39/59)71%  (12/17)
getFastSkipSQLCARDrowLength (): int 100% (1/1)100% (6/6)100% (1/1)
initialize (): void 100% (1/1)100% (40/40)100% (12/12)
mark (): void 100% (1/1)100% (5/5)100% (2/2)
matchCodePoint (int): void 100% (1/1)52%  (15/29)83%  (5/6)
parseLengthAndMatchCodePoint (int): void 100% (1/1)80%  (56/70)93%  (14/15)
peekCodePoint (): int 100% (1/1)100% (101/101)100% (16/16)
peekExtendedLength (): void 100% (1/1)90%  (66/73)70%  (7/10)
peekFastBytes (byte [], int, int): int 100% (1/1)100% (23/23)100% (3/3)
peekFastLength (): int 0%   (0/1)0%   (0/22)0%   (0/1)
peekForNullSqlcagrp (): boolean 100% (1/1)91%  (20/22)97%  (2.9/3)
peekLength (): int 0%   (0/1)0%   (0/25)0%   (0/2)
peekNumOfColumns (): int 0%   (0/1)0%   (0/19)0%   (0/3)
peekTotalColumnCount (int): int 100% (1/1)100% (54/54)100% (11/11)
popCollectionStack (): void 100% (1/1)100% (7/7)100% (2/2)
popMark (): int 100% (1/1)100% (3/3)100% (1/1)
pushLengthOnCollectionStack (): void 100% (1/1)100% (16/16)100% (3/3)
readBoolean (): boolean 0%   (0/1)0%   (0/21)0%   (0/3)
readByte (): byte 0%   (0/1)0%   (0/20)0%   (0/3)
readBytes (): byte [] 0%   (0/1)0%   (0/28)0%   (0/7)
readBytes (int): byte [] 100% (1/1)100% (25/25)100% (6/6)
readDSSContinuationHeader (): void 100% (1/1)95%  (62/65)90%  (9/10)
readDssHeader (): void 100% (1/1)84%  (193/229)81%  (31.6/39)
readExtendedLength (): void 0%   (0/1)0%   (0/89)0%   (0/13)
readFastByte (): byte 100% (1/1)100% (14/14)100% (1/1)
readFastBytes (int): byte [] 100% (1/1)100% (19/19)100% (4/4)
readFastInt (): int 100% (1/1)100% (14/14)100% (3/3)
readFastIntArray (int []): void 100% (1/1)100% (23/23)100% (4/4)
readFastLDBytes (): byte [] 100% (1/1)100% (53/53)100% (7/7)
readFastLong (): long 100% (1/1)100% (14/14)100% (3/3)
readFastShort (): short 100% (1/1)100% (14/14)100% (3/3)
readFastString (int): String 100% (1/1)100% (17/17)100% (3/3)
readFastString (int, String): String 100% (1/1)66%  (21/32)71%  (5/7)
readFastUnsignedByte (): int 100% (1/1)100% (13/13)100% (1/1)
readFastUnsignedShort (): int 100% (1/1)100% (30/30)100% (1/1)
readInt (): int 100% (1/1)100% (20/20)100% (5/5)
readIntArray (int []): void 0%   (0/1)0%   (0/35)0%   (0/6)
readLDBytes (): byte [] 0%   (0/1)0%   (0/67)0%   (0/11)
readLengthAndCodePoint (): int 100% (1/1)80%  (90/112)62%  (10/16)
readLong (): long 0%   (0/1)0%   (0/20)0%   (0/5)
readShort (): short 100% (1/1)100% (20/20)100% (5/5)
readString (): String 100% (1/1)100% (26/26)100% (6/6)
readString (int): String 0%   (0/1)0%   (0/23)0%   (0/5)
readString (int, String): String 0%   (0/1)0%   (0/38)0%   (0/9)
readUnsignedByte (): int 100% (1/1)100% (19/19)100% (3/3)
readUnsignedShort (): int 100% (1/1)100% (36/36)100% (3/3)
readUnsignedShortList (): int [] 100% (1/1)100% (57/57)100% (8/8)
shiftBuffer (byte []): void 100% (1/1)100% (24/24)100% (6/6)
skipBytes (): void 100% (1/1)100% (16/16)100% (5/5)
skipBytes (int): void 0%   (0/1)0%   (0/13)0%   (0/4)
skipFastBytes (int): void 100% (1/1)100% (7/7)100% (2/2)
skipSQLDHROW (int): int 0%   (0/1)0%   (0/109)0%   (0/11)
startSameIdChainParse (): void 100% (1/1)100% (6/6)100% (3/3)
zThrowSyntaxError (String): void 0%   (0/1)0%   (0/10)0%   (0/2)

1/*
2 
3   Derby - Class org.apache.derby.client.net.Reply
4 
5   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19*/
20 
21package org.apache.derby.client.net;
22 
23 
24import java.io.ByteArrayOutputStream;
25import java.util.Arrays;
26 
27import org.apache.derby.client.am.SignedBinary;
28import org.apache.derby.client.am.SqlException;
29import org.apache.derby.client.am.DisconnectException;
30import org.apache.derby.client.am.SqlState;
31import org.apache.derby.client.am.ClientMessageId;
32 
33import org.apache.derby.shared.common.reference.SQLState;
34import org.apache.derby.shared.common.reference.MessageId;
35 
36public class Reply {
37    protected org.apache.derby.client.am.Agent agent_;
38    protected NetAgent netAgent_; //cheat-link to (NetAgent) agent_
39 
40    private CcsidManager ccsidManager_;
41    protected final static int DEFAULT_BUFFER_SIZE = 32767;
42    protected byte[] buffer_;
43    protected int pos_;
44    protected int count_;
45 
46    private int topDdmCollectionStack_;
47    private final static int MAX_MARKS_NESTING = 10;
48    private int[] ddmCollectionLenStack_;
49    private int ddmScalarLen_; // a value of -1 -> streamed ddm -> length unknown
50    private final static int EMPTY_STACK = -1;
51 
52    protected boolean ensuredLengthForDecryption_ = false; // A layer lengths have already been ensured in decrypt method.
53    protected byte[] longBufferForDecryption_ = null;
54    protected int longPosForDecryption_ = 0;
55    protected byte[] longValueForDecryption_ = null;
56    protected int longCountForDecryption_ = 0;
57 
58    protected int dssLength_;
59    protected boolean dssIsContinued_;
60    private boolean dssIsChainedWithSameID_;
61    private boolean dssIsChainedWithDiffID_;
62    protected int dssCorrelationID_;
63 
64    protected int peekedLength_ = 0;
65    protected int peekedCodePoint_ = END_OF_COLLECTION;    // saves the peeked codept
66    private int peekedNumOfExtendedLenBytes_ = 0;
67    private int currentPos_ = 0;
68 
69    public final static int END_OF_COLLECTION = -1;
70    public final static int END_OF_SAME_ID_CHAIN = -2;
71 
72    Reply(NetAgent netAgent, int bufferSize) {
73        buffer_ = new byte[bufferSize];
74        agent_ = netAgent_ = netAgent;
75        ccsidManager_ = netAgent.targetCcsidManager_;
76        ddmCollectionLenStack_ = new int[Reply.MAX_MARKS_NESTING];
77        initialize();
78    }
79 
80    final void initialize() {
81        pos_ = 0;
82        count_ = 0;
83        topDdmCollectionStack_ = Reply.EMPTY_STACK;
84        Arrays.fill(ddmCollectionLenStack_, 0);
85        ddmScalarLen_ = 0;
86        dssLength_ = 0;
87        dssIsContinued_ = false;
88        dssIsChainedWithSameID_ = false;
89        dssIsChainedWithDiffID_ = false;
90        dssCorrelationID_ = 1;
91    }
92 
93    final int getDdmLength() {
94        return ddmScalarLen_;
95    }
96 
97    // This is a helper method which shifts the buffered bytes from
98    // wherever they are in the current buffer to the beginning of
99    // different buffer (note these buffers could be the same).
100    // State information is updated as needed after the shift.
101    private final void shiftBuffer(byte[] destinationBuffer) {
102        // calculate the size of the data in the current buffer.
103        int sz = count_ - pos_;
104 
105        // copy this data to the new buffer starting at position 0.
106        System.arraycopy(buffer_, pos_, destinationBuffer, 0, sz);
107 
108        // update the state information for data in the new buffer.
109        pos_ = 0;
110        count_ = sz;
111 
112        // replace the old buffer with the new buffer.
113        buffer_ = destinationBuffer;
114    }
115 
116    // This method makes sure there is enough room in the buffer
117    // for a certain number of bytes.  This method will allocate
118    // a new buffer if needed and shift the bytes in the current buffer
119    // to make ensure space is available for a fill.  Right now
120    // this method will shift bytes as needed to make sure there is
121    // as much room as possible in the buffer before trying to
122    // do the read.  The idea is to try to have space to get as much data as possible
123    // if we need to do a read on the socket's stream.
124    protected final void ensureSpaceInBufferForFill(int desiredSpace) {
125        // calculate the total unused space in the buffer.
126        // this includes any space at the end of the buffer and any free
127        // space at the beginning resulting from bytes already read.
128        int currentAvailableSpace = (buffer_.length - count_) + pos_;
129 
130        // check to see if there is enough free space.
131        if (currentAvailableSpace < desiredSpace) {
132 
133            // there is not enough free space so we need more storage.
134            // we are going to double the buffer unless that happens to still be too small.
135            // if more than double the buffer is needed, use the smallest amount over this as possible.
136            int doubleBufferSize = (2 * buffer_.length);
137 
138            int minumNewBufferSize = (desiredSpace - currentAvailableSpace) + buffer_.length;
139            int newsz = minumNewBufferSize <= doubleBufferSize ? doubleBufferSize : minumNewBufferSize;
140 
141            byte[] newBuffer = new byte[newsz];
142 
143            // shift everything from the old buffer to the new buffer
144            shiftBuffer(newBuffer);
145        } else {
146 
147            // there is enough free space in the buffer but let's make sure it is all at the end.
148            // this is also important because if we are going to do a read, it would be nice
149            // to get as much data as possible and making room at the end if the buffer helps to
150            // ensure this.
151            if (pos_ != 0) {
152                shiftBuffer(buffer_);
153            }
154        }
155    }
156 
157    // This method will attempt to read a minimum number of bytes
158    // from the underlying stream.  This method will keep trying to
159    // read bytes until it has obtained at least the minimum number.
160    // Now returns the total bytes read for decryption, use to return void.
161    protected int fill(int minimumBytesNeeded) throws DisconnectException {
162        // make sure that there is enough space in the buffer to hold
163        // the minimum number of bytes needed.
164        ensureSpaceInBufferForFill(minimumBytesNeeded);
165 
166        // read until the minimum number of bytes needed is now in the buffer.
167        // hopefully the read method will return as many bytes as it can.
168        int totalBytesRead = 0;
169        int actualBytesRead = 0;
170        do {
171            try {
172                // oops, we shouldn't expose the agent's input stream here, collapse this into a read method on the agent
173                actualBytesRead = netAgent_.getInputStream().read(buffer_, count_, buffer_.length - count_);
174            } catch (java.io.IOException ioe) {
175                netAgent_.throwCommunicationsFailure(ioe);
176            } finally {
177                if (agent_.loggingEnabled()) {
178                    ((NetLogWriter) netAgent_.logWriter_).traceProtocolFlow(buffer_,
179                            count_,
180                            actualBytesRead,
181                            NetLogWriter.TYPE_TRACE_RECEIVE,
182                            "Reply",
183                            "fill",
184                            2); // tracepoint
185                }
186            }
187            count_ += actualBytesRead;
188            totalBytesRead += actualBytesRead;
189 
190        } while ((totalBytesRead < minimumBytesNeeded) && (actualBytesRead != -1));
191 
192        if (actualBytesRead == -1) {
193            if (totalBytesRead < minimumBytesNeeded) {
194                netAgent_.accumulateChainBreakingReadExceptionAndThrow(
195                    new DisconnectException(netAgent_,
196                        new ClientMessageId(SQLState.NET_INSUFFICIENT_DATA),
197                        new Integer(minimumBytesNeeded),
198                        new Integer(totalBytesRead)));
199            }
200        }
201        return totalBytesRead;
202    }
203 
204    // Make sure a certain amount of Layer A data is in the buffer.
205    // The data will be in the buffer after this method is called.
206    // Now returns the total bytes read for decryption, use to return void.
207    protected final int ensureALayerDataInBuffer(int desiredDataSize) throws DisconnectException {
208        int totalBytesRead = 0;
209        // calulate the the number of bytes in the buffer.
210        int avail = count_ - pos_;
211 
212        // read more bytes off the network if the data is not in the buffer already.
213        if (avail < desiredDataSize) {
214            totalBytesRead = fill(desiredDataSize - avail);
215        }
216        return totalBytesRead;
217    }
218 
219    protected final void ensureBLayerDataInBuffer(int desiredDataSize) throws DisconnectException {
220        if (dssIsContinued_ && (desiredDataSize > dssLength_)) {
221            int continueDssHeaderCount =
222                    (((desiredDataSize - dssLength_) / 32767) + 1);
223            ensureALayerDataInBuffer(desiredDataSize + (continueDssHeaderCount * 2));
224            compressBLayerData(continueDssHeaderCount);
225            return;
226        }
227        ensureALayerDataInBuffer(desiredDataSize);
228    }
229 
230    // this will probably never be called.
231    // it is included here in the highly unlikely event that a reply object
232    // exceeds 32K.  for opimization purposes, we should consider
233    // removing this.  removing this should be ok since we handle most
234    // big stuff returned from the server (qrydta's for example) by
235    // copying out the data into some other storage.  any extended dss header
236    // info will be removed in the copying process.
237    private final void compressBLayerData(int continueDssHeaderCount) throws DisconnectException {
238        int tempPos = 0;
239 
240        // jump to the last continuation header.
241        for (int i = 0; i < continueDssHeaderCount; i++) {
242            // the first may be less than the size of a full dss
243            if (i == 0) {
244                // only jump by the number of bytes remaining in the current dss
245                tempPos = pos_ + dssLength_;
246            } else {
247                // all other jumps are for a full continued dss
248                tempPos += 32767;
249            }
250        }
251 
252        // for each of the dss headers to remove,
253        // read out the continuation header and increment the dss length by the
254        // size of the conitnation bytes,  then shift the continuation data as needed.
255        int shiftSize = 0;
256        int bytesToShift = 0;
257        int continueHeaderLength = 0;
258        int newDssLength = 0;
259        for (int i = 0; i < continueDssHeaderCount; i++) {
260 
261            continueHeaderLength = ((buffer_[tempPos] & 0xFF) << 8) +
262                    ((buffer_[tempPos + 1] & 0xFF) << 0);
263 
264            if (i == 0) {
265                // if this is the last one (farthest down stream and first to strip out)
266 
267                if ((continueHeaderLength & 0x8000) == 0x8000) {
268                    // the last dss header is again continued
269                    continueHeaderLength = 32767;
270                    dssIsContinued_ = true;
271                } else {
272                    // the last dss header was not contiued so update continue state flag
273                    dssIsContinued_ = false;
274                }
275                // the very first shift size is 2
276                shiftSize = 2;
277            } else {
278                // already removed the last header so make sure the chaining flag is on
279                if ((continueHeaderLength & 0x8000) == 0x8000) {
280                    continueHeaderLength = 32767;
281                } else {
282                    // this is a syntax error but not really certain which one.
283                    // for now pick 0x02 which is Dss header Length does not match the number
284                    // of bytes of data found.
285                    doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_LENGTH_BYTE_NUMBER_MISMATCH);
286                }
287                // increase the shift size by 2
288                shiftSize += 2;
289            }
290 
291            // it is a syntax error if the dss continuation is less than or equal to two
292            if (continueHeaderLength <= 2) {
293                doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2);
294            }
295 
296            newDssLength += (continueHeaderLength - 2);
297 
298            // calculate the number of bytes to shift
299            if (i != (continueDssHeaderCount - 1)) {
300                bytesToShift = 32767;
301            } else {
302                bytesToShift = dssLength_;
303            }
304 
305            tempPos -= (bytesToShift - 2);
306            System.arraycopy(buffer_, tempPos - shiftSize, buffer_, tempPos , bytesToShift);
307        }
308        // reposition the start of the data after the final dss shift.
309        pos_ = tempPos;
310        dssLength_ = dssLength_ + newDssLength;
311    }
312 
313    protected final void readDssHeader() throws DisconnectException {
314        int correlationID = 0;
315        int nextCorrelationID = 0;
316        ensureALayerDataInBuffer(6);
317 
318        // read out the dss length
319        dssLength_ =
320                ((buffer_[pos_++] & 0xFF) << 8) +
321                ((buffer_[pos_++] & 0xFF) << 0);
322 
323        // Remember the old dss length for decryption only.
324        int oldDssLength = dssLength_;
325 
326        // check for the continuation bit and update length as needed.
327        if ((dssLength_ & 0x8000) == 0x8000) {
328            dssLength_ = 32767;
329            dssIsContinued_ = true;
330        } else {
331            dssIsContinued_ = false;
332        }
333 
334        if (dssLength_ < 6) {
335            doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_LESS_THAN_6);
336        }
337 
338        // If the GDS id is not valid, or
339        // if the reply is not an RPYDSS nor
340        // a OBJDSS, then throw an exception.
341        if ((buffer_[pos_++] & 0xFF) != 0xd0) {
342            doSyntaxrmSemantics(CodePoint.SYNERRCD_CBYTE_NOT_D0);
343        }
344 
345        int gdsFormatter = buffer_[pos_++] & 0xFF;
346        if (((gdsFormatter & 0x02) != 0x02)
347                && ((gdsFormatter & 0x03) != 0x03)
348                && ((gdsFormatter & 0x04) != 0x04)) {
349            doSyntaxrmSemantics(CodePoint.SYNERRCD_FBYTE_NOT_SUPPORTED);
350        }
351 
352        // Determine if the current DSS is chained with the
353        // next DSS, with the same or different request ID.
354        if ((gdsFormatter & 0x40) == 0x40) {    // on indicates structure chained to next structure
355            if ((gdsFormatter & 0x10) == 0x10) {
356                dssIsChainedWithSameID_ = true;
357                dssIsChainedWithDiffID_ = false;
358                nextCorrelationID = dssCorrelationID_;
359            } else {
360                dssIsChainedWithSameID_ = false;
361                dssIsChainedWithDiffID_ = true;
362                nextCorrelationID = dssCorrelationID_ + 1;
363            }
364        } else {
365            // chaining bit not b'1', make sure DSSFMT bit3 not b'1'
366            if ((gdsFormatter & 0x10) == 0x10) {  // Next DSS can not have same correlator
367                doSyntaxrmSemantics(CodePoint.SYNERRCD_CHAIN_OFF_SAME_NEXT_CORRELATOR);
368            }
369 
370            // chaining bit not b'1', make sure no error continuation
371            if ((gdsFormatter & 0x20) == 0x20) { // must be 'do not continue on error'
372                doSyntaxrmSemantics(CodePoint.SYNERRCD_CHAIN_OFF_ERROR_CONTINUE);
373            }
374 
375            dssIsChainedWithSameID_ = false;
376            dssIsChainedWithDiffID_ = false;
377            nextCorrelationID = 1;
378        }
379 
380        correlationID =
381                ((buffer_[pos_++] & 0xFF) << 8) +
382                ((buffer_[pos_++] & 0xFF) << 0);
383 
384        // corrid must be the one expected or a -1 which gets returned in some error cases.
385        if ((correlationID != dssCorrelationID_) && (correlationID != 0xFFFF)) {
386            doSyntaxrmSemantics(CodePoint.SYNERRCD_INVALID_CORRELATOR);
387        } else {
388            dssCorrelationID_ = nextCorrelationID;
389        }
390        dssLength_ -= 6;
391        if ((gdsFormatter & 0x04) == 0x04) {
392            decryptData(gdsFormatter, oldDssLength);  //we have to decrypt data here because
393        }
394        //we need the decrypted codepoint. If
395        //Data is very long > 32767, we have to
396        //get all the data first because decrypt
397        //piece by piece doesn't work.
398    }
399 
400 
401    private final void decryptData(int gdsFormatter, int oldDssLength) throws DisconnectException {
402        boolean readHeader;
403 
404        if (dssLength_ == 32761) {
405            ByteArrayOutputStream baos;
406            int copySize = 0;
407 
408            baos = new ByteArrayOutputStream();
409 
410            // set the amount to read for the first segment
411            copySize = dssLength_; // note: has already been adjusted for headers
412 
413            do {
414                // determine if a continuation header needs to be read after the data
415                if (dssIsContinued_) {
416                    readHeader = true;
417                } else {
418                    readHeader = false;
419                }
420 
421                // read the segment
422                ensureALayerDataInBuffer(copySize);
423                adjustLengths(copySize);
424                baos.write(buffer_, pos_, copySize);
425                pos_ += copySize;
426 
427                // read the continuation header, if necessary
428                if (readHeader) {
429                    readDSSContinuationHeader();
430                }
431 
432                copySize = dssLength_;
433            } while (readHeader == true);
434            byte[] cipherBytes = baos.toByteArray();
435            byte[] clearedByte = null;
436            try {
437                clearedByte = netAgent_.netConnection_.getEncryptionManager().decryptData(cipherBytes,
438                        NetConfiguration.SECMEC_EUSRIDPWD,
439                        netAgent_.netConnection_.getTargetPublicKey(),
440                        netAgent_.netConnection_.getTargetPublicKey());
441            } catch (SqlException e) {
442                //throw new SqlException (agent_.logWriter_, "error in decrypting data");
443            }
444 
445            //The decrypted data is for one codepoint only. We need to save the data follows this codepoint
446            longBufferForDecryption_ = new byte[buffer_.length - pos_];
447            longPosForDecryption_ = 0;
448            count_ = count_ - pos_;
449            longCountForDecryption_ = count_;
450            System.arraycopy(buffer_, pos_, longBufferForDecryption_, 0, buffer_.length - pos_);
451 
452            //copy the clear data to buffer_
453            if (clearedByte.length >= 32767) {
454                System.arraycopy(clearedByte, 0, buffer_, 0, 32767);
455            } else {
456                System.arraycopy(clearedByte, 0, buffer_, 0, clearedByte.length);
457            }
458 
459            pos_ = 0;
460            dssLength_ = buffer_.length;
461 
462            int lobLength = 0;
463            if (clearedByte.length > 32767) {  //for extended length, length is the 4 bytes that follow codepoint
464                lobLength = ((clearedByte[4] & 0xFF) << 24) +
465                        ((clearedByte[5] & 0xFF) << 16) +
466                        ((clearedByte[6] & 0xFF) << 8) +
467                        ((clearedByte[7] & 0xFF) << 0);
468                longValueForDecryption_ = new byte[lobLength];
469                System.arraycopy(clearedByte, 8, longValueForDecryption_, 0, clearedByte.length - 8);
470            } else {
471                lobLength = ((clearedByte[0] & 0xFF) << 8) +
472                        ((clearedByte[1] & 0xFF) << 0);
473                longValueForDecryption_ = new byte[lobLength - 4];
474                System.arraycopy(clearedByte, 4, longValueForDecryption_, 0, clearedByte.length - 4);
475            }
476        } else {
477            int bytesRead = ensureALayerDataInBuffer(dssLength_);  //we need to get back all the data here, and then decrypt
478            if (bytesRead > 0) //we ensuredALayerDAtaInBuffer here and set the flag to true, so we don't need do this again later
479            {
480                ensuredLengthForDecryption_ = true;
481            }
482            byte[] encryptedByte = new byte[dssLength_];
483            System.arraycopy(buffer_, pos_, encryptedByte, 0, dssLength_);
484            byte[] array1 = new byte[pos_];
485            System.arraycopy(buffer_, 0, array1, 0, pos_);  //save the data before encrypted data in array1
486            byte[] array3 = new byte[buffer_.length - dssLength_ - pos_];
487            System.arraycopy(buffer_, pos_ + dssLength_, array3, 0, buffer_.length - dssLength_ - pos_); //save the data follows encrypted data in array3
488            byte[] clearedByte = null;
489            try {
490                clearedByte = netAgent_.netConnection_.getEncryptionManager().decryptData(encryptedByte,
491                        NetConfiguration.SECMEC_EUSRIDPWD,
492                        netAgent_.netConnection_.getTargetPublicKey(),
493                        netAgent_.netConnection_.getTargetPublicKey());
494            } catch (SqlException e) {
495                //throw new SqlException (agent_.logWriter_, "error in decrypting data");
496            }
497            dssLength_ -= (encryptedByte.length - clearedByte.length);
498            byte[] buffer = new byte[array1.length + clearedByte.length + array3.length];
499            System.arraycopy(array1, 0, buffer, 0, array1.length);
500            System.arraycopy(clearedByte, 0, buffer, array1.length, clearedByte.length);
501            System.arraycopy(array3, 0, buffer, array1.length + clearedByte.length, array3.length);
502            buffer_ = buffer;
503            int oldCount = count_;
504            count_ = count_ - (encryptedByte.length - clearedByte.length);
505            if (((clearedByte[2] & 0xff) << 8) + ((clearedByte[3] & 0xff) << 0) == 0x146c) {
506                int firstLobLength = ((clearedByte[0] & 0xFF) << 8) +
507                        ((clearedByte[1] & 0xFF) << 0);
508 
509                boolean flag = false;
510                if (gdsFormatter == 0x54) {
511                    flag = true;
512                }
513                if (flag) {
514                    if (oldCount - oldDssLength < 6) {
515                        int totalBytesRead = fill(6); //sometimes the 2nd EXTDTA doesn't come back, need to fetch again to get it
516                        if (totalBytesRead > 0) {
517                            longBufferForDecryption_ = new byte[totalBytesRead];
518                            longPosForDecryption_ = 0;
519                            System.arraycopy(buffer_, pos_ + firstLobLength, longBufferForDecryption_, 0,
520                                    totalBytesRead);
521                        }
522 
523                    } else {
524                        longBufferForDecryption_ = new byte[count_ - pos_ - firstLobLength];
525                        longPosForDecryption_ = 0;
526                        System.arraycopy(buffer_, pos_ + firstLobLength, longBufferForDecryption_, 0,
527                                longBufferForDecryption_.length);
528 
529                    }
530                } //end if(flag)
531                int lobLength = ((clearedByte[0] & 0xFF) << 8) +
532                        ((clearedByte[1] & 0xFF) << 0) - 4;
533 
534                longValueForDecryption_ = new byte[lobLength];
535 
536                System.arraycopy(clearedByte, 4, longValueForDecryption_, 0, clearedByte.length - 4);  //copy the decrypted lob value (excluded length an dcodepoint) to longValue_
537            } else if (((clearedByte[2] & 0xff) << 8) + ((clearedByte[3] & 0xff) << 0) == 0x241B) {
538                int length = ((clearedByte[0] & 0xFF) << 8) +
539                        ((clearedByte[1] & 0xFF) << 0);
540                boolean noData = false;
541                if (clearedByte[4] == -1 && clearedByte[5] == -1) {
542                    noData = true; //there is no data, no need to do the copy
543                }
544                if (!noData) {
545                    if (length == 32776) {
546                        length = ((clearedByte[4] & 0xFF) << 24) +
547                                ((clearedByte[5] & 0xFF) << 16) +
548                                ((clearedByte[6] & 0xFF) << 8) +
549                                ((clearedByte[7] & 0xFF) << 0);
550                        longValueForDecryption_ = new byte[length];
551                        System.arraycopy(clearedByte, 8, longValueForDecryption_, 0,
552                                clearedByte.length - 8);
553                        longCountForDecryption_ = count_ - (pos_ + length + 8);
554                        longBufferForDecryption_ = new byte[buffer_.length - pos_ - length - 8];
555                        System.arraycopy(buffer_, pos_ + length + 8, longBufferForDecryption_, 0,
556                                longBufferForDecryption_.length);
557 
558                    } else {
559                        longPosForDecryption_ = 0;
560                        longCountForDecryption_ = count_ - (pos_ + length);
561                        longBufferForDecryption_ = new byte[buffer_.length - pos_ - length];
562                        System.arraycopy(buffer_, pos_ + length, longBufferForDecryption_, 0,
563                                longBufferForDecryption_.length);
564 
565                        longValueForDecryption_ = new byte[length - 4];
566 
567                        System.arraycopy(clearedByte, 4, longValueForDecryption_, 0,
568                                clearedByte.length - 4);
569                    }
570                }
571            }
572        }
573    }
574 
575 
576    final int readUnsignedShort() throws DisconnectException {
577        // should we be checking dss lengths and ddmScalarLengths here
578        // if yes, i am not sure this is the correct place if we should be checking
579        ensureBLayerDataInBuffer(2);
580        adjustLengths(2);
581        return ((buffer_[pos_++] & 0xff) << 8) +
582                ((buffer_[pos_++] & 0xff) << 0);
583    }
584 
585    final short readShort() throws DisconnectException {
586        // should we be checking dss lengths and ddmScalarLengths here
587        ensureBLayerDataInBuffer(2);
588        adjustLengths(2);
589        short s = SignedBinary.getShort(buffer_, pos_);
590 
591        pos_ += 2;
592 
593        return s;
594    }
595 
596    final int readInt() throws DisconnectException {
597        // should we be checking dss lengths and ddmScalarLengths here
598        ensureBLayerDataInBuffer(4);
599        adjustLengths(4);
600        int i = SignedBinary.getInt(buffer_, pos_);
601        pos_ += 4;
602 
603        return i;
604    }
605 
606    final void readIntArray(int[] array) throws DisconnectException {
607        ensureBLayerDataInBuffer(array.length * 4);
608        adjustLengths(array.length * 4);
609 
610        for (int i = 0; i < array.length; i++) {
611            array[i] = SignedBinary.getInt(buffer_, pos_);
612            pos_ += 4;
613        }
614    }
615 
616 
617    final long readLong() throws DisconnectException {
618        // should we be checking dss lengths and ddmScalarLengths here
619        ensureBLayerDataInBuffer(8);
620        adjustLengths(8);
621        long l = SignedBinary.getLong(buffer_, pos_);
622 
623        pos_ += 8;
624 
625        return l;
626    }
627 
628 
629    final int[] readUnsignedShortList() throws DisconnectException {
630        int len = ddmScalarLen_;
631        ensureBLayerDataInBuffer(len);
632        adjustLengths(len);
633 
634        int count = len / 2;
635        int[] list = new int[count];
636 
637        for (int i = 0; i < count; i++) {
638            list[i] = ((buffer_[pos_++] & 0xff) << 8) +
639                    ((buffer_[pos_++] & 0xff) << 0);
640        }
641 
642        return list;
643    }
644 
645    final int readUnsignedByte() throws DisconnectException {
646        ensureBLayerDataInBuffer(1);
647        adjustLengths(1);
648        return (buffer_[pos_++] & 0xff);
649    }
650 
651    final byte readByte() throws DisconnectException {
652        ensureBLayerDataInBuffer(1);
653        adjustLengths(1);
654        return (byte) (buffer_[pos_++] & 0xff);
655    }
656 
657    final boolean readBoolean() throws DisconnectException {
658        ensureBLayerDataInBuffer(1);
659        adjustLengths(1);
660        return buffer_[pos_++] != 0;
661    }
662 
663    final String readString(int length) throws DisconnectException {
664        ensureBLayerDataInBuffer(length);
665        adjustLengths(length);
666 
667        String result = ccsidManager_.convertToUCS2(buffer_, pos_, length);
668        pos_ += length;
669        return result;
670    }
671 
672    final String readString(int length, String encoding) throws DisconnectException {
673        ensureBLayerDataInBuffer(length);
674        adjustLengths(length);
675        String s = null;
676 
677        try {
678            s = new String(buffer_, pos_, length, encoding);
679        } catch (java.io.UnsupportedEncodingException e) {
680            agent_.accumulateChainBreakingReadExceptionAndThrow(
681                new DisconnectException(agent_,
682                    new ClientMessageId(SQLState.NET_ENCODING_NOT_SUPPORTED), 
683                    e));
684        }
685 
686        pos_ += length;
687        return s;
688    }
689 
690    final String readString() throws DisconnectException {
691        int len = ddmScalarLen_;
692        ensureBLayerDataInBuffer(len);
693        adjustLengths(len);
694        String result = ccsidManager_.convertToUCS2(buffer_, pos_, len);
695        pos_ += len;
696        return result;
697    }
698 
699    final byte[] readBytes(int length) throws DisconnectException {
700        ensureBLayerDataInBuffer(length);
701        adjustLengths(length);
702 
703        byte[] b = new byte[length];
704        System.arraycopy(buffer_, pos_, b, 0, length);
705        pos_ += length;
706        return b;
707    }
708 
709    final byte[] readBytes() throws DisconnectException {
710        int len = ddmScalarLen_;
711        ensureBLayerDataInBuffer(len);
712        adjustLengths(len);
713 
714        byte[] b = new byte[len];
715        System.arraycopy(buffer_, pos_, b, 0, len);
716        pos_ += len;
717        return b;
718    }
719 
720    final byte[] readLDBytes() throws DisconnectException {
721        ensureBLayerDataInBuffer(2);
722        int len = ((buffer_[pos_++] & 0xff) << 8) + ((buffer_[pos_++] & 0xff) << 0);
723 
724        if (len == 0) {
725            adjustLengths(2);
726            return null;
727        }
728 
729        ensureBLayerDataInBuffer(len);
730        adjustLengths(len + 2);
731 
732        byte[] b = new byte[len];
733        System.arraycopy(buffer_, pos_, b, 0, len);
734        pos_ += len;
735        return b;
736    }
737 
738    final void skipBytes(int length) throws DisconnectException {
739        ensureBLayerDataInBuffer(length);
740        adjustLengths(length);
741        pos_ += length;
742    }
743 
744    final void skipBytes() throws DisconnectException {
745        int len = ddmScalarLen_;
746        ensureBLayerDataInBuffer(len);
747        adjustLengths(len);
748        pos_ += len;
749    }
750 
751    // This will be the new and improved getData that handles all QRYDTA/EXTDTA
752    // Returns the stream so that the caller can cache it
753    final ByteArrayOutputStream getData(ByteArrayOutputStream existingBuffer) throws DisconnectException {
754        boolean readHeader;
755        int copySize;
756        ByteArrayOutputStream baos;
757 
758        // note: an empty baos can yield an allocated and empty byte[]
759        if (existingBuffer != null) {
760            baos = existingBuffer;
761        } else {
762            if (ddmScalarLen_ != -1) {
763                // allocate a stream based on a known amount of data
764                baos = new ByteArrayOutputStream(ddmScalarLen_);
765            } else {
766                // allocate a stream to hold an unknown amount of data
767                baos = new ByteArrayOutputStream();
768                //isLengthAndNullabilityUnknown = true;
769            }
770        }
771 
772        // set the amount to read for the first segment
773        copySize = dssLength_; // note: has already been adjusted for headers
774 
775        do {
776            // determine if a continuation header needs to be read after the data
777            if (dssIsContinued_) {
778                readHeader = true;
779            } else {
780                readHeader = false;
781            }
782 
783            // read the segment
784            ensureALayerDataInBuffer(copySize);
785            adjustLengths(copySize);
786            baos.write(buffer_, pos_, copySize);
787            pos_ += copySize;
788 
789            // read the continuation header, if necessary
790            if (readHeader) {
791                readDSSContinuationHeader();
792            }
793 
794            copySize = dssLength_;
795        } while (readHeader == true);
796 
797        return baos;
798    }
799 
800    // reads a DSS continuation header
801    // prereq: pos_ is positioned on the first byte of the two-byte header
802    // post:   dssIsContinued_ is set to true if the continuation bit is on, false otherwise
803    //         dssLength_ is set to DssConstants.MAX_DSS_LEN - 2 (don't count the header for the next read)
804    // helper method for getEXTDTAData
805    protected final void readDSSContinuationHeader() throws DisconnectException {
806        ensureALayerDataInBuffer(2);
807 
808        dssLength_ =
809                ((buffer_[pos_++] & 0xFF) << 8) +
810                ((buffer_[pos_++] & 0xFF) << 0);
811 
812        if ((dssLength_ & 0x8000) == 0x8000) {
813            dssLength_ = DssConstants.MAX_DSS_LEN;
814            dssIsContinued_ = true;
815        } else {
816            dssIsContinued_ = false;
817        }
818        // it is a syntax error if the dss continuation header length
819        // is less than or equal to two
820        if (dssLength_ <= 2) {
821            doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2);
822        }
823 
824        dssLength_ -= 2;  // avoid consuming the DSS cont header
825    }
826 
827 
828    // As part of parsing the reply, the client can detect that the
829    // data sent from the target agent does not structurally
830    // conform to the requirements of the DDM architecture.  These are
831    // the same checks performed by the target server on the messages
832    // it receives from the protocolj code.  Server side detected errors
833    // result in a SYNTAXRM being returned from the AS.  According to the
834    // DDM manual, parsing of the DSS is terminated when the error is
835    // detected.  The Syntax Error Code, SYNERRCD, describes the various errors.
836    //
837    // Note: Not all of these may be valid at the client.  See descriptions for
838    // which ones make sense for client side errors/checks.
839    // Syntax Error Code                  Description of Error
840    // -----------------                  --------------------
841    // 0x01                               Dss header Length is less than 6.
842    // 0x02                               Dss header Length does not match the
843    //                                    number of bytes of data found.
844    // 0x03                               Dss header C-byte not D0.
845    // 0x04                               Dss header f-bytes either not
846    //                                    recognized or not supported.
847    // 0x05                               DSS continuation specified but not found.
848    //                                    For example, DSS continuation is specified
849    //                                    on the last DSS, and the SNA LU 6.2 communication
850    //                                    facility returned the SEND indicator.
851    // 0x06                               DSS chaining specified but no DSS found.
852    //                                    For example, DSS chaining is specified
853    //                                    on the last DSS, and the SNA LU 6.2 communication
854    //                                    facility returned the SEND indicator.
855    // 0x07                               Object length less than four.  For example,
856    //                                    a command parameter's length is specified
857    //                                    as two, or a command's length is specified as three.
858    // 0x08                               Object length does not match the number of bytes of data
859    //                                    found.  For example, a RQSDSS with a length of 150
860    //                                    contains a command whose length is 125 or a SRVDGN parameter
861    //                                    specifies a length of 200 but there are only 50
862    //                                    bytes left in the DSS.
863    // 0x09                               Object length greater than maximum allowed.
864    //                                    For example, a RECCNT parameter specifies a
865    //                                    length of ten, but the parameter is defined
866    //                                    to have a maximum length of eight.
867    // 0x0A                               Object length less than the minimum required.
868    //                                    For example, a SVRCOD parameter specifies a
869    //                                    length of five, but the parameter is defined
870    //                                    to have a fixed length of six.
871    // 0x0B                               Object length not allowed.  For example,
872    //                                    a FILEXDPT parameter is specified with a length of
873    //                                    11, but this would indicate that only half of the hours
874    //                                    field is present instead of the complete hours field.
875    // 0x0C                               Incorrect large object extended length field (see
876    //                                    description of DSS).  For example, an extended
877    //                                    length field is present, but it is only three bytes
878    //                                    long when it is defined to be a multiple of two bytes.
879    // 0x0D                               Object code point index not supported.
880    //                                    For example, a code point of 8032 is encountered
881    //                                    but x'8' is a reserved code point index.
882    // 0x0E                               Required object not found.  For example, a CLEAR
883    //                                    command does not have a filnam parameter present,
884    //                                    or a MODREC command is not followed by a RECORD
885    //                                    command data object.
886    // 0x0F                               Too many command data objects sent.  For example,
887    //                                    a MODREC command is followed by two RECORD command
888    //                                    command data objects, or a DECREC command is followed
889    //                                    by RECORD object.
890    // 0x10                               Mutually exclusive objects present.
891    //                                    For example, a CRTDIRF command specifies both
892    //                                    a DCLNAM and FILNAM parameters.
893    // 0x11                               Too few command data objects sent.
894    //                                    For example, an INSRECEF command that
895    //                                    specified RECCNT95) is followed by only
896    //                                    4 RECORD command data objects.
897    // 0x12                               Duplicate object present.
898    //                                    For example, a LSTFAT command has tow FILNAM
899    //                                    parameters specified.
900    // 0x13                               Invalid request correlator specified.
901    //                                    Use PRCCNVRM with PRCCNVDC of 04 or 05 instead
902    //                                    of this error code.  This error code is being retained
903    //                                    for compatibility with Level 1 of the architecture.
904    // 0x14                               Required value not found.
905    // 0x15                               Reserved value not allowed.  For example,
906    //                                    a INSRECEF command specified a RECCNT(0) parameter.
907    // 0x16                               DSS continuation less than or equal to two.
908    //                                    For example, the length bytes of the DSS continuation
909    //                                    have the value of one.
910    // 0x17                               Objects not in required order.  For example, a RECAL
911    //                                    object contains a RECORD object followed by a RECNBR
912    //                                    object with is not in the defined order.
913    // 0x18                               DSS chaining byt not b'1', but DSSFMT bit3 set to b'1'.
914    // 0x19                               Previous DSS indicated current DSS has the same
915    //                                    request correlator, but the request correlators are
916    //                                    not the same.
917    // 0x1A                               DSS cahining bit not b'1', but error continuation requested.
918    // 0x1B                               Mutually exclusive parameter values not specified.
919    //                                    For example, an OPEN command specified PRPSHD(TRUE)
920    //                                    and FILSHR(READER).
921    // 0x1D                               Code point not valid command.  For example, the first
922    //                                    code point in RQSDSS either is not in the dictionary
923    //                                    or is not a code point for a command.
924    //
925    // When the client detects these errors, it will be handled as if a SYNTAXRM is returned
926    // from the server.  In this SYNTAXRM case, PROTOCOL architects an SQLSTATE of 58008 or 58009.
927    //
928    // Messages
929    // SQLSTATE : 58009
930    //     Execution failed due to a distribution protocol error that caused deallocation of the conversation.
931    //     SQLCODE : -30020
932    //     Execution failed because of a Distributed Protocol
933    //         Error that will affect the successful execution of subsequent
934    //         commands and SQL statements: Reason Code <reason-code>.
935    //      Some possible reason codes include:
936    //      121C Indicates that the user is not authorized to perform the requested command.
937    //      1232 The command could not be completed because of a permanent error.
938    //          In most cases, the server will be in the process of an abend.
939    //      220A The target server has received an invalid data description.
940    //          If a user SQLDA is specified, ensure that the fields are
941    //          initialized correctly. Also, ensure that the length does not
942    //          exceed the maximum allowed length for the data type being used.
943    //
944    //      The command or statement cannot be processed.  The current
945    //          transaction is rolled back and the application is disconnected
946    //          from the remote database.
947    final void doSyntaxrmSemantics(int syntaxErrorCode) throws DisconnectException {
948        agent_.accumulateChainBreakingReadExceptionAndThrow(
949            new DisconnectException(agent_,
950                new ClientMessageId(SQLState.DRDA_CONNECTION_TERMINATED),
951                SqlException.getMessageUtil().getTextMessage(
952                    MessageId.CONN_DRDA_DATASTREAM_SYNTAX_ERROR,
953                    new Integer(syntaxErrorCode))));
954    }
955 
956 
957// the names of these methods start with a letter z.
958// the z will be removed when they are finalized...
959 
960    protected final void pushLengthOnCollectionStack() {
961        ddmCollectionLenStack_[++topDdmCollectionStack_] = ddmScalarLen_;
962        ddmScalarLen_ = 0;
963    }
964 
965    protected final void adjustLengths(int length) {
966        ddmScalarLen_ -= length;
967        adjustCollectionAndDssLengths(length);
968        /*
969        for (int i = 0; i <= topDdmCollectionStack_; i++) {
970          ddmCollectionLenStack_[i] -= length;
971        }
972        dssLength_ -= length;
973        */
974    }
975 
976    protected int adjustDdmLength(int ddmLength, int length) {
977        ddmLength -= length;
978        if (ddmLength == 0) {
979            adjustLengths(getDdmLength());
980        }
981        return ddmLength;
982    }
983 
984    // Pop the collection Length stack.
985    // pre:  The collection length stack must not be empty and the top value
986    //       on the stack must be 0.
987    // post: The top 0 value on the stack will be popped.
988    protected final void popCollectionStack() {
989        topDdmCollectionStack_--;
990    }
991 
992    protected final int peekCodePoint() throws DisconnectException {
993        if (topDdmCollectionStack_ != EMPTY_STACK) {
994            if (ddmCollectionLenStack_[topDdmCollectionStack_] == 0) {
995                return END_OF_COLLECTION;
996            } else if (ddmCollectionLenStack_[topDdmCollectionStack_] < 4) {
997                // error
998            }
999        }
1000 
1001        // if there is no more data in the current dss, and the dss is not
1002        // continued, indicate the end of the same Id chain or read the next dss header.
1003        if ((dssLength_ == 0) && (!dssIsContinued_)) {
1004            if (!dssIsChainedWithSameID_) {
1005                return END_OF_SAME_ID_CHAIN;
1006            }
1007            readDssHeader();
1008        }
1009 
1010        if (longBufferForDecryption_ == null)  //we don't need to do this if it's data stream encryption
1011        {
1012            ensureBLayerDataInBuffer(4);
1013        }
1014        peekedLength_ = ((buffer_[pos_] & 0xff) << 8) + ((buffer_[pos_ + 1] & 0xff) << 0);
1015        peekedCodePoint_ = ((buffer_[pos_ + 2] & 0xff) << 8) + ((buffer_[pos_ + 3] & 0xff) << 0);
1016 
1017        // check for extended length
1018        if ((peekedLength_ & 0x8000) == 0x8000) {
1019            peekExtendedLength();
1020        } else {
1021            peekedNumOfExtendedLenBytes_ = 0;
1022        }
1023        return peekedCodePoint_;
1024    }
1025 
1026    // Read out the 2-byte length without moving the pos_ pointer.
1027    protected final int peekLength() throws DisconnectException {
1028        ensureBLayerDataInBuffer(2);
1029        return (((buffer_[pos_] & 0xff) << 8) +
1030                ((buffer_[pos_ + 1] & 0xff) << 0));
1031    }
1032 
1033    // Read "length" number of bytes from the buffer into the byte array b starting from offset
1034    // "offset".  The current offset in the buffer does not change.
1035    protected final int peekFastBytes(byte[] b, int offset, int length) throws DisconnectException {
1036        for (int i = 0; i < length; i++) {
1037            b[offset + i] = buffer_[pos_ + i];
1038        }
1039        return offset + length;
1040    }
1041 
1042    protected final void parseLengthAndMatchCodePoint(int expectedCodePoint) throws DisconnectException {
1043        int actualCodePoint = 0;
1044        if (peekedCodePoint_ == END_OF_COLLECTION) {
1045            actualCodePoint = readLengthAndCodePoint();
1046        } else {
1047            actualCodePoint = peekedCodePoint_;
1048            pos_ += (4 + peekedNumOfExtendedLenBytes_);
1049            ddmScalarLen_ = peekedLength_;
1050            if (peekedNumOfExtendedLenBytes_ == 0 && ddmScalarLen_ != -1) {
1051                adjustLengths(4);
1052            } else {
1053                adjustCollectionAndDssLengths(4 + peekedNumOfExtendedLenBytes_);
1054            }
1055            peekedLength_ = 0;
1056            peekedCodePoint_ = END_OF_COLLECTION;
1057            peekedNumOfExtendedLenBytes_ = 0;
1058        }
1059 
1060        if (actualCodePoint != expectedCodePoint) {
1061            agent_.accumulateChainBreakingReadExceptionAndThrow(
1062                new DisconnectException(agent_, 
1063                    new ClientMessageId(SQLState.NET_NOT_EXPECTED_CODEPOINT), 
1064                    new Integer(actualCodePoint), 
1065                    new Integer(expectedCodePoint)));
1066        }
1067    }
1068 
1069    protected final int readLengthAndCodePoint() throws DisconnectException {
1070        if (topDdmCollectionStack_ != EMPTY_STACK) {
1071            if (ddmCollectionLenStack_[topDdmCollectionStack_] == 0) {
1072                return END_OF_COLLECTION;
1073            } else if (ddmCollectionLenStack_[topDdmCollectionStack_] < 4) {
1074                agent_.accumulateChainBreakingReadExceptionAndThrow(
1075                    new DisconnectException(agent_, 
1076                    new ClientMessageId(SQLState.NET_DDM_COLLECTION_TOO_SMALL)));
1077            }
1078        }
1079 
1080        // if there is no more data in the current dss, and the dss is not
1081        // continued, indicate the end of the same Id chain or read the next dss header.
1082        if ((dssLength_ == 0) && (!dssIsContinued_)) {
1083            if (!dssIsChainedWithSameID_) {
1084                return END_OF_SAME_ID_CHAIN;
1085            }
1086            readDssHeader();
1087        }
1088 
1089        ensureBLayerDataInBuffer(4);
1090        ddmScalarLen_ =
1091                ((buffer_[pos_++] & 0xff) << 8) +
1092                ((buffer_[pos_++] & 0xff) << 0);
1093        int codePoint = ((buffer_[pos_++] & 0xff) << 8) +
1094                ((buffer_[pos_++] & 0xff) << 0);
1095        adjustLengths(4);
1096 
1097        // check for extended length
1098        if ((ddmScalarLen_ & 0x8000) == 0x8000) {
1099            readExtendedLength();
1100        }
1101        return codePoint;
1102    }
1103 
1104    private final void readExtendedLength() throws DisconnectException {
1105        int numberOfExtendedLenBytes = (ddmScalarLen_ - 0x8000); // fix scroll problem was - 4
1106        int adjustSize = 0;
1107        switch (numberOfExtendedLenBytes) {
1108        case 4:
1109            ensureBLayerDataInBuffer(4);
1110            ddmScalarLen_ =
1111                    ((buffer_[pos_++] & 0xff) << 24) +
1112                    ((buffer_[pos_++] & 0xff) << 16) +
1113                    ((buffer_[pos_++] & 0xff) << 8) +
1114                    ((buffer_[pos_++] & 0xff) << 0);
1115            adjustSize = 4;
1116            break;
1117        case 0:
1118            ddmScalarLen_ = -1;
1119            adjustSize = 0;
1120            break;
1121        default:
1122            doSyntaxrmSemantics(CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN);
1123        }
1124 
1125        adjustCollectionAndDssLengths(adjustSize);
1126        /*
1127        // adjust the lengths here.  this is a special case since the
1128        // extended length bytes do not include their own length.
1129        for (int i = 0; i <= topDdmCollectionStack_; i++) {
1130          ddmCollectionLenStack_[i] -= adjustSize;
1131        }
1132        dssLength_ -= adjustSize;
1133        */
1134    }
1135 
1136    private final void adjustCollectionAndDssLengths(int length) {
1137        // adjust the lengths here.  this is a special case since the
1138        // extended length bytes do not include their own length.
1139        for (int i = 0; i <= topDdmCollectionStack_; i++) {
1140            ddmCollectionLenStack_[i] -= length;
1141        }
1142        dssLength_ -= length;
1143    }
1144 
1145    protected final void startSameIdChainParse() throws DisconnectException {
1146        readDssHeader();
1147        netAgent_.clearSvrcod();
1148    }
1149 
1150    protected final void endOfSameIdChainData() throws DisconnectException {
1151        netAgent_.targetTypdef_ = netAgent_.originalTargetTypdef_;
1152        netAgent_.targetSqlam_ = netAgent_.orignalTargetSqlam_;
1153 
1154        if (this.topDdmCollectionStack_ != Reply.EMPTY_STACK) {
1155            agent_.accumulateChainBreakingReadExceptionAndThrow(
1156                new DisconnectException(agent_, 
1157                new ClientMessageId(SQLState.NET_COLLECTION_STACK_NOT_EMPTY)));
1158        }
1159        if (this.dssLength_ != 0) {
1160            agent_.accumulateChainBreakingReadExceptionAndThrow(
1161                new DisconnectException(agent_, 
1162                new ClientMessageId(SQLState.NET_DSS_NOT_ZERO)));
1163        }
1164        if (dssIsChainedWithSameID_ == true) {
1165            agent_.accumulateChainBreakingReadExceptionAndThrow(
1166                new DisconnectException(agent_, 
1167                new ClientMessageId(SQLState.NET_DSS_CHAINED_WITH_SAME_ID)));
1168        }
1169    }
1170    
1171    protected final int peekTotalColumnCount(int tripletLength) throws DisconnectException {
1172        int columnCount = 0;
1173        int offset = 0;
1174        int tripletType = FdocaConstants.CPT_TRIPLET_TYPE;
1175        while (tripletType == FdocaConstants.CPT_TRIPLET_TYPE) {
1176            columnCount += ((tripletLength - 3) / 3);
1177            // Peek ahead for the next triplet's tripletLength and tripletType.
1178            // The number of bytes to skip before the next tripletType is tripletLength - 3.
1179            ensureBLayerDataInBuffer(tripletLength - 3);
1180            offset += (tripletLength - 3);
1181            tripletLength = (buffer_[pos_ + offset++] & 0xff);
1182            tripletType = (buffer_[pos_ + offset++] & 0xff);
1183            // Skip the 1-byte tripletId.
1184            offset++;
1185        }
1186        return columnCount;
1187    }
1188 
1189    private final void peekExtendedLength() throws DisconnectException {
1190        peekedNumOfExtendedLenBytes_ = (peekedLength_ - 0x8004);
1191        switch (peekedNumOfExtendedLenBytes_) {
1192        case 4:
1193            // L   L   C   P  Extended Length
1194            // -->2-bytes<--  --->4-bytes<---
1195            // We are only peeking the length here, the actual pos_ is still before LLCP.  We ensured
1196            // 4-bytes in peedCodePoint() for the LLCP, and we need to ensure 4-bytes(of LLCP) + the
1197            // extended length bytes here.
1198            if (longBufferForDecryption_ == null) //we ddon't need to do this if it's data stream encryption
1199            {
1200                ensureBLayerDataInBuffer(4 + 4);
1201            }
1202            // The ddmScalarLen_ we peek here does not include the LLCP and the extended length bytes
1203            // themselves.  So we will add those back to the ddmScalarLen_ so it can be adjusted
1204            // correctly in parseLengthAndMatchCodePoint(). (since the adjustLengths() method will
1205            // subtract the length from ddmScalarLen_)
1206            peekedLength_ =
1207                    ((buffer_[pos_ + 4] & 0xff) << 24) +
1208                    ((buffer_[pos_ + 5] & 0xff) << 16) +
1209                    ((buffer_[pos_ + 6] & 0xff) << 8) +
1210                    ((buffer_[pos_ + 7] & 0xff) << 0);
1211            break;
1212        case 0:
1213            peekedLength_ = -1; // this ddm is streamed, so set -1 -> length unknown
1214            break;
1215        default:
1216            doSyntaxrmSemantics(CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN);
1217        }
1218    }
1219 
1220    final int readFastUnsignedByte() throws DisconnectException {
1221        return (buffer_[pos_++] & 0xff);
1222    }
1223 
1224    final short readFastShort() throws DisconnectException {
1225        short s = SignedBinary.getShort(buffer_, pos_);
1226        pos_ += 2;
1227        return s;
1228    }
1229 
1230    final int readFastUnsignedShort() throws DisconnectException {
1231        return ((buffer_[pos_++] & 0xff) << 8) +
1232                ((buffer_[pos_++] & 0xff) << 0);
1233    }
1234 
1235    final int readFastInt() throws DisconnectException {
1236        int i = SignedBinary.getInt(buffer_, pos_);
1237        pos_ += 4;
1238        return i;
1239    }
1240 
1241    final String readFastString(int length) throws DisconnectException {
1242        String result = ccsidManager_.convertToUCS2(buffer_, pos_, length);
1243        pos_ += length;
1244        return result;
1245    }
1246 
1247    final byte[] readFastBytes(int length) throws DisconnectException {
1248        byte[] b = new byte[length];
1249        System.arraycopy(buffer_, pos_, b, 0, length);
1250        pos_ += length;
1251        return b;
1252    }
1253 
1254    protected final int peekFastLength() throws DisconnectException {
1255        return (((buffer_[pos_] & 0xff) << 8) +
1256                ((buffer_[pos_ + 1] & 0xff) << 0));
1257    }
1258 
1259    final void skipFastBytes(int length) throws DisconnectException {
1260        pos_ += length;
1261    }
1262 
1263    final void readFastIntArray(int[] array) throws DisconnectException {
1264        for (int i = 0; i < array.length; i++) {
1265            array[i] = SignedBinary.getInt(buffer_, pos_);
1266            pos_ += 4;
1267        }
1268    }
1269 
1270    final String readFastString(int length, String encoding) throws DisconnectException {
1271        String s = null;
1272 
1273        try {
1274            s = new String(buffer_, pos_, length, encoding);
1275        } catch (java.io.UnsupportedEncodingException e) {
1276            agent_.accumulateChainBreakingReadExceptionAndThrow(
1277                new DisconnectException(agent_,
1278                    new ClientMessageId(SQLState.NET_ENCODING_NOT_SUPPORTED),
1279                    e));
1280        }
1281        pos_ += length;
1282        return s;
1283    }
1284 
1285    final byte[] readFastLDBytes() throws DisconnectException {
1286        int len = ((buffer_[pos_++] & 0xff) << 8) + ((buffer_[pos_++] & 0xff) << 0);
1287        if (len == 0) {
1288            return null;
1289        }
1290 
1291        byte[] b = new byte[len];
1292        System.arraycopy(buffer_, pos_, b, 0, len);
1293        pos_ += len;
1294        return b;
1295    }
1296 
1297    final long readFastLong() throws DisconnectException {
1298        long l = SignedBinary.getLong(buffer_, pos_);
1299        pos_ += 8;
1300        return l;
1301    }
1302 
1303    final byte readFastByte() throws DisconnectException {
1304        return (byte) (buffer_[pos_++] & 0xff);
1305    }
1306 
1307    final void mark() {
1308        currentPos_ = pos_;
1309    }
1310 
1311    // remove and return the top offset value from mark stack.
1312    final int popMark() {
1313        return currentPos_;
1314    }
1315 
1316    final int getFastSkipSQLCARDrowLength() {
1317        return pos_ - popMark();
1318    }
1319 
1320    // The only difference between this method and the original getData() method is this method
1321    // is not doing an ensureALayerDataInBuffer
1322    final ByteArrayOutputStream getFastData(ByteArrayOutputStream existingBuffer) throws DisconnectException {
1323        boolean readHeader;
1324        int copySize;
1325        ByteArrayOutputStream baos;
1326 
1327        // note: an empty baos can yield an allocated and empty byte[]
1328        if (existingBuffer != null) {
1329            baos = existingBuffer;
1330        } else {
1331            if (ddmScalarLen_ != -1) {
1332                // allocate a stream based on a known amount of data
1333                baos = new ByteArrayOutputStream(ddmScalarLen_);
1334            } else {
1335                // allocate a stream to hold an unknown amount of data
1336                baos = new ByteArrayOutputStream();
1337                //isLengthAndNullabilityUnknown = true;
1338            }
1339        }
1340 
1341        // set the amount to read for the first segment
1342        copySize = dssLength_; // note: has already been adjusted for headers
1343 
1344        do {
1345            // determine if a continuation header needs to be read after the data
1346            if (dssIsContinued_) {
1347                readHeader = true;
1348            } else {
1349                readHeader = false;
1350            }
1351 
1352            // read the segment
1353            //ensureALayerDataInBuffer (copySize);
1354            adjustLengths(copySize);
1355            baos.write(buffer_, pos_, copySize);
1356            pos_ += copySize;
1357 
1358            // read the continuation header, if necessary
1359            if (readHeader) {
1360                readDSSContinuationHeader();
1361            }
1362 
1363            copySize = dssLength_;
1364        } while (readHeader == true);
1365 
1366        return baos;
1367    }
1368 
1369    // This method is only used to match the codePoint for those class instance variables
1370    // that are embedded in other reply messages.
1371    final protected void matchCodePoint(int expectedCodePoint) throws DisconnectException {
1372        int actualCodePoint = 0;
1373        actualCodePoint = peekedCodePoint_;
1374        pos_ += 4;
1375        if (actualCodePoint != expectedCodePoint) {
1376            agent_.accumulateChainBreakingReadExceptionAndThrow(
1377                new DisconnectException(agent_, 
1378                    new ClientMessageId(SQLState.NET_NOT_EXPECTED_CODEPOINT), 
1379                    new Integer(actualCodePoint), 
1380                    new Integer(expectedCodePoint)));
1381        }
1382    }
1383 
1384 
1385    protected final int peekNumOfColumns() throws DisconnectException {
1386        // skip the 4-byte LLCP and any extended length bytes + 1-byte null sqlcagrp null indicator
1387        int offset = (4 + peekedNumOfExtendedLenBytes_ + 1);
1388 
1389        offset = skipSQLDHROW(offset);
1390 
1391        return SignedBinary.getShort(buffer_, pos_ + offset);
1392    }
1393 
1394    protected final boolean peekForNullSqlcagrp() {
1395        // skip the 4-byte LLCP and any extended length bytes
1396        int offset = (4 + peekedNumOfExtendedLenBytes_);
1397        int nullInd = buffer_[pos_ + offset] & 0xff;
1398        return (nullInd == CodePoint.NULLDATA);
1399    }
1400 
1401    private final int skipSQLDHROW(int offset) throws DisconnectException {
1402        int sqldhrowgrpNullInd = buffer_[pos_ + offset++] & 0xff;
1403        if (sqldhrowgrpNullInd == CodePoint.NULLDATA) {
1404            return offset;
1405        }
1406 
1407        offset += 12;
1408 
1409        // skip sqldrdbnam
1410        int stringLength = ((buffer_[pos_ + offset++] & 0xff) << 8) +
1411                ((buffer_[pos_ + offset++] & 0xff) << 0);
1412        offset += stringLength;
1413 
1414        // skip sqldschema
1415        stringLength = ((buffer_[pos_ + offset++] & 0xff) << 8) +
1416                ((buffer_[pos_ + offset++] & 0xff) << 0);
1417        offset += stringLength;
1418 
1419        stringLength = ((buffer_[pos_ + offset++] & 0xff) << 8) +
1420                ((buffer_[pos_ + offset++] & 0xff) << 0);
1421        offset += stringLength;
1422 
1423        return offset;
1424    }
1425}
1426 
1427 
1428 
1429 

[all classes][org.apache.derby.client.net]
EMMA 2.0.5312 (C) Vladimir Roubtsov