Source Code Cross Referenced for Reply.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » client » net » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.client.net 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.client.net.Reply
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to You under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.client.net;
0023:
0024:        import java.io.ByteArrayOutputStream;
0025:        import java.util.Arrays;
0026:
0027:        import org.apache.derby.client.am.SignedBinary;
0028:        import org.apache.derby.client.am.SqlException;
0029:        import org.apache.derby.client.am.DisconnectException;
0030:        import org.apache.derby.client.am.SqlState;
0031:        import org.apache.derby.client.am.ClientMessageId;
0032:
0033:        import org.apache.derby.shared.common.reference.SQLState;
0034:        import org.apache.derby.shared.common.reference.MessageId;
0035:
0036:        public class Reply {
0037:            protected org.apache.derby.client.am.Agent agent_;
0038:            protected NetAgent netAgent_; //cheat-link to (NetAgent) agent_
0039:
0040:            private CcsidManager ccsidManager_;
0041:            protected final static int DEFAULT_BUFFER_SIZE = 32767;
0042:            protected byte[] buffer_;
0043:            protected int pos_;
0044:            protected int count_;
0045:
0046:            private int topDdmCollectionStack_;
0047:            private final static int MAX_MARKS_NESTING = 10;
0048:            private int[] ddmCollectionLenStack_;
0049:            private int ddmScalarLen_; // a value of -1 -> streamed ddm -> length unknown
0050:            private final static int EMPTY_STACK = -1;
0051:
0052:            protected boolean ensuredLengthForDecryption_ = false; // A layer lengths have already been ensured in decrypt method.
0053:            protected byte[] longBufferForDecryption_ = null;
0054:            protected int longPosForDecryption_ = 0;
0055:            protected byte[] longValueForDecryption_ = null;
0056:            protected int longCountForDecryption_ = 0;
0057:
0058:            protected int dssLength_;
0059:            protected boolean dssIsContinued_;
0060:            private boolean dssIsChainedWithSameID_;
0061:            private boolean dssIsChainedWithDiffID_;
0062:            protected int dssCorrelationID_;
0063:
0064:            protected int peekedLength_ = 0;
0065:            protected int peekedCodePoint_ = END_OF_COLLECTION; // saves the peeked codept
0066:            private int peekedNumOfExtendedLenBytes_ = 0;
0067:            private int currentPos_ = 0;
0068:
0069:            public final static int END_OF_COLLECTION = -1;
0070:            public final static int END_OF_SAME_ID_CHAIN = -2;
0071:
0072:            Reply(NetAgent netAgent, int bufferSize) {
0073:                buffer_ = new byte[bufferSize];
0074:                agent_ = netAgent_ = netAgent;
0075:                ccsidManager_ = netAgent.targetCcsidManager_;
0076:                ddmCollectionLenStack_ = new int[Reply.MAX_MARKS_NESTING];
0077:                initialize();
0078:            }
0079:
0080:            final void initialize() {
0081:                pos_ = 0;
0082:                count_ = 0;
0083:                topDdmCollectionStack_ = Reply.EMPTY_STACK;
0084:                Arrays.fill(ddmCollectionLenStack_, 0);
0085:                ddmScalarLen_ = 0;
0086:                dssLength_ = 0;
0087:                dssIsContinued_ = false;
0088:                dssIsChainedWithSameID_ = false;
0089:                dssIsChainedWithDiffID_ = false;
0090:                dssCorrelationID_ = 1;
0091:            }
0092:
0093:            final int getDdmLength() {
0094:                return ddmScalarLen_;
0095:            }
0096:
0097:            // This is a helper method which shifts the buffered bytes from
0098:            // wherever they are in the current buffer to the beginning of
0099:            // different buffer (note these buffers could be the same).
0100:            // State information is updated as needed after the shift.
0101:            private final void shiftBuffer(byte[] destinationBuffer) {
0102:                // calculate the size of the data in the current buffer.
0103:                int sz = count_ - pos_;
0104:
0105:                // copy this data to the new buffer starting at position 0.
0106:                System.arraycopy(buffer_, pos_, destinationBuffer, 0, sz);
0107:
0108:                // update the state information for data in the new buffer.
0109:                pos_ = 0;
0110:                count_ = sz;
0111:
0112:                // replace the old buffer with the new buffer.
0113:                buffer_ = destinationBuffer;
0114:            }
0115:
0116:            // This method makes sure there is enough room in the buffer
0117:            // for a certain number of bytes.  This method will allocate
0118:            // a new buffer if needed and shift the bytes in the current buffer
0119:            // to make ensure space is available for a fill.  Right now
0120:            // this method will shift bytes as needed to make sure there is
0121:            // as much room as possible in the buffer before trying to
0122:            // do the read.  The idea is to try to have space to get as much data as possible
0123:            // if we need to do a read on the socket's stream.
0124:            protected final void ensureSpaceInBufferForFill(int desiredSpace) {
0125:                // calculate the total unused space in the buffer.
0126:                // this includes any space at the end of the buffer and any free
0127:                // space at the beginning resulting from bytes already read.
0128:                int currentAvailableSpace = (buffer_.length - count_) + pos_;
0129:
0130:                // check to see if there is enough free space.
0131:                if (currentAvailableSpace < desiredSpace) {
0132:
0133:                    // there is not enough free space so we need more storage.
0134:                    // we are going to double the buffer unless that happens to still be too small.
0135:                    // if more than double the buffer is needed, use the smallest amount over this as possible.
0136:                    int doubleBufferSize = (2 * buffer_.length);
0137:
0138:                    int minumNewBufferSize = (desiredSpace - currentAvailableSpace)
0139:                            + buffer_.length;
0140:                    int newsz = minumNewBufferSize <= doubleBufferSize ? doubleBufferSize
0141:                            : minumNewBufferSize;
0142:
0143:                    byte[] newBuffer = new byte[newsz];
0144:
0145:                    // shift everything from the old buffer to the new buffer
0146:                    shiftBuffer(newBuffer);
0147:                } else {
0148:
0149:                    // there is enough free space in the buffer but let's make sure it is all at the end.
0150:                    // this is also important because if we are going to do a read, it would be nice
0151:                    // to get as much data as possible and making room at the end if the buffer helps to
0152:                    // ensure this.
0153:                    if (pos_ != 0) {
0154:                        shiftBuffer(buffer_);
0155:                    }
0156:                }
0157:            }
0158:
0159:            // This method will attempt to read a minimum number of bytes
0160:            // from the underlying stream.  This method will keep trying to
0161:            // read bytes until it has obtained at least the minimum number.
0162:            // Now returns the total bytes read for decryption, use to return void.
0163:            protected int fill(int minimumBytesNeeded)
0164:                    throws DisconnectException {
0165:                // make sure that there is enough space in the buffer to hold
0166:                // the minimum number of bytes needed.
0167:                ensureSpaceInBufferForFill(minimumBytesNeeded);
0168:
0169:                // read until the minimum number of bytes needed is now in the buffer.
0170:                // hopefully the read method will return as many bytes as it can.
0171:                int totalBytesRead = 0;
0172:                int actualBytesRead = 0;
0173:                do {
0174:                    try {
0175:                        // oops, we shouldn't expose the agent's input stream here, collapse this into a read method on the agent
0176:                        actualBytesRead = netAgent_.getInputStream().read(
0177:                                buffer_, count_, buffer_.length - count_);
0178:                    } catch (java.io.IOException ioe) {
0179:                        netAgent_.throwCommunicationsFailure(ioe);
0180:                    } finally {
0181:                        if (agent_.loggingEnabled()) {
0182:                            ((NetLogWriter) netAgent_.logWriter_)
0183:                                    .traceProtocolFlow(buffer_, count_,
0184:                                            actualBytesRead,
0185:                                            NetLogWriter.TYPE_TRACE_RECEIVE,
0186:                                            "Reply", "fill", 2); // tracepoint
0187:                        }
0188:                    }
0189:                    count_ += actualBytesRead;
0190:                    totalBytesRead += actualBytesRead;
0191:
0192:                } while ((totalBytesRead < minimumBytesNeeded)
0193:                        && (actualBytesRead != -1));
0194:
0195:                if (actualBytesRead == -1) {
0196:                    if (totalBytesRead < minimumBytesNeeded) {
0197:                        netAgent_
0198:                                .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
0199:                                        netAgent_,
0200:                                        new ClientMessageId(
0201:                                                SQLState.NET_INSUFFICIENT_DATA),
0202:                                        new Integer(minimumBytesNeeded),
0203:                                        new Integer(totalBytesRead)));
0204:                    }
0205:                }
0206:                return totalBytesRead;
0207:            }
0208:
0209:            // Make sure a certain amount of Layer A data is in the buffer.
0210:            // The data will be in the buffer after this method is called.
0211:            // Now returns the total bytes read for decryption, use to return void.
0212:            protected final int ensureALayerDataInBuffer(int desiredDataSize)
0213:                    throws DisconnectException {
0214:                int totalBytesRead = 0;
0215:                // calulate the the number of bytes in the buffer.
0216:                int avail = count_ - pos_;
0217:
0218:                // read more bytes off the network if the data is not in the buffer already.
0219:                if (avail < desiredDataSize) {
0220:                    totalBytesRead = fill(desiredDataSize - avail);
0221:                }
0222:                return totalBytesRead;
0223:            }
0224:
0225:            protected final void ensureBLayerDataInBuffer(int desiredDataSize)
0226:                    throws DisconnectException {
0227:                if (dssIsContinued_ && (desiredDataSize > dssLength_)) {
0228:                    int continueDssHeaderCount = (((desiredDataSize - dssLength_) / 32767) + 1);
0229:                    ensureALayerDataInBuffer(desiredDataSize
0230:                            + (continueDssHeaderCount * 2));
0231:                    compressBLayerData(continueDssHeaderCount);
0232:                    return;
0233:                }
0234:                ensureALayerDataInBuffer(desiredDataSize);
0235:            }
0236:
0237:            // this will probably never be called.
0238:            // it is included here in the highly unlikely event that a reply object
0239:            // exceeds 32K.  for opimization purposes, we should consider
0240:            // removing this.  removing this should be ok since we handle most
0241:            // big stuff returned from the server (qrydta's for example) by
0242:            // copying out the data into some other storage.  any extended dss header
0243:            // info will be removed in the copying process.
0244:            private final void compressBLayerData(int continueDssHeaderCount)
0245:                    throws DisconnectException {
0246:                int tempPos = 0;
0247:
0248:                // jump to the last continuation header.
0249:                for (int i = 0; i < continueDssHeaderCount; i++) {
0250:                    // the first may be less than the size of a full dss
0251:                    if (i == 0) {
0252:                        // only jump by the number of bytes remaining in the current dss
0253:                        tempPos = pos_ + dssLength_;
0254:                    } else {
0255:                        // all other jumps are for a full continued dss
0256:                        tempPos += 32767;
0257:                    }
0258:                }
0259:
0260:                // for each of the dss headers to remove,
0261:                // read out the continuation header and increment the dss length by the
0262:                // size of the conitnation bytes,  then shift the continuation data as needed.
0263:                int shiftSize = 0;
0264:                int bytesToShift = 0;
0265:                int continueHeaderLength = 0;
0266:                int newDssLength = 0;
0267:                for (int i = 0; i < continueDssHeaderCount; i++) {
0268:
0269:                    continueHeaderLength = ((buffer_[tempPos] & 0xFF) << 8)
0270:                            + ((buffer_[tempPos + 1] & 0xFF) << 0);
0271:
0272:                    if (i == 0) {
0273:                        // if this is the last one (farthest down stream and first to strip out)
0274:
0275:                        if ((continueHeaderLength & 0x8000) == 0x8000) {
0276:                            // the last dss header is again continued
0277:                            continueHeaderLength = 32767;
0278:                            dssIsContinued_ = true;
0279:                        } else {
0280:                            // the last dss header was not contiued so update continue state flag
0281:                            dssIsContinued_ = false;
0282:                        }
0283:                        // the very first shift size is 2
0284:                        shiftSize = 2;
0285:                    } else {
0286:                        // already removed the last header so make sure the chaining flag is on
0287:                        if ((continueHeaderLength & 0x8000) == 0x8000) {
0288:                            continueHeaderLength = 32767;
0289:                        } else {
0290:                            // this is a syntax error but not really certain which one.
0291:                            // for now pick 0x02 which is Dss header Length does not match the number
0292:                            // of bytes of data found.
0293:                            doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_LENGTH_BYTE_NUMBER_MISMATCH);
0294:                        }
0295:                        // increase the shift size by 2
0296:                        shiftSize += 2;
0297:                    }
0298:
0299:                    // it is a syntax error if the dss continuation is less than or equal to two
0300:                    if (continueHeaderLength <= 2) {
0301:                        doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2);
0302:                    }
0303:
0304:                    newDssLength += (continueHeaderLength - 2);
0305:
0306:                    // calculate the number of bytes to shift
0307:                    if (i != (continueDssHeaderCount - 1)) {
0308:                        bytesToShift = 32767;
0309:                    } else {
0310:                        bytesToShift = dssLength_;
0311:                    }
0312:
0313:                    tempPos -= (bytesToShift - 2);
0314:                    System.arraycopy(buffer_, tempPos - shiftSize, buffer_,
0315:                            tempPos, bytesToShift);
0316:                }
0317:                // reposition the start of the data after the final dss shift.
0318:                pos_ = tempPos;
0319:                dssLength_ = dssLength_ + newDssLength;
0320:            }
0321:
0322:            protected final void readDssHeader() throws DisconnectException {
0323:                int correlationID = 0;
0324:                int nextCorrelationID = 0;
0325:                ensureALayerDataInBuffer(6);
0326:
0327:                // read out the dss length
0328:                dssLength_ = ((buffer_[pos_++] & 0xFF) << 8)
0329:                        + ((buffer_[pos_++] & 0xFF) << 0);
0330:
0331:                // Remember the old dss length for decryption only.
0332:                int oldDssLength = dssLength_;
0333:
0334:                // check for the continuation bit and update length as needed.
0335:                if ((dssLength_ & 0x8000) == 0x8000) {
0336:                    dssLength_ = 32767;
0337:                    dssIsContinued_ = true;
0338:                } else {
0339:                    dssIsContinued_ = false;
0340:                }
0341:
0342:                if (dssLength_ < 6) {
0343:                    doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_LESS_THAN_6);
0344:                }
0345:
0346:                // If the GDS id is not valid, or
0347:                // if the reply is not an RPYDSS nor
0348:                // a OBJDSS, then throw an exception.
0349:                if ((buffer_[pos_++] & 0xFF) != 0xd0) {
0350:                    doSyntaxrmSemantics(CodePoint.SYNERRCD_CBYTE_NOT_D0);
0351:                }
0352:
0353:                int gdsFormatter = buffer_[pos_++] & 0xFF;
0354:                if (((gdsFormatter & 0x02) != 0x02)
0355:                        && ((gdsFormatter & 0x03) != 0x03)
0356:                        && ((gdsFormatter & 0x04) != 0x04)) {
0357:                    doSyntaxrmSemantics(CodePoint.SYNERRCD_FBYTE_NOT_SUPPORTED);
0358:                }
0359:
0360:                // Determine if the current DSS is chained with the
0361:                // next DSS, with the same or different request ID.
0362:                if ((gdsFormatter & 0x40) == 0x40) { // on indicates structure chained to next structure
0363:                    if ((gdsFormatter & 0x10) == 0x10) {
0364:                        dssIsChainedWithSameID_ = true;
0365:                        dssIsChainedWithDiffID_ = false;
0366:                        nextCorrelationID = dssCorrelationID_;
0367:                    } else {
0368:                        dssIsChainedWithSameID_ = false;
0369:                        dssIsChainedWithDiffID_ = true;
0370:                        nextCorrelationID = dssCorrelationID_ + 1;
0371:                    }
0372:                } else {
0373:                    // chaining bit not b'1', make sure DSSFMT bit3 not b'1'
0374:                    if ((gdsFormatter & 0x10) == 0x10) { // Next DSS can not have same correlator
0375:                        doSyntaxrmSemantics(CodePoint.SYNERRCD_CHAIN_OFF_SAME_NEXT_CORRELATOR);
0376:                    }
0377:
0378:                    // chaining bit not b'1', make sure no error continuation
0379:                    if ((gdsFormatter & 0x20) == 0x20) { // must be 'do not continue on error'
0380:                        doSyntaxrmSemantics(CodePoint.SYNERRCD_CHAIN_OFF_ERROR_CONTINUE);
0381:                    }
0382:
0383:                    dssIsChainedWithSameID_ = false;
0384:                    dssIsChainedWithDiffID_ = false;
0385:                    nextCorrelationID = 1;
0386:                }
0387:
0388:                correlationID = ((buffer_[pos_++] & 0xFF) << 8)
0389:                        + ((buffer_[pos_++] & 0xFF) << 0);
0390:
0391:                // corrid must be the one expected or a -1 which gets returned in some error cases.
0392:                if ((correlationID != dssCorrelationID_)
0393:                        && (correlationID != 0xFFFF)) {
0394:                    doSyntaxrmSemantics(CodePoint.SYNERRCD_INVALID_CORRELATOR);
0395:                } else {
0396:                    dssCorrelationID_ = nextCorrelationID;
0397:                }
0398:                dssLength_ -= 6;
0399:                if ((gdsFormatter & 0x04) == 0x04) {
0400:                    decryptData(gdsFormatter, oldDssLength); //we have to decrypt data here because
0401:                }
0402:                //we need the decrypted codepoint. If
0403:                //Data is very long > 32767, we have to
0404:                //get all the data first because decrypt
0405:                //piece by piece doesn't work.
0406:            }
0407:
0408:            private final void decryptData(int gdsFormatter, int oldDssLength)
0409:                    throws DisconnectException {
0410:                boolean readHeader;
0411:
0412:                if (dssLength_ == 32761) {
0413:                    ByteArrayOutputStream baos;
0414:                    int copySize = 0;
0415:
0416:                    baos = new ByteArrayOutputStream();
0417:
0418:                    // set the amount to read for the first segment
0419:                    copySize = dssLength_; // note: has already been adjusted for headers
0420:
0421:                    do {
0422:                        // determine if a continuation header needs to be read after the data
0423:                        if (dssIsContinued_) {
0424:                            readHeader = true;
0425:                        } else {
0426:                            readHeader = false;
0427:                        }
0428:
0429:                        // read the segment
0430:                        ensureALayerDataInBuffer(copySize);
0431:                        adjustLengths(copySize);
0432:                        baos.write(buffer_, pos_, copySize);
0433:                        pos_ += copySize;
0434:
0435:                        // read the continuation header, if necessary
0436:                        if (readHeader) {
0437:                            readDSSContinuationHeader();
0438:                        }
0439:
0440:                        copySize = dssLength_;
0441:                    } while (readHeader == true);
0442:                    byte[] cipherBytes = baos.toByteArray();
0443:                    byte[] clearedByte = null;
0444:                    try {
0445:                        clearedByte = netAgent_.netConnection_
0446:                                .getEncryptionManager().decryptData(
0447:                                        cipherBytes,
0448:                                        NetConfiguration.SECMEC_EUSRIDPWD,
0449:                                        netAgent_.netConnection_
0450:                                                .getTargetPublicKey(),
0451:                                        netAgent_.netConnection_
0452:                                                .getTargetPublicKey());
0453:                    } catch (SqlException e) {
0454:                        //throw new SqlException (agent_.logWriter_, "error in decrypting data");
0455:                    }
0456:
0457:                    //The decrypted data is for one codepoint only. We need to save the data follows this codepoint
0458:                    longBufferForDecryption_ = new byte[buffer_.length - pos_];
0459:                    longPosForDecryption_ = 0;
0460:                    count_ = count_ - pos_;
0461:                    longCountForDecryption_ = count_;
0462:                    System.arraycopy(buffer_, pos_, longBufferForDecryption_,
0463:                            0, buffer_.length - pos_);
0464:
0465:                    //copy the clear data to buffer_
0466:                    if (clearedByte.length >= 32767) {
0467:                        System.arraycopy(clearedByte, 0, buffer_, 0, 32767);
0468:                    } else {
0469:                        System.arraycopy(clearedByte, 0, buffer_, 0,
0470:                                clearedByte.length);
0471:                    }
0472:
0473:                    pos_ = 0;
0474:                    dssLength_ = buffer_.length;
0475:
0476:                    int lobLength = 0;
0477:                    if (clearedByte.length > 32767) { //for extended length, length is the 4 bytes that follow codepoint
0478:                        lobLength = ((clearedByte[4] & 0xFF) << 24)
0479:                                + ((clearedByte[5] & 0xFF) << 16)
0480:                                + ((clearedByte[6] & 0xFF) << 8)
0481:                                + ((clearedByte[7] & 0xFF) << 0);
0482:                        longValueForDecryption_ = new byte[lobLength];
0483:                        System.arraycopy(clearedByte, 8,
0484:                                longValueForDecryption_, 0,
0485:                                clearedByte.length - 8);
0486:                    } else {
0487:                        lobLength = ((clearedByte[0] & 0xFF) << 8)
0488:                                + ((clearedByte[1] & 0xFF) << 0);
0489:                        longValueForDecryption_ = new byte[lobLength - 4];
0490:                        System.arraycopy(clearedByte, 4,
0491:                                longValueForDecryption_, 0,
0492:                                clearedByte.length - 4);
0493:                    }
0494:                } else {
0495:                    int bytesRead = ensureALayerDataInBuffer(dssLength_); //we need to get back all the data here, and then decrypt
0496:                    if (bytesRead > 0) //we ensuredALayerDAtaInBuffer here and set the flag to true, so we don't need do this again later
0497:                    {
0498:                        ensuredLengthForDecryption_ = true;
0499:                    }
0500:                    byte[] encryptedByte = new byte[dssLength_];
0501:                    System.arraycopy(buffer_, pos_, encryptedByte, 0,
0502:                            dssLength_);
0503:                    byte[] array1 = new byte[pos_];
0504:                    System.arraycopy(buffer_, 0, array1, 0, pos_); //save the data before encrypted data in array1
0505:                    byte[] array3 = new byte[buffer_.length - dssLength_ - pos_];
0506:                    System.arraycopy(buffer_, pos_ + dssLength_, array3, 0,
0507:                            buffer_.length - dssLength_ - pos_); //save the data follows encrypted data in array3
0508:                    byte[] clearedByte = null;
0509:                    try {
0510:                        clearedByte = netAgent_.netConnection_
0511:                                .getEncryptionManager().decryptData(
0512:                                        encryptedByte,
0513:                                        NetConfiguration.SECMEC_EUSRIDPWD,
0514:                                        netAgent_.netConnection_
0515:                                                .getTargetPublicKey(),
0516:                                        netAgent_.netConnection_
0517:                                                .getTargetPublicKey());
0518:                    } catch (SqlException e) {
0519:                        //throw new SqlException (agent_.logWriter_, "error in decrypting data");
0520:                    }
0521:                    dssLength_ -= (encryptedByte.length - clearedByte.length);
0522:                    byte[] buffer = new byte[array1.length + clearedByte.length
0523:                            + array3.length];
0524:                    System.arraycopy(array1, 0, buffer, 0, array1.length);
0525:                    System.arraycopy(clearedByte, 0, buffer, array1.length,
0526:                            clearedByte.length);
0527:                    System.arraycopy(array3, 0, buffer, array1.length
0528:                            + clearedByte.length, array3.length);
0529:                    buffer_ = buffer;
0530:                    int oldCount = count_;
0531:                    count_ = count_
0532:                            - (encryptedByte.length - clearedByte.length);
0533:                    if (((clearedByte[2] & 0xff) << 8)
0534:                            + ((clearedByte[3] & 0xff) << 0) == 0x146c) {
0535:                        int firstLobLength = ((clearedByte[0] & 0xFF) << 8)
0536:                                + ((clearedByte[1] & 0xFF) << 0);
0537:
0538:                        boolean flag = false;
0539:                        if (gdsFormatter == 0x54) {
0540:                            flag = true;
0541:                        }
0542:                        if (flag) {
0543:                            if (oldCount - oldDssLength < 6) {
0544:                                int totalBytesRead = fill(6); //sometimes the 2nd EXTDTA doesn't come back, need to fetch again to get it
0545:                                if (totalBytesRead > 0) {
0546:                                    longBufferForDecryption_ = new byte[totalBytesRead];
0547:                                    longPosForDecryption_ = 0;
0548:                                    System.arraycopy(buffer_, pos_
0549:                                            + firstLobLength,
0550:                                            longBufferForDecryption_, 0,
0551:                                            totalBytesRead);
0552:                                }
0553:
0554:                            } else {
0555:                                longBufferForDecryption_ = new byte[count_
0556:                                        - pos_ - firstLobLength];
0557:                                longPosForDecryption_ = 0;
0558:                                System.arraycopy(buffer_,
0559:                                        pos_ + firstLobLength,
0560:                                        longBufferForDecryption_, 0,
0561:                                        longBufferForDecryption_.length);
0562:
0563:                            }
0564:                        } //end if(flag)
0565:                        int lobLength = ((clearedByte[0] & 0xFF) << 8)
0566:                                + ((clearedByte[1] & 0xFF) << 0) - 4;
0567:
0568:                        longValueForDecryption_ = new byte[lobLength];
0569:
0570:                        System.arraycopy(clearedByte, 4,
0571:                                longValueForDecryption_, 0,
0572:                                clearedByte.length - 4); //copy the decrypted lob value (excluded length an dcodepoint) to longValue_
0573:                    } else if (((clearedByte[2] & 0xff) << 8)
0574:                            + ((clearedByte[3] & 0xff) << 0) == 0x241B) {
0575:                        int length = ((clearedByte[0] & 0xFF) << 8)
0576:                                + ((clearedByte[1] & 0xFF) << 0);
0577:                        boolean noData = false;
0578:                        if (clearedByte[4] == -1 && clearedByte[5] == -1) {
0579:                            noData = true; //there is no data, no need to do the copy
0580:                        }
0581:                        if (!noData) {
0582:                            if (length == 32776) {
0583:                                length = ((clearedByte[4] & 0xFF) << 24)
0584:                                        + ((clearedByte[5] & 0xFF) << 16)
0585:                                        + ((clearedByte[6] & 0xFF) << 8)
0586:                                        + ((clearedByte[7] & 0xFF) << 0);
0587:                                longValueForDecryption_ = new byte[length];
0588:                                System.arraycopy(clearedByte, 8,
0589:                                        longValueForDecryption_, 0,
0590:                                        clearedByte.length - 8);
0591:                                longCountForDecryption_ = count_
0592:                                        - (pos_ + length + 8);
0593:                                longBufferForDecryption_ = new byte[buffer_.length
0594:                                        - pos_ - length - 8];
0595:                                System.arraycopy(buffer_, pos_ + length + 8,
0596:                                        longBufferForDecryption_, 0,
0597:                                        longBufferForDecryption_.length);
0598:
0599:                            } else {
0600:                                longPosForDecryption_ = 0;
0601:                                longCountForDecryption_ = count_
0602:                                        - (pos_ + length);
0603:                                longBufferForDecryption_ = new byte[buffer_.length
0604:                                        - pos_ - length];
0605:                                System.arraycopy(buffer_, pos_ + length,
0606:                                        longBufferForDecryption_, 0,
0607:                                        longBufferForDecryption_.length);
0608:
0609:                                longValueForDecryption_ = new byte[length - 4];
0610:
0611:                                System.arraycopy(clearedByte, 4,
0612:                                        longValueForDecryption_, 0,
0613:                                        clearedByte.length - 4);
0614:                            }
0615:                        }
0616:                    }
0617:                }
0618:            }
0619:
0620:            final int readUnsignedShort() throws DisconnectException {
0621:                // should we be checking dss lengths and ddmScalarLengths here
0622:                // if yes, i am not sure this is the correct place if we should be checking
0623:                ensureBLayerDataInBuffer(2);
0624:                adjustLengths(2);
0625:                return ((buffer_[pos_++] & 0xff) << 8)
0626:                        + ((buffer_[pos_++] & 0xff) << 0);
0627:            }
0628:
0629:            final short readShort() throws DisconnectException {
0630:                // should we be checking dss lengths and ddmScalarLengths here
0631:                ensureBLayerDataInBuffer(2);
0632:                adjustLengths(2);
0633:                short s = SignedBinary.getShort(buffer_, pos_);
0634:
0635:                pos_ += 2;
0636:
0637:                return s;
0638:            }
0639:
0640:            final int readInt() throws DisconnectException {
0641:                // should we be checking dss lengths and ddmScalarLengths here
0642:                ensureBLayerDataInBuffer(4);
0643:                adjustLengths(4);
0644:                int i = SignedBinary.getInt(buffer_, pos_);
0645:                pos_ += 4;
0646:
0647:                return i;
0648:            }
0649:
0650:            final void readIntArray(int[] array) throws DisconnectException {
0651:                ensureBLayerDataInBuffer(array.length * 4);
0652:                adjustLengths(array.length * 4);
0653:
0654:                for (int i = 0; i < array.length; i++) {
0655:                    array[i] = SignedBinary.getInt(buffer_, pos_);
0656:                    pos_ += 4;
0657:                }
0658:            }
0659:
0660:            final long readLong() throws DisconnectException {
0661:                // should we be checking dss lengths and ddmScalarLengths here
0662:                ensureBLayerDataInBuffer(8);
0663:                adjustLengths(8);
0664:                long l = SignedBinary.getLong(buffer_, pos_);
0665:
0666:                pos_ += 8;
0667:
0668:                return l;
0669:            }
0670:
0671:            final int[] readUnsignedShortList() throws DisconnectException {
0672:                int len = ddmScalarLen_;
0673:                ensureBLayerDataInBuffer(len);
0674:                adjustLengths(len);
0675:
0676:                int count = len / 2;
0677:                int[] list = new int[count];
0678:
0679:                for (int i = 0; i < count; i++) {
0680:                    list[i] = ((buffer_[pos_++] & 0xff) << 8)
0681:                            + ((buffer_[pos_++] & 0xff) << 0);
0682:                }
0683:
0684:                return list;
0685:            }
0686:
0687:            final int readUnsignedByte() throws DisconnectException {
0688:                ensureBLayerDataInBuffer(1);
0689:                adjustLengths(1);
0690:                return (buffer_[pos_++] & 0xff);
0691:            }
0692:
0693:            final byte readByte() throws DisconnectException {
0694:                ensureBLayerDataInBuffer(1);
0695:                adjustLengths(1);
0696:                return (byte) (buffer_[pos_++] & 0xff);
0697:            }
0698:
0699:            final boolean readBoolean() throws DisconnectException {
0700:                ensureBLayerDataInBuffer(1);
0701:                adjustLengths(1);
0702:                return buffer_[pos_++] != 0;
0703:            }
0704:
0705:            final String readString(int length) throws DisconnectException {
0706:                ensureBLayerDataInBuffer(length);
0707:                adjustLengths(length);
0708:
0709:                String result = ccsidManager_.convertToUCS2(buffer_, pos_,
0710:                        length);
0711:                pos_ += length;
0712:                return result;
0713:            }
0714:
0715:            final String readString(int length, String encoding)
0716:                    throws DisconnectException {
0717:                ensureBLayerDataInBuffer(length);
0718:                adjustLengths(length);
0719:                String s = null;
0720:
0721:                try {
0722:                    s = new String(buffer_, pos_, length, encoding);
0723:                } catch (java.io.UnsupportedEncodingException e) {
0724:                    agent_
0725:                            .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
0726:                                    agent_,
0727:                                    new ClientMessageId(
0728:                                            SQLState.NET_ENCODING_NOT_SUPPORTED),
0729:                                    e));
0730:                }
0731:
0732:                pos_ += length;
0733:                return s;
0734:            }
0735:
0736:            final String readString() throws DisconnectException {
0737:                int len = ddmScalarLen_;
0738:                ensureBLayerDataInBuffer(len);
0739:                adjustLengths(len);
0740:                String result = ccsidManager_.convertToUCS2(buffer_, pos_, len);
0741:                pos_ += len;
0742:                return result;
0743:            }
0744:
0745:            final byte[] readBytes(int length) throws DisconnectException {
0746:                ensureBLayerDataInBuffer(length);
0747:                adjustLengths(length);
0748:
0749:                byte[] b = new byte[length];
0750:                System.arraycopy(buffer_, pos_, b, 0, length);
0751:                pos_ += length;
0752:                return b;
0753:            }
0754:
0755:            final byte[] readBytes() throws DisconnectException {
0756:                int len = ddmScalarLen_;
0757:                ensureBLayerDataInBuffer(len);
0758:                adjustLengths(len);
0759:
0760:                byte[] b = new byte[len];
0761:                System.arraycopy(buffer_, pos_, b, 0, len);
0762:                pos_ += len;
0763:                return b;
0764:            }
0765:
0766:            final byte[] readLDBytes() throws DisconnectException {
0767:                ensureBLayerDataInBuffer(2);
0768:                int len = ((buffer_[pos_++] & 0xff) << 8)
0769:                        + ((buffer_[pos_++] & 0xff) << 0);
0770:
0771:                if (len == 0) {
0772:                    adjustLengths(2);
0773:                    return null;
0774:                }
0775:
0776:                ensureBLayerDataInBuffer(len);
0777:                adjustLengths(len + 2);
0778:
0779:                byte[] b = new byte[len];
0780:                System.arraycopy(buffer_, pos_, b, 0, len);
0781:                pos_ += len;
0782:                return b;
0783:            }
0784:
0785:            final void skipBytes(int length) throws DisconnectException {
0786:                ensureBLayerDataInBuffer(length);
0787:                adjustLengths(length);
0788:                pos_ += length;
0789:            }
0790:
0791:            final void skipBytes() throws DisconnectException {
0792:                int len = ddmScalarLen_;
0793:                ensureBLayerDataInBuffer(len);
0794:                adjustLengths(len);
0795:                pos_ += len;
0796:            }
0797:
0798:            // This will be the new and improved getData that handles all QRYDTA/EXTDTA
0799:            // Returns the stream so that the caller can cache it
0800:            final ByteArrayOutputStream getData(
0801:                    ByteArrayOutputStream existingBuffer)
0802:                    throws DisconnectException {
0803:                boolean readHeader;
0804:                int copySize;
0805:                ByteArrayOutputStream baos;
0806:
0807:                // note: an empty baos can yield an allocated and empty byte[]
0808:                if (existingBuffer != null) {
0809:                    baos = existingBuffer;
0810:                } else {
0811:                    if (ddmScalarLen_ != -1) {
0812:                        // allocate a stream based on a known amount of data
0813:                        baos = new ByteArrayOutputStream(ddmScalarLen_);
0814:                    } else {
0815:                        // allocate a stream to hold an unknown amount of data
0816:                        baos = new ByteArrayOutputStream();
0817:                        //isLengthAndNullabilityUnknown = true;
0818:                    }
0819:                }
0820:
0821:                // set the amount to read for the first segment
0822:                copySize = dssLength_; // note: has already been adjusted for headers
0823:
0824:                do {
0825:                    // determine if a continuation header needs to be read after the data
0826:                    if (dssIsContinued_) {
0827:                        readHeader = true;
0828:                    } else {
0829:                        readHeader = false;
0830:                    }
0831:
0832:                    // read the segment
0833:                    ensureALayerDataInBuffer(copySize);
0834:                    adjustLengths(copySize);
0835:                    baos.write(buffer_, pos_, copySize);
0836:                    pos_ += copySize;
0837:
0838:                    // read the continuation header, if necessary
0839:                    if (readHeader) {
0840:                        readDSSContinuationHeader();
0841:                    }
0842:
0843:                    copySize = dssLength_;
0844:                } while (readHeader == true);
0845:
0846:                return baos;
0847:            }
0848:
0849:            // reads a DSS continuation header
0850:            // prereq: pos_ is positioned on the first byte of the two-byte header
0851:            // post:   dssIsContinued_ is set to true if the continuation bit is on, false otherwise
0852:            //         dssLength_ is set to DssConstants.MAX_DSS_LEN - 2 (don't count the header for the next read)
0853:            // helper method for getEXTDTAData
0854:            protected final void readDSSContinuationHeader()
0855:                    throws DisconnectException {
0856:                ensureALayerDataInBuffer(2);
0857:
0858:                dssLength_ = ((buffer_[pos_++] & 0xFF) << 8)
0859:                        + ((buffer_[pos_++] & 0xFF) << 0);
0860:
0861:                if ((dssLength_ & 0x8000) == 0x8000) {
0862:                    dssLength_ = DssConstants.MAX_DSS_LEN;
0863:                    dssIsContinued_ = true;
0864:                } else {
0865:                    dssIsContinued_ = false;
0866:                }
0867:                // it is a syntax error if the dss continuation header length
0868:                // is less than or equal to two
0869:                if (dssLength_ <= 2) {
0870:                    doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2);
0871:                }
0872:
0873:                dssLength_ -= 2; // avoid consuming the DSS cont header
0874:            }
0875:
0876:            // As part of parsing the reply, the client can detect that the
0877:            // data sent from the target agent does not structurally
0878:            // conform to the requirements of the DDM architecture.  These are
0879:            // the same checks performed by the target server on the messages
0880:            // it receives from the protocolj code.  Server side detected errors
0881:            // result in a SYNTAXRM being returned from the AS.  According to the
0882:            // DDM manual, parsing of the DSS is terminated when the error is
0883:            // detected.  The Syntax Error Code, SYNERRCD, describes the various errors.
0884:            //
0885:            // Note: Not all of these may be valid at the client.  See descriptions for
0886:            // which ones make sense for client side errors/checks.
0887:            // Syntax Error Code                  Description of Error
0888:            // -----------------                  --------------------
0889:            // 0x01                               Dss header Length is less than 6.
0890:            // 0x02                               Dss header Length does not match the
0891:            //                                    number of bytes of data found.
0892:            // 0x03                               Dss header C-byte not D0.
0893:            // 0x04                               Dss header f-bytes either not
0894:            //                                    recognized or not supported.
0895:            // 0x05                               DSS continuation specified but not found.
0896:            //                                    For example, DSS continuation is specified
0897:            //                                    on the last DSS, and the SNA LU 6.2 communication
0898:            //                                    facility returned the SEND indicator.
0899:            // 0x06                               DSS chaining specified but no DSS found.
0900:            //                                    For example, DSS chaining is specified
0901:            //                                    on the last DSS, and the SNA LU 6.2 communication
0902:            //                                    facility returned the SEND indicator.
0903:            // 0x07                               Object length less than four.  For example,
0904:            //                                    a command parameter's length is specified
0905:            //                                    as two, or a command's length is specified as three.
0906:            // 0x08                               Object length does not match the number of bytes of data
0907:            //                                    found.  For example, a RQSDSS with a length of 150
0908:            //                                    contains a command whose length is 125 or a SRVDGN parameter
0909:            //                                    specifies a length of 200 but there are only 50
0910:            //                                    bytes left in the DSS.
0911:            // 0x09                               Object length greater than maximum allowed.
0912:            //                                    For example, a RECCNT parameter specifies a
0913:            //                                    length of ten, but the parameter is defined
0914:            //                                    to have a maximum length of eight.
0915:            // 0x0A                               Object length less than the minimum required.
0916:            //                                    For example, a SVRCOD parameter specifies a
0917:            //                                    length of five, but the parameter is defined
0918:            //                                    to have a fixed length of six.
0919:            // 0x0B                               Object length not allowed.  For example,
0920:            //                                    a FILEXDPT parameter is specified with a length of
0921:            //                                    11, but this would indicate that only half of the hours
0922:            //                                    field is present instead of the complete hours field.
0923:            // 0x0C                               Incorrect large object extended length field (see
0924:            //                                    description of DSS).  For example, an extended
0925:            //                                    length field is present, but it is only three bytes
0926:            //                                    long when it is defined to be a multiple of two bytes.
0927:            // 0x0D                               Object code point index not supported.
0928:            //                                    For example, a code point of 8032 is encountered
0929:            //                                    but x'8' is a reserved code point index.
0930:            // 0x0E                               Required object not found.  For example, a CLEAR
0931:            //                                    command does not have a filnam parameter present,
0932:            //                                    or a MODREC command is not followed by a RECORD
0933:            //                                    command data object.
0934:            // 0x0F                               Too many command data objects sent.  For example,
0935:            //                                    a MODREC command is followed by two RECORD command
0936:            //                                    command data objects, or a DECREC command is followed
0937:            //                                    by RECORD object.
0938:            // 0x10                               Mutually exclusive objects present.
0939:            //                                    For example, a CRTDIRF command specifies both
0940:            //                                    a DCLNAM and FILNAM parameters.
0941:            // 0x11                               Too few command data objects sent.
0942:            //                                    For example, an INSRECEF command that
0943:            //                                    specified RECCNT95) is followed by only
0944:            //                                    4 RECORD command data objects.
0945:            // 0x12                               Duplicate object present.
0946:            //                                    For example, a LSTFAT command has tow FILNAM
0947:            //                                    parameters specified.
0948:            // 0x13                               Invalid request correlator specified.
0949:            //                                    Use PRCCNVRM with PRCCNVDC of 04 or 05 instead
0950:            //                                    of this error code.  This error code is being retained
0951:            //                                    for compatibility with Level 1 of the architecture.
0952:            // 0x14                               Required value not found.
0953:            // 0x15                               Reserved value not allowed.  For example,
0954:            //                                    a INSRECEF command specified a RECCNT(0) parameter.
0955:            // 0x16                               DSS continuation less than or equal to two.
0956:            //                                    For example, the length bytes of the DSS continuation
0957:            //                                    have the value of one.
0958:            // 0x17                               Objects not in required order.  For example, a RECAL
0959:            //                                    object contains a RECORD object followed by a RECNBR
0960:            //                                    object with is not in the defined order.
0961:            // 0x18                               DSS chaining byt not b'1', but DSSFMT bit3 set to b'1'.
0962:            // 0x19                               Previous DSS indicated current DSS has the same
0963:            //                                    request correlator, but the request correlators are
0964:            //                                    not the same.
0965:            // 0x1A                               DSS cahining bit not b'1', but error continuation requested.
0966:            // 0x1B                               Mutually exclusive parameter values not specified.
0967:            //                                    For example, an OPEN command specified PRPSHD(TRUE)
0968:            //                                    and FILSHR(READER).
0969:            // 0x1D                               Code point not valid command.  For example, the first
0970:            //                                    code point in RQSDSS either is not in the dictionary
0971:            //                                    or is not a code point for a command.
0972:            //
0973:            // When the client detects these errors, it will be handled as if a SYNTAXRM is returned
0974:            // from the server.  In this SYNTAXRM case, PROTOCOL architects an SQLSTATE of 58008 or 58009.
0975:            //
0976:            // Messages
0977:            // SQLSTATE : 58009
0978:            //     Execution failed due to a distribution protocol error that caused deallocation of the conversation.
0979:            //     SQLCODE : -30020
0980:            //     Execution failed because of a Distributed Protocol
0981:            //         Error that will affect the successful execution of subsequent
0982:            //         commands and SQL statements: Reason Code <reason-code>.
0983:            //      Some possible reason codes include:
0984:            //      121C Indicates that the user is not authorized to perform the requested command.
0985:            //      1232 The command could not be completed because of a permanent error.
0986:            //          In most cases, the server will be in the process of an abend.
0987:            //      220A The target server has received an invalid data description.
0988:            //          If a user SQLDA is specified, ensure that the fields are
0989:            //          initialized correctly. Also, ensure that the length does not
0990:            //          exceed the maximum allowed length for the data type being used.
0991:            //
0992:            //      The command or statement cannot be processed.  The current
0993:            //          transaction is rolled back and the application is disconnected
0994:            //          from the remote database.
0995:            final void doSyntaxrmSemantics(int syntaxErrorCode)
0996:                    throws DisconnectException {
0997:                agent_
0998:                        .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
0999:                                agent_,
1000:                                new ClientMessageId(
1001:                                        SQLState.DRDA_CONNECTION_TERMINATED),
1002:                                SqlException
1003:                                        .getMessageUtil()
1004:                                        .getTextMessage(
1005:                                                MessageId.CONN_DRDA_DATASTREAM_SYNTAX_ERROR,
1006:                                                new Integer(syntaxErrorCode))));
1007:            }
1008:
1009:            // the names of these methods start with a letter z.
1010:            // the z will be removed when they are finalized...
1011:
1012:            protected final void pushLengthOnCollectionStack() {
1013:                ddmCollectionLenStack_[++topDdmCollectionStack_] = ddmScalarLen_;
1014:                ddmScalarLen_ = 0;
1015:            }
1016:
1017:            protected final void adjustLengths(int length) {
1018:                ddmScalarLen_ -= length;
1019:                adjustCollectionAndDssLengths(length);
1020:                /*
1021:                for (int i = 0; i <= topDdmCollectionStack_; i++) {
1022:                  ddmCollectionLenStack_[i] -= length;
1023:                }
1024:                dssLength_ -= length;
1025:                 */
1026:            }
1027:
1028:            protected int adjustDdmLength(int ddmLength, int length) {
1029:                ddmLength -= length;
1030:                if (ddmLength == 0) {
1031:                    adjustLengths(getDdmLength());
1032:                }
1033:                return ddmLength;
1034:            }
1035:
1036:            // Pop the collection Length stack.
1037:            // pre:  The collection length stack must not be empty and the top value
1038:            //       on the stack must be 0.
1039:            // post: The top 0 value on the stack will be popped.
1040:            protected final void popCollectionStack() {
1041:                topDdmCollectionStack_--;
1042:            }
1043:
1044:            protected final int peekCodePoint() throws DisconnectException {
1045:                if (topDdmCollectionStack_ != EMPTY_STACK) {
1046:                    if (ddmCollectionLenStack_[topDdmCollectionStack_] == 0) {
1047:                        return END_OF_COLLECTION;
1048:                    } else if (ddmCollectionLenStack_[topDdmCollectionStack_] < 4) {
1049:                        // error
1050:                    }
1051:                }
1052:
1053:                // if there is no more data in the current dss, and the dss is not
1054:                // continued, indicate the end of the same Id chain or read the next dss header.
1055:                if ((dssLength_ == 0) && (!dssIsContinued_)) {
1056:                    if (!dssIsChainedWithSameID_) {
1057:                        return END_OF_SAME_ID_CHAIN;
1058:                    }
1059:                    readDssHeader();
1060:                }
1061:
1062:                if (longBufferForDecryption_ == null) //we don't need to do this if it's data stream encryption
1063:                {
1064:                    ensureBLayerDataInBuffer(4);
1065:                }
1066:                peekedLength_ = ((buffer_[pos_] & 0xff) << 8)
1067:                        + ((buffer_[pos_ + 1] & 0xff) << 0);
1068:                peekedCodePoint_ = ((buffer_[pos_ + 2] & 0xff) << 8)
1069:                        + ((buffer_[pos_ + 3] & 0xff) << 0);
1070:
1071:                // check for extended length
1072:                if ((peekedLength_ & 0x8000) == 0x8000) {
1073:                    peekExtendedLength();
1074:                } else {
1075:                    peekedNumOfExtendedLenBytes_ = 0;
1076:                }
1077:                return peekedCodePoint_;
1078:            }
1079:
1080:            // Read out the 2-byte length without moving the pos_ pointer.
1081:            protected final int peekLength() throws DisconnectException {
1082:                ensureBLayerDataInBuffer(2);
1083:                return (((buffer_[pos_] & 0xff) << 8) + ((buffer_[pos_ + 1] & 0xff) << 0));
1084:            }
1085:
1086:            // Read "length" number of bytes from the buffer into the byte array b starting from offset
1087:            // "offset".  The current offset in the buffer does not change.
1088:            protected final int peekFastBytes(byte[] b, int offset, int length)
1089:                    throws DisconnectException {
1090:                for (int i = 0; i < length; i++) {
1091:                    b[offset + i] = buffer_[pos_ + i];
1092:                }
1093:                return offset + length;
1094:            }
1095:
1096:            protected final void parseLengthAndMatchCodePoint(
1097:                    int expectedCodePoint) throws DisconnectException {
1098:                int actualCodePoint = 0;
1099:                if (peekedCodePoint_ == END_OF_COLLECTION) {
1100:                    actualCodePoint = readLengthAndCodePoint();
1101:                } else {
1102:                    actualCodePoint = peekedCodePoint_;
1103:                    pos_ += (4 + peekedNumOfExtendedLenBytes_);
1104:                    ddmScalarLen_ = peekedLength_;
1105:                    if (peekedNumOfExtendedLenBytes_ == 0
1106:                            && ddmScalarLen_ != -1) {
1107:                        adjustLengths(4);
1108:                    } else {
1109:                        adjustCollectionAndDssLengths(4 + peekedNumOfExtendedLenBytes_);
1110:                    }
1111:                    peekedLength_ = 0;
1112:                    peekedCodePoint_ = END_OF_COLLECTION;
1113:                    peekedNumOfExtendedLenBytes_ = 0;
1114:                }
1115:
1116:                if (actualCodePoint != expectedCodePoint) {
1117:                    agent_
1118:                            .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
1119:                                    agent_,
1120:                                    new ClientMessageId(
1121:                                            SQLState.NET_NOT_EXPECTED_CODEPOINT),
1122:                                    new Integer(actualCodePoint), new Integer(
1123:                                            expectedCodePoint)));
1124:                }
1125:            }
1126:
1127:            protected final int readLengthAndCodePoint()
1128:                    throws DisconnectException {
1129:                if (topDdmCollectionStack_ != EMPTY_STACK) {
1130:                    if (ddmCollectionLenStack_[topDdmCollectionStack_] == 0) {
1131:                        return END_OF_COLLECTION;
1132:                    } else if (ddmCollectionLenStack_[topDdmCollectionStack_] < 4) {
1133:                        agent_
1134:                                .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
1135:                                        agent_,
1136:                                        new ClientMessageId(
1137:                                                SQLState.NET_DDM_COLLECTION_TOO_SMALL)));
1138:                    }
1139:                }
1140:
1141:                // if there is no more data in the current dss, and the dss is not
1142:                // continued, indicate the end of the same Id chain or read the next dss header.
1143:                if ((dssLength_ == 0) && (!dssIsContinued_)) {
1144:                    if (!dssIsChainedWithSameID_) {
1145:                        return END_OF_SAME_ID_CHAIN;
1146:                    }
1147:                    readDssHeader();
1148:                }
1149:
1150:                ensureBLayerDataInBuffer(4);
1151:                ddmScalarLen_ = ((buffer_[pos_++] & 0xff) << 8)
1152:                        + ((buffer_[pos_++] & 0xff) << 0);
1153:                int codePoint = ((buffer_[pos_++] & 0xff) << 8)
1154:                        + ((buffer_[pos_++] & 0xff) << 0);
1155:                adjustLengths(4);
1156:
1157:                // check for extended length
1158:                if ((ddmScalarLen_ & 0x8000) == 0x8000) {
1159:                    readExtendedLength();
1160:                }
1161:                return codePoint;
1162:            }
1163:
1164:            private final void readExtendedLength() throws DisconnectException {
1165:                int numberOfExtendedLenBytes = (ddmScalarLen_ - 0x8000); // fix scroll problem was - 4
1166:                int adjustSize = 0;
1167:                switch (numberOfExtendedLenBytes) {
1168:                case 4:
1169:                    ensureBLayerDataInBuffer(4);
1170:                    ddmScalarLen_ = ((buffer_[pos_++] & 0xff) << 24)
1171:                            + ((buffer_[pos_++] & 0xff) << 16)
1172:                            + ((buffer_[pos_++] & 0xff) << 8)
1173:                            + ((buffer_[pos_++] & 0xff) << 0);
1174:                    adjustSize = 4;
1175:                    break;
1176:                case 0:
1177:                    ddmScalarLen_ = -1;
1178:                    adjustSize = 0;
1179:                    break;
1180:                default:
1181:                    doSyntaxrmSemantics(CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN);
1182:                }
1183:
1184:                adjustCollectionAndDssLengths(adjustSize);
1185:                /*
1186:                // adjust the lengths here.  this is a special case since the
1187:                // extended length bytes do not include their own length.
1188:                for (int i = 0; i <= topDdmCollectionStack_; i++) {
1189:                  ddmCollectionLenStack_[i] -= adjustSize;
1190:                }
1191:                dssLength_ -= adjustSize;
1192:                 */
1193:            }
1194:
1195:            private final void adjustCollectionAndDssLengths(int length) {
1196:                // adjust the lengths here.  this is a special case since the
1197:                // extended length bytes do not include their own length.
1198:                for (int i = 0; i <= topDdmCollectionStack_; i++) {
1199:                    ddmCollectionLenStack_[i] -= length;
1200:                }
1201:                dssLength_ -= length;
1202:            }
1203:
1204:            protected final void startSameIdChainParse()
1205:                    throws DisconnectException {
1206:                readDssHeader();
1207:                netAgent_.clearSvrcod();
1208:            }
1209:
1210:            protected final void endOfSameIdChainData()
1211:                    throws DisconnectException {
1212:                netAgent_.targetTypdef_ = netAgent_.originalTargetTypdef_;
1213:                netAgent_.targetSqlam_ = netAgent_.orignalTargetSqlam_;
1214:
1215:                if (this .topDdmCollectionStack_ != Reply.EMPTY_STACK) {
1216:                    agent_
1217:                            .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
1218:                                    agent_,
1219:                                    new ClientMessageId(
1220:                                            SQLState.NET_COLLECTION_STACK_NOT_EMPTY)));
1221:                }
1222:                if (this .dssLength_ != 0) {
1223:                    agent_
1224:                            .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
1225:                                    agent_, new ClientMessageId(
1226:                                            SQLState.NET_DSS_NOT_ZERO)));
1227:                }
1228:                if (dssIsChainedWithSameID_ == true) {
1229:                    agent_
1230:                            .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
1231:                                    agent_,
1232:                                    new ClientMessageId(
1233:                                            SQLState.NET_DSS_CHAINED_WITH_SAME_ID)));
1234:                }
1235:            }
1236:
1237:            protected final int peekTotalColumnCount(int tripletLength)
1238:                    throws DisconnectException {
1239:                int columnCount = 0;
1240:                int offset = 0;
1241:                int tripletType = FdocaConstants.CPT_TRIPLET_TYPE;
1242:                while (tripletType == FdocaConstants.CPT_TRIPLET_TYPE) {
1243:                    columnCount += ((tripletLength - 3) / 3);
1244:                    // Peek ahead for the next triplet's tripletLength and tripletType.
1245:                    // The number of bytes to skip before the next tripletType is tripletLength - 3.
1246:                    ensureBLayerDataInBuffer(tripletLength - 3);
1247:                    offset += (tripletLength - 3);
1248:                    tripletLength = (buffer_[pos_ + offset++] & 0xff);
1249:                    tripletType = (buffer_[pos_ + offset++] & 0xff);
1250:                    // Skip the 1-byte tripletId.
1251:                    offset++;
1252:                }
1253:                return columnCount;
1254:            }
1255:
1256:            private final void peekExtendedLength() throws DisconnectException {
1257:                peekedNumOfExtendedLenBytes_ = (peekedLength_ - 0x8004);
1258:                switch (peekedNumOfExtendedLenBytes_) {
1259:                case 4:
1260:                    // L   L   C   P  Extended Length
1261:                    // -->2-bytes<--  --->4-bytes<---
1262:                    // We are only peeking the length here, the actual pos_ is still before LLCP.  We ensured
1263:                    // 4-bytes in peedCodePoint() for the LLCP, and we need to ensure 4-bytes(of LLCP) + the
1264:                    // extended length bytes here.
1265:                    if (longBufferForDecryption_ == null) //we ddon't need to do this if it's data stream encryption
1266:                    {
1267:                        ensureBLayerDataInBuffer(4 + 4);
1268:                    }
1269:                    // The ddmScalarLen_ we peek here does not include the LLCP and the extended length bytes
1270:                    // themselves.  So we will add those back to the ddmScalarLen_ so it can be adjusted
1271:                    // correctly in parseLengthAndMatchCodePoint(). (since the adjustLengths() method will
1272:                    // subtract the length from ddmScalarLen_)
1273:                    peekedLength_ = ((buffer_[pos_ + 4] & 0xff) << 24)
1274:                            + ((buffer_[pos_ + 5] & 0xff) << 16)
1275:                            + ((buffer_[pos_ + 6] & 0xff) << 8)
1276:                            + ((buffer_[pos_ + 7] & 0xff) << 0);
1277:                    break;
1278:                case 0:
1279:                    peekedLength_ = -1; // this ddm is streamed, so set -1 -> length unknown
1280:                    break;
1281:                default:
1282:                    doSyntaxrmSemantics(CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN);
1283:                }
1284:            }
1285:
1286:            final int readFastUnsignedByte() throws DisconnectException {
1287:                return (buffer_[pos_++] & 0xff);
1288:            }
1289:
1290:            final short readFastShort() throws DisconnectException {
1291:                short s = SignedBinary.getShort(buffer_, pos_);
1292:                pos_ += 2;
1293:                return s;
1294:            }
1295:
1296:            final int readFastUnsignedShort() throws DisconnectException {
1297:                return ((buffer_[pos_++] & 0xff) << 8)
1298:                        + ((buffer_[pos_++] & 0xff) << 0);
1299:            }
1300:
1301:            final int readFastInt() throws DisconnectException {
1302:                int i = SignedBinary.getInt(buffer_, pos_);
1303:                pos_ += 4;
1304:                return i;
1305:            }
1306:
1307:            final String readFastString(int length) throws DisconnectException {
1308:                String result = ccsidManager_.convertToUCS2(buffer_, pos_,
1309:                        length);
1310:                pos_ += length;
1311:                return result;
1312:            }
1313:
1314:            final byte[] readFastBytes(int length) throws DisconnectException {
1315:                byte[] b = new byte[length];
1316:                System.arraycopy(buffer_, pos_, b, 0, length);
1317:                pos_ += length;
1318:                return b;
1319:            }
1320:
1321:            protected final int peekFastLength() throws DisconnectException {
1322:                return (((buffer_[pos_] & 0xff) << 8) + ((buffer_[pos_ + 1] & 0xff) << 0));
1323:            }
1324:
1325:            final void skipFastBytes(int length) throws DisconnectException {
1326:                pos_ += length;
1327:            }
1328:
1329:            final void readFastIntArray(int[] array) throws DisconnectException {
1330:                for (int i = 0; i < array.length; i++) {
1331:                    array[i] = SignedBinary.getInt(buffer_, pos_);
1332:                    pos_ += 4;
1333:                }
1334:            }
1335:
1336:            final String readFastString(int length, String encoding)
1337:                    throws DisconnectException {
1338:                String s = null;
1339:
1340:                try {
1341:                    s = new String(buffer_, pos_, length, encoding);
1342:                } catch (java.io.UnsupportedEncodingException e) {
1343:                    agent_
1344:                            .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
1345:                                    agent_,
1346:                                    new ClientMessageId(
1347:                                            SQLState.NET_ENCODING_NOT_SUPPORTED),
1348:                                    e));
1349:                }
1350:                pos_ += length;
1351:                return s;
1352:            }
1353:
1354:            final byte[] readFastLDBytes() throws DisconnectException {
1355:                int len = ((buffer_[pos_++] & 0xff) << 8)
1356:                        + ((buffer_[pos_++] & 0xff) << 0);
1357:                if (len == 0) {
1358:                    return null;
1359:                }
1360:
1361:                byte[] b = new byte[len];
1362:                System.arraycopy(buffer_, pos_, b, 0, len);
1363:                pos_ += len;
1364:                return b;
1365:            }
1366:
1367:            final long readFastLong() throws DisconnectException {
1368:                long l = SignedBinary.getLong(buffer_, pos_);
1369:                pos_ += 8;
1370:                return l;
1371:            }
1372:
1373:            final byte readFastByte() throws DisconnectException {
1374:                return (byte) (buffer_[pos_++] & 0xff);
1375:            }
1376:
1377:            final void mark() {
1378:                currentPos_ = pos_;
1379:            }
1380:
1381:            // remove and return the top offset value from mark stack.
1382:            final int popMark() {
1383:                return currentPos_;
1384:            }
1385:
1386:            final int getFastSkipSQLCARDrowLength() {
1387:                return pos_ - popMark();
1388:            }
1389:
1390:            // The only difference between this method and the original getData() method is this method
1391:            // is not doing an ensureALayerDataInBuffer
1392:            final ByteArrayOutputStream getFastData(
1393:                    ByteArrayOutputStream existingBuffer)
1394:                    throws DisconnectException {
1395:                boolean readHeader;
1396:                int copySize;
1397:                ByteArrayOutputStream baos;
1398:
1399:                // note: an empty baos can yield an allocated and empty byte[]
1400:                if (existingBuffer != null) {
1401:                    baos = existingBuffer;
1402:                } else {
1403:                    if (ddmScalarLen_ != -1) {
1404:                        // allocate a stream based on a known amount of data
1405:                        baos = new ByteArrayOutputStream(ddmScalarLen_);
1406:                    } else {
1407:                        // allocate a stream to hold an unknown amount of data
1408:                        baos = new ByteArrayOutputStream();
1409:                        //isLengthAndNullabilityUnknown = true;
1410:                    }
1411:                }
1412:
1413:                // set the amount to read for the first segment
1414:                copySize = dssLength_; // note: has already been adjusted for headers
1415:
1416:                do {
1417:                    // determine if a continuation header needs to be read after the data
1418:                    if (dssIsContinued_) {
1419:                        readHeader = true;
1420:                    } else {
1421:                        readHeader = false;
1422:                    }
1423:
1424:                    // read the segment
1425:                    //ensureALayerDataInBuffer (copySize);
1426:                    adjustLengths(copySize);
1427:                    baos.write(buffer_, pos_, copySize);
1428:                    pos_ += copySize;
1429:
1430:                    // read the continuation header, if necessary
1431:                    if (readHeader) {
1432:                        readDSSContinuationHeader();
1433:                    }
1434:
1435:                    copySize = dssLength_;
1436:                } while (readHeader == true);
1437:
1438:                return baos;
1439:            }
1440:
1441:            // This method is only used to match the codePoint for those class instance variables
1442:            // that are embedded in other reply messages.
1443:            final protected void matchCodePoint(int expectedCodePoint)
1444:                    throws DisconnectException {
1445:                int actualCodePoint = 0;
1446:                actualCodePoint = peekedCodePoint_;
1447:                pos_ += 4;
1448:                if (actualCodePoint != expectedCodePoint) {
1449:                    agent_
1450:                            .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
1451:                                    agent_,
1452:                                    new ClientMessageId(
1453:                                            SQLState.NET_NOT_EXPECTED_CODEPOINT),
1454:                                    new Integer(actualCodePoint), new Integer(
1455:                                            expectedCodePoint)));
1456:                }
1457:            }
1458:
1459:            protected final int peekNumOfColumns() throws DisconnectException {
1460:                // skip the 4-byte LLCP and any extended length bytes + 1-byte null sqlcagrp null indicator
1461:                int offset = (4 + peekedNumOfExtendedLenBytes_ + 1);
1462:
1463:                offset = skipSQLDHROW(offset);
1464:
1465:                return SignedBinary.getShort(buffer_, pos_ + offset);
1466:            }
1467:
1468:            protected final boolean peekForNullSqlcagrp() {
1469:                // skip the 4-byte LLCP and any extended length bytes
1470:                int offset = (4 + peekedNumOfExtendedLenBytes_);
1471:                int nullInd = buffer_[pos_ + offset] & 0xff;
1472:                return (nullInd == CodePoint.NULLDATA);
1473:            }
1474:
1475:            private final int skipSQLDHROW(int offset)
1476:                    throws DisconnectException {
1477:                int sqldhrowgrpNullInd = buffer_[pos_ + offset++] & 0xff;
1478:                if (sqldhrowgrpNullInd == CodePoint.NULLDATA) {
1479:                    return offset;
1480:                }
1481:
1482:                offset += 12;
1483:
1484:                // skip sqldrdbnam
1485:                int stringLength = ((buffer_[pos_ + offset++] & 0xff) << 8)
1486:                        + ((buffer_[pos_ + offset++] & 0xff) << 0);
1487:                offset += stringLength;
1488:
1489:                // skip sqldschema
1490:                stringLength = ((buffer_[pos_ + offset++] & 0xff) << 8)
1491:                        + ((buffer_[pos_ + offset++] & 0xff) << 0);
1492:                offset += stringLength;
1493:
1494:                stringLength = ((buffer_[pos_ + offset++] & 0xff) << 8)
1495:                        + ((buffer_[pos_ + offset++] & 0xff) << 0);
1496:                offset += stringLength;
1497:
1498:                return offset;
1499:            }
1500:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.