Source Code Cross Referenced for DDMReader.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » drda » 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.impl.drda 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.impl.drda.DDMReader
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.impl.drda;
0023:
0024:        import org.apache.derby.iapi.services.sanity.SanityManager;
0025:        import java.io.IOException;
0026:        import java.io.InputStream;
0027:        import java.io.ByteArrayOutputStream;
0028:        import java.io.ByteArrayInputStream;
0029:        import java.math.BigDecimal;
0030:
0031:        /**
0032:         The DDMReader is used to read DRDA protocol.   DRDA Protocol is divided into
0033:         three layers corresponding to the DDM three-tier architecture. For each layer,
0034:         their is a DSS (Data Stream Structure) defined.
0035:         Layer A 	Communications management services
0036:         Layer B		Agent services
0037:         Layer C 	Data management services
0038:         <P>
0039:         At layer A are request, reply and data correlation, structure chaining,
0040:         continuation or termination of chains when errors are detected, interleaving
0041:         and multi-leaving request, reply, and data DSSs for multitasking environments.
0042:         For TCP/IP, the format of the DDM envelope is
0043:         2 bytes		Length of the data
0044:         1 byte		'D0' - indicates DDM data
0045:         1 byte		DDM format byte(DSSFMT) - type of DSS(RQSDSS,RPYDSS), whether it is
0046:         chained, information about the next chained DSS
0047:         2 bytes		request correlation identifier
0048:         <P>
0049:         The correlation identifier ties together a request, the request data and the
0050:         reply.  In a chained DSS, each request has a correlation identifier which
0051:         is higher than the previous request (all correlation identifiers must
0052:         be greater than 0).
0053:         <P>
0054:         At layer B are object mapping, object validation and command routing.
0055:         Layer B objects with data 5 bytes less than 32K bytes consist of
0056:         2 bytes		Length
0057:         2 bytes		Type of the object (code point)
0058:         Object data
0059:         Object data is either SCALAR or COLLECTION data.  Scalar data consists of
0060:         a string of bytes formatted as the class description of the object required.
0061:         Collections consist of a set of objects in which the entries in the collection
0062:         are nested within the length/ code point of the collection.
0063:         <P>
0064:         Layer B objects with data >=32763 bytes long format is 
0065:         2 bytes		Length - length of class, length, and extended total length fields
0066:         (high order bit set, indicating >=32763)
0067:         2 bytes		Type of the object (code point)
0068:         n bytes		Extended total length - length of the object
0069:         (n = Length - 4)
0070:         Object data
0071:         <P>
0072:         At layer C are services each class of DDM object provides.
0073:
0074:         |-------------------------------------------|
0075:         Layer C | Specific	|	Specific	|	Specific	|
0076:         | Commands	|	Replies		| Scalars and	|
0077:         | and their |  and their    | Collections   |
0078:         |-------------------------------------------|----------------|
0079:         Layer B | Commands  |    Reply		| Scalars and   | Communications |
0080:         |			|   Messages	| Collections	|                |
0081:         |-----------|---------------|---------------|----------------|
0082:         Layer A |  RQSDSS   |   RPYDSS		| OBJDSS		| CMNDSS         |
0083:         |           |               |               | Mapped Data    |
0084:         |-----------|---------------|---------------|----------------|
0085:         |                DDM Data Stream Structures                  |
0086:         |------------------------------------------------------------|
0087:        
0088:         DSS's may be chained so that more than one can be transmitted at a time
0089:         to improve performance.
0090:         For more details, see DRDA Volume 3 (Distributed Data Management(DDM)
0091:         Architecture (DDS definition)
0092:         */
0093:        class DDMReader {
0094:            private final static int DEFAULT_BUFFER_SIZE = 32767;
0095:            private final static int MAX_MARKS_NESTING = 10;
0096:            private final static int NO_CODEPOINT = -1;
0097:            private final static int EMPTY_STACK = -1;
0098:            private final static boolean ADJUST_LENGTHS = true;
0099:            private final static boolean NO_ADJUST_LENGTHS = false;
0100:            private final static long MAX_EXTDTA_SIZE = Long.MAX_VALUE;
0101:            private static boolean internalTrace = true;
0102:
0103:            // magnitude represented in an int array, used in BigDecimal conversion
0104:            private static final int[][] tenRadixMagnitude = { { 0x3b9aca00 }, // 10^9
0105:                    { 0x0de0b6b3, 0xa7640000 }, // 10^18
0106:                    { 0x033b2e3c, 0x9fd0803c, 0xe8000000 }, // 10^27
0107:            };
0108:
0109:            private DRDAConnThread agent;
0110:            private CcsidManager ccsidManager;
0111:
0112:            // data buffer
0113:            private byte[] buffer;
0114:            private int pos;
0115:            private int count;
0116:
0117:            // DDM object collection
0118:            // top of stack
0119:            private int topDdmCollectionStack;
0120:            // length of each object in the stack
0121:            private long[] ddmCollectionLenStack;
0122:
0123:            // DDM object length
0124:            private long ddmScalarLen;
0125:
0126:            // DSS Length
0127:            private int dssLength;
0128:
0129:            // DSS is larger than 32762 (continuation bit is set) so DSS is continued
0130:            private boolean dssIsContinued;
0131:
0132:            private boolean terminateChainOnErr;
0133:
0134:            // next DSS in the chain has the same correlator
0135:            private boolean dssIsChainedWithSameID;
0136:
0137:            // next DSS in the chain has a different correlator
0138:            private boolean dssIsChainedWithDiffID;
0139:
0140:            // correlation id for the current DSS
0141:            private int dssCorrelationID;
0142:
0143:            // previous corelation id
0144:            private int prevCorrelationID;
0145:
0146:            // current server codepoint
0147:            private int svrcod;
0148:
0149:            // trace object of the associated session
0150:            private DssTrace dssTrace;
0151:
0152:            // input stream
0153:            private InputStream inputStream;
0154:
0155:            // constructor
0156:            DDMReader(DRDAConnThread agent, DssTrace dssTrace) {
0157:                buffer = new byte[DEFAULT_BUFFER_SIZE];
0158:                ddmCollectionLenStack = new long[MAX_MARKS_NESTING];
0159:                initialize(agent, dssTrace);
0160:            }
0161:
0162:            /**
0163:             * This constructor is used for testing the protocol
0164:             * It is used by TestProto to read the protocol returned by the
0165:             * server 
0166:             */
0167:            DDMReader(CcsidManager ccsidManager, InputStream inputStream) {
0168:                buffer = new byte[DEFAULT_BUFFER_SIZE];
0169:                ddmCollectionLenStack = new long[MAX_MARKS_NESTING];
0170:                this .ccsidManager = ccsidManager;
0171:                this .inputStream = inputStream;
0172:                initialize(null, null);
0173:                // turn off tracing
0174:                internalTrace = false;
0175:            }
0176:
0177:            /**
0178:             * This initializer is used for testing the protocol
0179:             * It is used by TestProto for the reader it uses
0180:             */
0181:            protected void initialize(InputStream inputStream) {
0182:                this .inputStream = inputStream;
0183:                initialize(null, null);
0184:            }
0185:
0186:            /**
0187:             * Initialize values for this session, the reader is reused so we need to
0188:             * set null and 0 values
0189:             */
0190:            protected void initialize(DRDAConnThread agent, DssTrace dssTrace) {
0191:                this .agent = agent;
0192:                if (agent != null) {
0193:                    ccsidManager = agent.ccsidManager;
0194:                    inputStream = agent.getInputStream();
0195:                }
0196:                topDdmCollectionStack = EMPTY_STACK;
0197:                svrcod = 0;
0198:                pos = 0;
0199:                count = 0;
0200:                ddmScalarLen = 0;
0201:                dssLength = 0;
0202:                prevCorrelationID = DssConstants.CORRELATION_ID_UNKNOWN;
0203:                dssCorrelationID = DssConstants.CORRELATION_ID_UNKNOWN;
0204:                this .dssTrace = dssTrace;
0205:            }
0206:
0207:            protected boolean terminateChainOnErr() {
0208:                return terminateChainOnErr;
0209:            }
0210:
0211:            /**
0212:             * Next DSS has same correlator as current DSS
0213:             *
0214:             * @return true if next DSS has the same correlator as current DSS
0215:             */
0216:            protected boolean isChainedWithSameID() {
0217:                return dssIsChainedWithSameID;
0218:            }
0219:
0220:            /**
0221:             * Next DSS has different correlator than current DSS
0222:             *
0223:             * @return true if next DSS has a different correlator than current DSS
0224:             */
0225:            protected boolean isChainedWithDiffID() {
0226:                return dssIsChainedWithDiffID;
0227:            }
0228:
0229:            /**
0230:             * Length of current DDM object
0231:             *
0232:             * @return length of DDM object
0233:             */
0234:            protected long getDdmLength() {
0235:                return ddmScalarLen;
0236:            }
0237:
0238:            /**
0239:             * Is there more in this DDM object
0240:             *
0241:             * @return true if DDM length is > 0
0242:             */
0243:            protected boolean moreDdmData() {
0244:                return ddmScalarLen > 0;
0245:            }
0246:
0247:            /**
0248:             * Is there more in this DDS object
0249:             *
0250:             * @return true if DDS length is > 0
0251:             */
0252:            protected boolean moreDssData() {
0253:                return dssLength > 0;
0254:            }
0255:
0256:            /** 
0257:             * Is there more data in the buffer
0258:             *
0259:             * @return true if there is more data in the buffer
0260:             */
0261:            protected boolean moreData() {
0262:                return (pos - count) > 0;
0263:            }
0264:
0265:            /**
0266:             * Check for the command protocol
0267:             *
0268:             * @return true if this is a command; false otherwise
0269:             *
0270:             * @exception DRDProtocolException
0271:             */
0272:            protected boolean isCmd() throws DRDAProtocolException,
0273:                    java.io.UnsupportedEncodingException {
0274:                ensureALayerDataInBuffer(4);
0275:                String val = new String(buffer, 0, 4,
0276:                        NetworkServerControlImpl.DEFAULT_ENCODING);
0277:                return NetworkServerControlImpl.isCmd(val);
0278:            }
0279:
0280:            /**
0281:             * Read DSS header
0282:             * DSS Header format is 
0283:             * 	2 bytes	- length
0284:             *	1 byte	- 'D0'	- indicates DDM data
0285:             * 	1 byte	- DSS format 
0286:             *		|---|---------|----------|
0287:             *		| 0	|  flags  |  type    |
0288:             *		|---|---------|----------|
0289:             *		| 0 | 1  2  3 | 4 5 6 7  |
0290:             *		|---|---------|----------|
0291:             *		bit 0 - '0'
0292:             *		bit 1 - '0' - unchained, '1' - chained
0293:             *		bit 2 - '0'	- do not continue on error, '1' - continue on error
0294:             *		bit 3 - '0' - next DSS has different correlator, '1' - next DSS has
0295:             *						same correlator
0296:             *		type - 1 - Request DSS
0297:             *			 - 2 - Reply DSS
0298:             *			 - 3 - Object DSS
0299:             *			 - 4 - Communications DSS
0300:             *			 - 5 - Request DSS where no reply is expected
0301:             *	2 bytes - request correlation id
0302:             *
0303:             * @exception DRDProtocolException
0304:             */
0305:            protected int readDssHeader() throws DRDAProtocolException {
0306:                ensureALayerDataInBuffer(6);
0307:
0308:                // read out the DSS length
0309:                dssLength = ((buffer[pos] & 0xff) << 8)
0310:                        + ((buffer[pos + 1] & 0xff) << 0);
0311:                pos += 2;
0312:                // check for the continuation bit and update length as needed.
0313:                if ((dssLength & DssConstants.CONTINUATION_BIT) == DssConstants.CONTINUATION_BIT) {
0314:                    dssLength = DssConstants.MAX_DSS_LENGTH;
0315:                    dssIsContinued = true;
0316:                } else {
0317:                    dssIsContinued = false;
0318:                }
0319:
0320:                if (dssLength < 6)
0321:                    agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_LESS_THAN_6,
0322:                            DRDAProtocolException.NO_CODPNT_ARG);
0323:
0324:                // If the GDS id is not valid, or
0325:                // if the reply is not an RQSDSS nor
0326:                // a OBJDSS, then throw an exception.
0327:
0328:                if ((buffer[pos++] & 0xff) != DssConstants.DSS_ID)
0329:                    agent.throwSyntaxrm(CodePoint.SYNERRCD_CBYTE_NOT_D0,
0330:                            DRDAProtocolException.NO_CODPNT_ARG);
0331:
0332:                int gdsFormatter = buffer[pos++] & 0xff;
0333:
0334:                if (((gdsFormatter & 0x0F) != DssConstants.DSSFMT_RQSDSS)
0335:                        && ((gdsFormatter & 0x0F) != DssConstants.DSSFMT_OBJDSS)) {
0336:                    agent.throwSyntaxrm(CodePoint.SYNERRCD_FBYTE_NOT_SUPPORTED,
0337:                            DRDAProtocolException.NO_CODPNT_ARG);
0338:                }
0339:
0340:                // Determine if the current DSS is chained with the
0341:                // next DSS, with the same or different request ID.
0342:                if ((gdsFormatter & DssConstants.DSSCHAIN) == DssConstants.DSSCHAIN) { // on indicates structure chained to next structure
0343:                    if ((gdsFormatter & DssConstants.DSSCHAIN_SAME_ID) == DssConstants.DSSCHAIN_SAME_ID) {
0344:                        dssIsChainedWithSameID = true;
0345:                        dssIsChainedWithDiffID = false;
0346:                    } else {
0347:                        dssIsChainedWithSameID = false;
0348:                        dssIsChainedWithDiffID = true;
0349:                    }
0350:                    if ((gdsFormatter & DssConstants.DSSCHAIN_ERROR_CONTINUE) == DssConstants.DSSCHAIN_ERROR_CONTINUE)
0351:                        terminateChainOnErr = false;
0352:                    else
0353:                        terminateChainOnErr = true;
0354:                } else {
0355:                    // chaining bit not b'1', make sure DSSFMT same id not b'1'
0356:                    if ((gdsFormatter & DssConstants.DSSCHAIN_SAME_ID) == DssConstants.DSSCHAIN_SAME_ID) { // Next DSS can not have same correlator
0357:                        agent
0358:                                .throwSyntaxrm(
0359:                                        CodePoint.SYNERRCD_CHAIN_OFF_SAME_NEXT_CORRELATOR,
0360:                                        DRDAProtocolException.NO_CODPNT_ARG);
0361:                    }
0362:                    // chaining bit not b'1', make sure no error continuation
0363:                    if ((gdsFormatter & DssConstants.DSSCHAIN_ERROR_CONTINUE) == DssConstants.DSSCHAIN_ERROR_CONTINUE) { // must be 'do not continue on error'
0364:                        agent.throwSyntaxrm(
0365:                                CodePoint.SYNERRCD_CHAIN_OFF_ERROR_CONTINUE,
0366:                                DRDAProtocolException.NO_CODPNT_ARG);
0367:                    }
0368:
0369:                    dssIsChainedWithSameID = false;
0370:                    dssIsChainedWithDiffID = false;
0371:                }
0372:
0373:                dssCorrelationID = ((buffer[pos] & 0xff) << 8)
0374:                        + ((buffer[pos + 1] & 0xff) << 0);
0375:                pos += 2;
0376:                if (SanityManager.DEBUG)
0377:                    trace("dssLength = " + dssLength + " correlationID = "
0378:                            + dssCorrelationID);
0379:
0380:                //check that correlationID is the same as previous
0381:                if (prevCorrelationID != DssConstants.CORRELATION_ID_UNKNOWN
0382:                        && dssCorrelationID != prevCorrelationID) {
0383:                    agent.throwSyntaxrm(
0384:                            CodePoint.SYNERRCD_CHAIN_OFF_ERROR_CONTINUE,
0385:                            DRDAProtocolException.NO_CODPNT_ARG);
0386:                }
0387:
0388:                // set up previous correlation id to check that next DSS is correctly
0389:                // formatted
0390:                if (dssIsChainedWithSameID)
0391:                    prevCorrelationID = dssCorrelationID;
0392:                else
0393:                    prevCorrelationID = DssConstants.CORRELATION_ID_UNKNOWN;
0394:
0395:                dssLength -= 6;
0396:
0397:                return dssCorrelationID;
0398:            }
0399:
0400:            /**
0401:             * Read Reply DSS
0402:             * This is used in testing the protocol.  We shouldn't see a reply
0403:             * DSS when we are servicing DRDA commands
0404:             *
0405:             * @exception DRDProtocolException
0406:             */
0407:            protected void readReplyDss() throws DRDAProtocolException {
0408:                ensureALayerDataInBuffer(6);
0409:
0410:                // read out the DSS length
0411:                dssLength = ((buffer[pos++] & 0xff) << 8)
0412:                        + ((buffer[pos++] & 0xff) << 0);
0413:
0414:                // check for the continuation bit and update length as needed.
0415:                if ((dssLength & DssConstants.CONTINUATION_BIT) == DssConstants.CONTINUATION_BIT) {
0416:                    dssLength = DssConstants.MAX_DSS_LENGTH;
0417:                    dssIsContinued = true;
0418:                } else {
0419:                    dssIsContinued = false;
0420:                }
0421:
0422:                if (dssLength < 6)
0423:                    agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_LESS_THAN_6,
0424:                            DRDAProtocolException.NO_CODPNT_ARG);
0425:
0426:                // If the GDS id is not valid, throw exception
0427:
0428:                if ((buffer[pos++] & 0xff) != DssConstants.DSS_ID)
0429:                    agent.throwSyntaxrm(CodePoint.SYNERRCD_CBYTE_NOT_D0,
0430:                            DRDAProtocolException.NO_CODPNT_ARG);
0431:
0432:                int gdsFormatter = buffer[pos++] & 0xff;
0433:
0434:                // Determine if the current DSS is chained with the
0435:                // next DSS, with the same or different request ID.
0436:                if ((gdsFormatter & DssConstants.DSSCHAIN) == DssConstants.DSSCHAIN) { // on indicates structure chained to next structure
0437:                    if ((gdsFormatter & DssConstants.DSSCHAIN_SAME_ID) == DssConstants.DSSCHAIN_SAME_ID) {
0438:                        dssIsChainedWithSameID = true;
0439:                        dssIsChainedWithDiffID = false;
0440:                    } else {
0441:                        dssIsChainedWithSameID = false;
0442:                        dssIsChainedWithDiffID = true;
0443:                    }
0444:                } else {
0445:                    dssIsChainedWithSameID = false;
0446:                    dssIsChainedWithDiffID = false;
0447:                }
0448:
0449:                dssCorrelationID = ((buffer[pos++] & 0xff) << 8)
0450:                        + ((buffer[pos++] & 0xff) << 0);
0451:
0452:                if (SanityManager.DEBUG)
0453:                    trace("dssLength = " + dssLength + " correlationID = "
0454:                            + dssCorrelationID);
0455:
0456:                dssLength -= 6;
0457:
0458:            }
0459:
0460:            /**
0461:             * Read the DDM Length and CodePoint
0462:             *
0463:             * @return - returns codepoint
0464:             *
0465:             * @exception DRDProtocolException
0466:             */
0467:            protected int readLengthAndCodePoint() throws DRDAProtocolException {
0468:                ensureBLayerDataInBuffer(4, NO_ADJUST_LENGTHS);
0469:
0470:                ddmScalarLen = readCodePoint();
0471:                int codePoint = readCodePoint();
0472:
0473:                if (SanityManager.DEBUG)
0474:                    trace("length = " + ddmScalarLen + " codepoint = "
0475:                            + java.lang.Integer.toHexString(codePoint));
0476:                // SYNERRCD 0x0D - Object code point index not supported.
0477:                // the object codepoint index will not be checked here since
0478:                // the parse methods will catch any incorrect/unexpected codepoint values
0479:                // and report them as unsupported objects or parameters.
0480:
0481:                // Check if this DDM has extended length field
0482:                if ((ddmScalarLen & DssConstants.CONTINUATION_BIT) == DssConstants.CONTINUATION_BIT) {
0483:                    int numberOfExtendedLenBytes = ((int) ddmScalarLen - DssConstants.CONTINUATION_BIT) - 4;
0484:                    int adjustSize = 0;
0485:                    ensureBLayerDataInBuffer(numberOfExtendedLenBytes,
0486:                            NO_ADJUST_LENGTHS);
0487:                    switch (numberOfExtendedLenBytes) {
0488:                    case 8:
0489:                        ddmScalarLen = ((buffer[pos++] & 0xff) << 56)
0490:                                + ((buffer[pos++] & 0xff) << 48)
0491:                                + ((buffer[pos++] & 0xff) << 40)
0492:                                + ((buffer[pos++] & 0xff) << 32)
0493:                                + ((buffer[pos++] & 0xff) << 24)
0494:                                + ((buffer[pos++] & 0xff) << 16)
0495:                                + ((buffer[pos++] & 0xff) << 8)
0496:                                + ((buffer[pos++] & 0xff) << 0);
0497:                        adjustSize = 12;
0498:                        break;
0499:                    case 6:
0500:                        ddmScalarLen = ((buffer[pos++] & 0xff) << 40)
0501:                                + ((buffer[pos++] & 0xff) << 32)
0502:                                + ((buffer[pos++] & 0xff) << 24)
0503:                                + ((buffer[pos++] & 0xff) << 16)
0504:                                + ((buffer[pos++] & 0xff) << 8)
0505:                                + ((buffer[pos++] & 0xff) << 0);
0506:                        adjustSize = 10;
0507:                        break;
0508:                    case 4:
0509:                        ddmScalarLen = ((buffer[pos++] & 0xff) << 24)
0510:                                + ((buffer[pos++] & 0xff) << 16)
0511:                                + ((buffer[pos++] & 0xff) << 8)
0512:                                + ((buffer[pos++] & 0xff) << 0);
0513:                        adjustSize = 8;
0514:                        break;
0515:                    default:
0516:                        agent.throwSyntaxrm(
0517:                                CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN,
0518:                                DRDAProtocolException.NO_CODPNT_ARG);
0519:                    }
0520:
0521:                    // adjust the lengths here.	this is a special case since the
0522:                    // extended length bytes do not include their own length.
0523:                    for (int i = 0; i <= topDdmCollectionStack; i++) {
0524:                        ddmCollectionLenStack[i] -= adjustSize;
0525:                    }
0526:                    dssLength -= adjustSize;
0527:                } else {
0528:                    if (ddmScalarLen < 4)
0529:                        agent.throwSyntaxrm(
0530:                                CodePoint.SYNERRCD_OBJ_LEN_LESS_THAN_4,
0531:                                DRDAProtocolException.NO_CODPNT_ARG);
0532:                    adjustLengths(4);
0533:                }
0534:                return codePoint;
0535:            }
0536:
0537:            /**
0538:             * Read the CodePoint
0539:             *
0540:             * @return - returns codepoint
0541:             */
0542:            protected int readCodePoint() {
0543:                return (((buffer[pos++] & 0xff) << 8) + ((buffer[pos++] & 0xff) << 0));
0544:            }
0545:
0546:            /**
0547:             * Push DDM Length on to collection stack
0548:             */
0549:            protected void markCollection() {
0550:                ddmCollectionLenStack[++topDdmCollectionStack] = ddmScalarLen;
0551:                ddmScalarLen = 0;
0552:            }
0553:
0554:            /**
0555:             * 	Get the next CodePoint from a collection
0556:             * 	@return	NO_CODEPOINT if collection stack is empty or remaining length is
0557:             *		0; otherwise,  read length and code point
0558:             *
0559:             * @exception DRDProtocolException
0560:             */
0561:            protected int getCodePoint() throws DRDAProtocolException {
0562:                if (topDdmCollectionStack == EMPTY_STACK) {
0563:                    return NO_CODEPOINT;
0564:                } else {
0565:                    // if the collecion is exhausted then return NO_CODEPOINT
0566:                    if (ddmCollectionLenStack[topDdmCollectionStack] == 0) {
0567:                        // done with this collection so remove it's length from the stack
0568:                        ddmCollectionLenStack[topDdmCollectionStack--] = 0;
0569:                        return NO_CODEPOINT;
0570:                    } else {
0571:                        return readLengthAndCodePoint();
0572:                    }
0573:                }
0574:            }
0575:
0576:            /**
0577:             * Get the next CodePoint from a collection and check that it matches the specified
0578:             * 	CodePoint
0579:             * @param	codePointCheck	- codePoint to check against
0580:             * @return	codePoint
0581:             *
0582:             * @exception DRDProtocolException
0583:             */
0584:            protected int getCodePoint(int codePointCheck)
0585:                    throws DRDAProtocolException {
0586:                int codePoint = getCodePoint();
0587:                if (codePoint != codePointCheck)
0588:                    agent.missingCodePoint(codePoint);
0589:                return codePoint;
0590:            }
0591:
0592:            /**
0593:             * The following routines read different types from the input stream
0594:             * Data can be in network order or platform order depending on whether the
0595:             * data is part of the protocol or data being received
0596:             * The platform is determined by EXCSAT protocol
0597:             */
0598:
0599:            /**
0600:             * Read byte value
0601:             * @return	value
0602:             *
0603:             * @exception DRDProtocolException
0604:             */
0605:            protected byte readByte() throws DRDAProtocolException {
0606:                ensureBLayerDataInBuffer(1, ADJUST_LENGTHS);
0607:                return buffer[pos++];
0608:            }
0609:
0610:            /**
0611:             * Read byte value and mask out high order bytes before returning
0612:             * @return value
0613:             */
0614:            protected int readUnsignedByte() throws DRDAProtocolException {
0615:                ensureBLayerDataInBuffer(1, ADJUST_LENGTHS);
0616:                return (int) (buffer[pos++] & 0xff);
0617:            }
0618:
0619:            /**
0620:             * Read network short value
0621:             * @return	value
0622:             *
0623:             * @exception DRDProtocolException
0624:             */
0625:            protected int readNetworkShort() throws DRDAProtocolException {
0626:                ensureBLayerDataInBuffer(2, ADJUST_LENGTHS);
0627:                return ((buffer[pos++] & 0xff) << 8)
0628:                        + ((buffer[pos++] & 0xff) << 0);
0629:            }
0630:
0631:            /**
0632:             * Read signed network short value
0633:             * @return	value
0634:             *
0635:             * @exception DRDProtocolException
0636:             */
0637:            protected int readSignedNetworkShort() throws DRDAProtocolException {
0638:                ensureBLayerDataInBuffer(2, ADJUST_LENGTHS);
0639:                return (short) (((buffer[pos++] & 0xff) << 8) + ((buffer[pos++] & 0xff) << 0));
0640:            }
0641:
0642:            /**
0643:             * Read platform short value
0644:             * @return	value
0645:             *
0646:             * @exception DRDProtocolException
0647:             */
0648:            protected short readShort(int byteOrder)
0649:                    throws DRDAProtocolException {
0650:                ensureBLayerDataInBuffer(2, ADJUST_LENGTHS);
0651:                short s = SignedBinary.getShort(buffer, pos, byteOrder);
0652:
0653:                pos += 2;
0654:
0655:                return s;
0656:            }
0657:
0658:            /**
0659:             * Read network int value
0660:             * @return	value
0661:             *
0662:             * @exception DRDProtocolException
0663:             */
0664:            protected int readNetworkInt() throws DRDAProtocolException {
0665:                ensureBLayerDataInBuffer(4, ADJUST_LENGTHS);
0666:                return ((buffer[pos++] & 0xff) << 24)
0667:                        + ((buffer[pos++] & 0xff) << 16)
0668:                        + ((buffer[pos++] & 0xff) << 8)
0669:                        + ((buffer[pos++] & 0xff) << 0);
0670:            }
0671:
0672:            /**
0673:             * Read platform int value
0674:             * @return	value
0675:             *
0676:             * @exception DRDProtocolException
0677:             */
0678:            protected int readInt(int byteOrder) throws DRDAProtocolException {
0679:                ensureBLayerDataInBuffer(4, ADJUST_LENGTHS);
0680:                int i = SignedBinary.getInt(buffer, pos, byteOrder);
0681:
0682:                pos += 4;
0683:
0684:                return i;
0685:            }
0686:
0687:            /**
0688:             * Read network long value
0689:             * @return	value
0690:             *
0691:             * @exception DRDProtocolException
0692:             */
0693:            protected long readNetworkLong() throws DRDAProtocolException {
0694:                ensureBLayerDataInBuffer(8, ADJUST_LENGTHS);
0695:
0696:                return ((buffer[pos++] & 0xffL) << 56)
0697:                        + ((buffer[pos++] & 0xffL) << 48)
0698:                        + ((buffer[pos++] & 0xffL) << 40)
0699:                        + ((buffer[pos++] & 0xffL) << 32)
0700:                        + ((buffer[pos++] & 0xffL) << 24)
0701:                        + ((buffer[pos++] & 0xffL) << 16)
0702:                        + ((buffer[pos++] & 0xffL) << 8)
0703:                        + ((buffer[pos++] & 0xffL) << 0);
0704:            }
0705:
0706:            /**
0707:             * Read network six byte value and put it in a long v
0708:             * @return	value
0709:             *
0710:             * @exception DRDProtocolException
0711:             */
0712:            protected long readNetworkSixByteLong()
0713:                    throws DRDAProtocolException {
0714:                ensureBLayerDataInBuffer(6, ADJUST_LENGTHS);
0715:
0716:                return (((buffer[pos++] & 0xffL) << 40)
0717:                        + ((buffer[pos++] & 0xffL) << 32)
0718:                        + ((buffer[pos++] & 0xffL) << 24)
0719:                        + ((buffer[pos++] & 0xffL) << 16)
0720:                        + ((buffer[pos++] & 0xffL) << 8) + ((buffer[pos++] & 0xffL) << 0));
0721:            }
0722:
0723:            /**
0724:             * Read platform long value
0725:             * @return	value
0726:             *
0727:             * @exception DRDProtocolException
0728:             */
0729:            protected long readLong(int byteOrder) throws DRDAProtocolException {
0730:                ensureBLayerDataInBuffer(8, ADJUST_LENGTHS);
0731:                long l = SignedBinary.getLong(buffer, pos, byteOrder);
0732:
0733:                pos += 8;
0734:
0735:                return l;
0736:            }
0737:
0738:            /**
0739:             * Read platform float value
0740:             * @return	value
0741:             *
0742:             * @exception DRDProtocolException
0743:             */
0744:            protected float readFloat(int byteOrder)
0745:                    throws DRDAProtocolException {
0746:                return Float.intBitsToFloat(readInt(byteOrder));
0747:            }
0748:
0749:            /**
0750:             * Read platform double value
0751:             * @return	value
0752:             *
0753:             * @exception DRDProtocolException
0754:             */
0755:            protected double readDouble(int byteOrder)
0756:                    throws DRDAProtocolException {
0757:                return Double.longBitsToDouble(readLong(byteOrder));
0758:            }
0759:
0760:            /**
0761:             * Read a BigDecimal value
0762:             * @param	precision of the BigDecimal
0763:             * @param	scale of the BigDecimal
0764:             * @return	value
0765:             *
0766:             * @exception DRDProtocolException
0767:             */
0768:            protected BigDecimal readBigDecimal(int precision, int scale)
0769:                    throws DRDAProtocolException {
0770:                // The byte-length of a packed decimal with precision p is always p/2 + 1
0771:                int length = precision / 2 + 1;
0772:
0773:                ensureBLayerDataInBuffer(length, ADJUST_LENGTHS);
0774:
0775:                // check for sign.
0776:                int signum;
0777:                if ((buffer[pos + length - 1] & 0x0F) == 0x0D)
0778:                    signum = -1;
0779:                else
0780:                    signum = 1;
0781:
0782:                if (precision <= 9) {
0783:                    // can be handled by int without overflow.
0784:                    int value = packedNybblesToInt(buffer, pos, 0,
0785:                            length * 2 - 1);
0786:
0787:                    // convert value to a byte array of magnitude.
0788:                    byte[] magnitude = new byte[4];
0789:                    magnitude[0] = (byte) (value >>> 24);
0790:                    magnitude[1] = (byte) (value >>> 16);
0791:                    magnitude[2] = (byte) (value >>> 8);
0792:                    magnitude[3] = (byte) (value);
0793:
0794:                    pos += length;
0795:                    return new java.math.BigDecimal(new java.math.BigInteger(
0796:                            signum, magnitude), scale);
0797:                } else if (precision <= 18) {
0798:                    // can be handled by long without overflow.
0799:                    long value = packedNybblesToLong(buffer, pos, 0,
0800:                            length * 2 - 1);
0801:
0802:                    // convert value to a byte array of magnitude.
0803:                    byte[] magnitude = new byte[8];
0804:                    magnitude[0] = (byte) (value >>> 56);
0805:                    magnitude[1] = (byte) (value >>> 48);
0806:                    magnitude[2] = (byte) (value >>> 40);
0807:                    magnitude[3] = (byte) (value >>> 32);
0808:                    magnitude[4] = (byte) (value >>> 24);
0809:                    magnitude[5] = (byte) (value >>> 16);
0810:                    magnitude[6] = (byte) (value >>> 8);
0811:                    magnitude[7] = (byte) (value);
0812:
0813:                    pos += length;
0814:                    return new java.math.BigDecimal(new java.math.BigInteger(
0815:                            signum, magnitude), scale);
0816:                } else if (precision <= 27) {
0817:                    // get the value of last 9 digits (5 bytes).
0818:                    int lo = packedNybblesToInt(buffer, pos, (length - 5) * 2,
0819:                            9);
0820:                    // get the value of another 9 digits (5 bytes).
0821:                    int me = packedNybblesToInt(buffer, pos,
0822:                            (length - 10) * 2 + 1, 9);
0823:                    // get the value of the rest digits.
0824:                    int hi = packedNybblesToInt(buffer, pos, 0,
0825:                            (length - 10) * 2 + 1);
0826:
0827:                    // compute the int array of magnitude.
0828:                    int[] value = computeMagnitude(new int[] { hi, me, lo });
0829:
0830:                    // convert value to a byte array of magnitude.
0831:                    byte[] magnitude = new byte[12];
0832:                    magnitude[0] = (byte) (value[0] >>> 24);
0833:                    magnitude[1] = (byte) (value[0] >>> 16);
0834:                    magnitude[2] = (byte) (value[0] >>> 8);
0835:                    magnitude[3] = (byte) (value[0]);
0836:                    magnitude[4] = (byte) (value[1] >>> 24);
0837:                    magnitude[5] = (byte) (value[1] >>> 16);
0838:                    magnitude[6] = (byte) (value[1] >>> 8);
0839:                    magnitude[7] = (byte) (value[1]);
0840:                    magnitude[8] = (byte) (value[2] >>> 24);
0841:                    magnitude[9] = (byte) (value[2] >>> 16);
0842:                    magnitude[10] = (byte) (value[2] >>> 8);
0843:                    magnitude[11] = (byte) (value[2]);
0844:
0845:                    pos += length;
0846:                    return new java.math.BigDecimal(new java.math.BigInteger(
0847:                            signum, magnitude), scale);
0848:                } else if (precision <= 31) {
0849:                    // get the value of last 9 digits (5 bytes).
0850:                    int lo = packedNybblesToInt(buffer, pos, (length - 5) * 2,
0851:                            9);
0852:                    // get the value of another 9 digits (5 bytes).
0853:                    int meLo = packedNybblesToInt(buffer, pos,
0854:                            (length - 10) * 2 + 1, 9);
0855:                    // get the value of another 9 digits (5 bytes).
0856:                    int meHi = packedNybblesToInt(buffer, pos,
0857:                            (length - 14) * 2, 9);
0858:                    // get the value of the rest digits.
0859:                    int hi = packedNybblesToInt(buffer, pos, 0,
0860:                            (length - 14) * 2);
0861:
0862:                    // compute the int array of magnitude.
0863:                    int[] value = computeMagnitude(new int[] { hi, meHi, meLo,
0864:                            lo });
0865:
0866:                    // convert value to a byte array of magnitude.
0867:                    byte[] magnitude = new byte[16];
0868:                    magnitude[0] = (byte) (value[0] >>> 24);
0869:                    magnitude[1] = (byte) (value[0] >>> 16);
0870:                    magnitude[2] = (byte) (value[0] >>> 8);
0871:                    magnitude[3] = (byte) (value[0]);
0872:                    magnitude[4] = (byte) (value[1] >>> 24);
0873:                    magnitude[5] = (byte) (value[1] >>> 16);
0874:                    magnitude[6] = (byte) (value[1] >>> 8);
0875:                    magnitude[7] = (byte) (value[1]);
0876:                    magnitude[8] = (byte) (value[2] >>> 24);
0877:                    magnitude[9] = (byte) (value[2] >>> 16);
0878:                    magnitude[10] = (byte) (value[2] >>> 8);
0879:                    magnitude[11] = (byte) (value[2]);
0880:                    magnitude[12] = (byte) (value[3] >>> 24);
0881:                    magnitude[13] = (byte) (value[3] >>> 16);
0882:                    magnitude[14] = (byte) (value[3] >>> 8);
0883:                    magnitude[15] = (byte) (value[3]);
0884:
0885:                    pos += length;
0886:                    return new java.math.BigDecimal(new java.math.BigInteger(
0887:                            signum, magnitude), scale);
0888:                } else {
0889:                    pos += length;
0890:                    // throw an exception here if nibbles is greater than 31
0891:                    throw new java.lang.IllegalArgumentException(
0892:                            "Decimal may only be up to 31 digits!");
0893:                }
0894:            }
0895:
0896:            byte[] getExtData(boolean checkNullability)
0897:                    throws DRDAProtocolException {
0898:                return getExtData(ddmScalarLen, checkNullability);
0899:            }
0900:
0901:            /**
0902:             * Creates an InputStream which can stream EXTDTA objects.
0903:             * The InputStream uses this DDMReader to read data from network. The 
0904:             * DDMReader should not be used before all data in the stream has been read.
0905:             * @param checkNullability used to check if the stream is null. If it is 
0906:             * null, this method returns null
0907:             * @return EXTDTAReaderInputStream object which can be passed to prepared
0908:             *         statement as a binary stream.
0909:             * @exception DRDAProtocolException standard DRDA protocol exception
0910:             */
0911:            EXTDTAReaderInputStream getEXTDTAReaderInputStream(
0912:                    final boolean checkNullability)
0913:                    throws DRDAProtocolException {
0914:                if (checkNullability && isEXTDTANull()) {
0915:                    return null;
0916:                } else {
0917:                    return new EXTDTAReaderInputStream(this );
0918:                }
0919:            }
0920:
0921:            /**
0922:             * This method is used by EXTDTAReaderInputStream to read the first chunk 
0923:             * of data.
0924:             * @param desiredLength the desired length of chunk
0925:             * @exception DRDAProtocolException standard DRDA protocol exception
0926:             */
0927:            ByteArrayInputStream readLOBInitStream(final long desiredLength)
0928:                    throws DRDAProtocolException {
0929:                return readLOBChunk(false, desiredLength);
0930:            }
0931:
0932:            /**
0933:             * This method is used by EXTDTAReaderInputStream to read the next chunk 
0934:             * of data.
0935:             * @param desiredLength the desired length of chunk
0936:             * @exception IOException IOException
0937:             */
0938:            ByteArrayInputStream readLOBContinuationStream(
0939:                    final long desiredLength) throws IOException {
0940:                try {
0941:                    return readLOBChunk(true, desiredLength);
0942:                } catch (DRDAProtocolException e) {
0943:                    e.printStackTrace(agent.getServer().logWriter);
0944:                    throw new IOException(e.getMessage());
0945:                }
0946:            }
0947:
0948:            /**
0949:             * This method is used by EXTDTAReaderInputStream to read the next chunk 
0950:             * of data.
0951:             * @param readHeader set to true if the dss continuation should be read
0952:             * @param desiredLength the desired length of chunk
0953:             * @exception DRDAProtocolException standard DRDA protocol exception
0954:             */
0955:            private ByteArrayInputStream readLOBChunk(final boolean readHeader,
0956:                    final long desiredLength) throws DRDAProtocolException {
0957:                if (readHeader) {
0958:                    readDSSContinuationHeader();
0959:                }
0960:                int copySize = (int) Math.min(dssLength, desiredLength);
0961:
0962:                // read the segment
0963:                ensureALayerDataInBuffer(copySize);
0964:                adjustLengths(copySize);
0965:
0966:                // Create ByteArrayInputStream on top of buffer. 
0967:                // This will not make a copy of the buffer.
0968:                ByteArrayInputStream bais = new ByteArrayInputStream(buffer,
0969:                        pos, copySize);
0970:                pos += copySize;
0971:
0972:                return bais;
0973:            }
0974:
0975:            byte[] getExtData(long desiredLength, boolean checkNullability)
0976:                    throws DRDAProtocolException {
0977:                boolean readHeader;
0978:                int copySize;
0979:                ByteArrayOutputStream baos;
0980:                boolean isLengthAndNullabilityUnknown = false;
0981:
0982:                if (desiredLength != -1) {
0983:                    // allocate a stream based on a known amount of data
0984:                    baos = new ByteArrayOutputStream((int) desiredLength);
0985:                } else {
0986:                    // allocate a stream to hold an unknown amount of data
0987:                    baos = new ByteArrayOutputStream();
0988:                    //isLengthAndNullabilityUnknown = true;
0989:                    // If we aren't given a  length get the whole thing.
0990:                    desiredLength = MAX_EXTDTA_SIZE;
0991:                }
0992:
0993:                // check for a null EXTDTA value, if it is nullable and if streaming
0994:                if (checkNullability)
0995:                    if (isEXTDTANull())
0996:                        return null;
0997:
0998:                // set the amount to read for the first segment
0999:                copySize = (int) Math.min(dssLength, desiredLength); //note: has already been adjusted for headers
1000:
1001:                //if (checkNullability)  // don't count the null byte we've already read
1002:                //copySize--;
1003:
1004:                do {
1005:                    // determine if a continuation header needs to be read after the data
1006:                    if (dssIsContinued)
1007:                        readHeader = true;
1008:                    else
1009:                        readHeader = false;
1010:
1011:                    // read the segment
1012:                    ensureALayerDataInBuffer(copySize);
1013:                    adjustLengths(copySize);
1014:                    baos.write(buffer, pos, copySize);
1015:                    pos += copySize;
1016:                    desiredLength -= copySize;
1017:
1018:                    // read the continuation header, if necessary
1019:                    if (readHeader)
1020:                        readDSSContinuationHeader();
1021:
1022:                    copySize = (int) Math.min(dssLength, desiredLength); //note: has already been adjusted for headers
1023:
1024:                } while (readHeader == true && desiredLength > 0);
1025:
1026:                return baos.toByteArray();
1027:            }
1028:
1029:            // reads a DSS continuation header
1030:            // prereq: pos is positioned on the first byte of the two-byte header
1031:            // post:   dssIsContinued is set to true if the continuation bit is on, false otherwise
1032:            //         dssLength is set to DssConstants.MAXDSS_LEN - 2 (don't count the header for the next read)
1033:            // helper method for getEXTDTAData
1034:            private void readDSSContinuationHeader()
1035:                    throws DRDAProtocolException {
1036:                ensureALayerDataInBuffer(2);
1037:
1038:                dssLength = ((buffer[pos++] & 0xFF) << 8)
1039:                        + ((buffer[pos++] & 0xFF) << 0);
1040:
1041:                if ((dssLength & 0x8000) == 0x8000) {
1042:                    dssLength = DssConstants.MAX_DSS_LENGTH;
1043:                    dssIsContinued = true;
1044:                } else {
1045:                    dssIsContinued = false;
1046:                }
1047:                // it is a syntax error if the dss continuation header length
1048:                // is less than or equal to two
1049:                if (dssLength <= 2) {
1050:                    agent.throwSyntaxrm(
1051:                            CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2,
1052:                            DRDAProtocolException.NO_CODPNT_ARG);
1053:                }
1054:
1055:                dssLength -= 2; // avoid consuming the DSS cont header
1056:            }
1057:
1058:            // checks the null EXTDTA byte
1059:            // returns true if null, false otherwise
1060:            // helper method for getEXTDTAData
1061:            private boolean isEXTDTANull() throws DRDAProtocolException {
1062:                // make sure that the null byte is in the buffer
1063:                ensureALayerDataInBuffer(1);
1064:                adjustLengths(1);
1065:
1066:                // examine the null byte
1067:                byte nullByte = buffer[pos++];
1068:                if (nullByte == (byte) 0x00)
1069:                    return false;
1070:
1071:                return true;
1072:            }
1073:
1074:            /**
1075:             * Convert a range of packed nybbles (up to 9 digits without overflow) to an int.
1076:             * Note that for performance purpose, it does not do array-out-of-bound checking.
1077:             * @param buffer			buffer to read from
1078:             * @param offset			offset in the buffer
1079:             * @param startNybble		start nybble
1080:             * @param numberOfNybbles	number of nybbles
1081:             * @return	an int value
1082:             */
1083:            private int packedNybblesToInt(byte[] buffer, int offset,
1084:                    int startNybble, int numberOfNybbles) {
1085:                int value = 0;
1086:
1087:                int i = startNybble / 2;
1088:                if ((startNybble % 2) != 0) {
1089:                    // process low nybble of the first byte if necessary.
1090:                    value += buffer[offset + i] & 0x0F;
1091:                    i++;
1092:                }
1093:
1094:                int endNybble = startNybble + numberOfNybbles - 1;
1095:                for (; i < (endNybble + 1) / 2; i++) {
1096:                    value = value * 10 + ((buffer[offset + i] & 0xF0) >>> 4); // high nybble.
1097:                    value = value * 10 + (buffer[offset + i] & 0x0F); // low nybble.
1098:                }
1099:
1100:                if ((endNybble % 2) == 0) {
1101:                    // process high nybble of the last byte if necessary.
1102:                    value = value * 10 + ((buffer[offset + i] & 0xF0) >>> 4);
1103:                }
1104:
1105:                return value;
1106:            }
1107:
1108:            /**
1109:             * Convert a range of packed nybbles (up to 18 digits without overflow) to a long.
1110:             * Note that for performance purpose, it does not do array-out-of-bound checking.
1111:             * @param buffer		buffer to read from
1112:             * @param offset		offset in the buffer
1113:             * @param startNybble		start nybble
1114:             * @param numberOfNybbles	number of nybbles
1115:             * @return	an long value
1116:             */
1117:            private long packedNybblesToLong(byte[] buffer, int offset,
1118:                    int startNybble, int numberOfNybbles) {
1119:                long value = 0;
1120:
1121:                int i = startNybble / 2;
1122:                if ((startNybble % 2) != 0) {
1123:                    // process low nybble of the first byte if necessary.
1124:                    value += buffer[offset + i] & 0x0F;
1125:                    i++;
1126:                }
1127:
1128:                int endNybble = startNybble + numberOfNybbles - 1;
1129:                for (; i < (endNybble + 1) / 2; i++) {
1130:                    value = value * 10 + ((buffer[offset + i] & 0xF0) >>> 4); // high nybble.
1131:                    value = value * 10 + (buffer[offset + i] & 0x0F); // low nybble.
1132:                }
1133:
1134:                if ((endNybble % 2) == 0) {
1135:                    // process high nybble of the last byte if necessary.
1136:                    value = value * 10 + ((buffer[offset + i] & 0xF0) >>> 4);
1137:                }
1138:
1139:                return value;
1140:            }
1141:
1142:            /**
1143:             * Compute the int array of magnitude from input value segments.
1144:             * @param	input value segments
1145:             * @return	array of int magnitudes
1146:             */
1147:            private int[] computeMagnitude(int[] input) {
1148:                int length = input.length;
1149:                int[] mag = new int[length];
1150:
1151:                mag[length - 1] = input[length - 1];
1152:                for (int i = 0; i < length - 1; i++) {
1153:                    int carry = 0;
1154:                    int j = tenRadixMagnitude[i].length - 1;
1155:                    int k = length - 1;
1156:                    for (; j >= 0; j--, k--) {
1157:                        long product = (input[length - 2 - i] & 0xFFFFFFFFL)
1158:                                * (tenRadixMagnitude[i][j] & 0xFFFFFFFFL)
1159:                                + (mag[k] & 0xFFFFFFFFL) // add previous value
1160:                                + (carry & 0xFFFFFFFFL); // add carry
1161:                        carry = (int) (product >>> 32);
1162:                        mag[k] = (int) (product & 0xFFFFFFFFL);
1163:                    }
1164:                    mag[k] = (int) carry;
1165:                }
1166:                return mag;
1167:            }
1168:
1169:            /**
1170:             * Read boolean value
1171:             * @return	value
1172:             *
1173:             * @exception DRDProtocolException
1174:             */
1175:            protected boolean readBoolean() throws DRDAProtocolException {
1176:                ensureBLayerDataInBuffer(1, ADJUST_LENGTHS);
1177:                return buffer[pos++] != 0;
1178:            }
1179:
1180:            /**
1181:             * Read encrypted string
1182:             * @param   decryptM  decryption manager
1183:             * @param   securityMechanism security mechanism
1184:             * @param   initVector   initialization vector for cipher
1185:             * @param   sourcePublicKey  public key (as in Deffie-Hellman algorithm)
1186:             *                           from source (encryptor)
1187:             * @return  decrypted string
1188:             *
1189:             * @exception DRDProtocolException, SQLException(wrapping any exception in decryption)
1190:             */
1191:            protected String readEncryptedString(DecryptionManager decryptM,
1192:                    int securityMechanism, byte[] initVector,
1193:                    byte[] sourcePublicKey) throws DRDAProtocolException,
1194:                    java.sql.SQLException {
1195:                byte[] cipherText = readBytes();
1196:                byte[] plainText = null;
1197:                plainText = decryptM.decryptData(cipherText, securityMechanism,
1198:                        initVector, sourcePublicKey);
1199:                if (plainText == null)
1200:                    return null;
1201:                else
1202:                    return ccsidManager.convertToUCS2(plainText);
1203:            }
1204:
1205:            /**
1206:             * Read string value
1207:             * Strings in DRDA protocol are encoded in EBCDIC by default so we
1208:             * need to convert to UCS2
1209:             * @param length  - length of string to read
1210:             * @return value
1211:             *
1212:             * @exception DRDProtocolException
1213:             */
1214:            protected String readString(int length)
1215:                    throws DRDAProtocolException {
1216:                ensureBLayerDataInBuffer(length, ADJUST_LENGTHS);
1217:
1218:                String result = ccsidManager.convertToUCS2(buffer, pos, length);
1219:                pos += length;
1220:                return result;
1221:            }
1222:
1223:            /**
1224:             * Read string value into a <code>DRDAString</code> object.
1225:             *
1226:             * @param dst  destination for the read string
1227:             * @param size size (in bytes) of string to read
1228:             * @param unpad if true, remove padding (trailing spaces)
1229:             *
1230:             * @exception DRDAProtocolException
1231:             */
1232:            protected void readString(DRDAString dst, int size, boolean unpad)
1233:                    throws DRDAProtocolException {
1234:                ensureBLayerDataInBuffer(size, ADJUST_LENGTHS);
1235:                int startPos = pos;
1236:                pos += size;
1237:                if (unpad) {
1238:                    while ((size > 0)
1239:                            && (buffer[startPos + size - 1] == ccsidManager.space)) {
1240:                        --size;
1241:                    }
1242:                }
1243:                dst.setBytes(buffer, startPos, size);
1244:            }
1245:
1246:            /**
1247:             * Read encoded string value
1248:             * @param length  - length of string to read
1249:             * @return value
1250:             *
1251:             * @exception DRDProtocolException
1252:             */
1253:            protected String readString(int length, String encoding)
1254:                    throws DRDAProtocolException {
1255:                ensureBLayerDataInBuffer(length, ADJUST_LENGTHS);
1256:                String s = null;
1257:
1258:                try {
1259:                    s = new String(buffer, pos, length, encoding);
1260:                } catch (java.io.UnsupportedEncodingException e) {
1261:                    agent
1262:                            .agentError("UnsupportedEncodingException in readString, encoding = "
1263:                                    + encoding);
1264:                    e.printStackTrace(agent.getServer().logWriter);
1265:                }
1266:
1267:                pos += length;
1268:                return s;
1269:            }
1270:
1271:            /**
1272:             * Read string value in DDM data with default encoding
1273:             * @return value
1274:             *
1275:             * @exception DRDProtocolException
1276:             */
1277:            protected String readStringData() throws DRDAProtocolException {
1278:                return readString((int) ddmScalarLen,
1279:                        NetworkServerControlImpl.DEFAULT_ENCODING);
1280:            }
1281:
1282:            /**
1283:             * Read specified length of string value in DDM data with default encoding
1284:             * @param length  - length of string to read
1285:             * @return value
1286:             *
1287:             * @exception DRDProtocolException
1288:             */
1289:            protected String readStringData(int length)
1290:                    throws DRDAProtocolException {
1291:                return readString(length,
1292:                        NetworkServerControlImpl.DEFAULT_ENCODING);
1293:            }
1294:
1295:            /**
1296:             * Read length delimited string value in DDM data with default encoding
1297:             * @return value
1298:             *
1299:             * @exception DRDProtocolException
1300:             */
1301:            protected String readLDStringData(String encoding)
1302:                    throws DRDAProtocolException {
1303:                int length = readNetworkShort();
1304:                return readString(length, encoding);
1305:            }
1306:
1307:            /**
1308:             * Read string value
1309:             *
1310:             * @exception DRDProtocolException
1311:             */
1312:            protected String readString() throws DRDAProtocolException {
1313:                return readString((int) ddmScalarLen);
1314:            }
1315:
1316:            /**
1317:             * Read byte string value
1318:             * @param length  - length of string to read
1319:             * @return byte array
1320:             *
1321:             * @exception DRDProtocolException
1322:             */
1323:            protected byte[] readBytes(int length) throws DRDAProtocolException {
1324:                byte[] b;
1325:
1326:                if (length < DssConstants.MAX_DSS_LENGTH) {
1327:                    ensureBLayerDataInBuffer(length, ADJUST_LENGTHS);
1328:                    b = new byte[length];
1329:                    System.arraycopy(buffer, pos, b, 0, length);
1330:                    pos += length;
1331:                } else
1332:                    b = getExtData(length, false);
1333:                return b;
1334:            }
1335:
1336:            /**
1337:             * Read byte string value
1338:             * @return byte array
1339:             *
1340:             * @exception DRDProtocolException
1341:             */
1342:            protected byte[] readBytes() throws DRDAProtocolException {
1343:                return readBytes((int) ddmScalarLen);
1344:            }
1345:
1346:            /**
1347:             * Skip byte string value
1348:             * @param length  - length of string to skip
1349:             *
1350:             * @exception DRDProtocolException
1351:             */
1352:            protected void skipBytes(int length) throws DRDAProtocolException {
1353:                ensureBLayerDataInBuffer(length, ADJUST_LENGTHS);
1354:                pos += length;
1355:            }
1356:
1357:            /**
1358:             * Skip byte string value
1359:             *
1360:             * @exception DRDAProtocolException
1361:             */
1362:            protected void skipBytes() throws DRDAProtocolException {
1363:                skipBytes((int) ddmScalarLen);
1364:            }
1365:
1366:            /**
1367:             * Skip remaining DSS
1368:             *
1369:             * @exception DRDAProtocolException
1370:             */
1371:            protected void skipDss() throws DRDAProtocolException {
1372:                while (dssIsContinued) {
1373:                    skipBytes((int) dssLength);
1374:                    readDSSContinuationHeader();
1375:                }
1376:                skipBytes((int) dssLength);
1377:                topDdmCollectionStack = EMPTY_STACK;
1378:                ddmScalarLen = 0;
1379:                dssLength = 0;
1380:
1381:            }
1382:
1383:            protected void clearBuffer() throws DRDAProtocolException {
1384:                skipBytes(java.lang.Math.min(dssLength, count - pos));
1385:                dssIsChainedWithSameID = false;
1386:                dssIsChainedWithDiffID = false;
1387:            }
1388:
1389:            /**
1390:             * Convert EBCDIC byte array to unicode string
1391:             *
1392:             * @param 	buf	- byte array
1393:             * @return string
1394:             */
1395:            protected String convertBytes(byte[] buf) {
1396:                return ccsidManager.convertToUCS2(buf, 0, buf.length);
1397:            }
1398:
1399:            // Private methods
1400:            /**
1401:             * Adjust remaining length
1402:             *
1403:             * @param length - adjustment length
1404:             */
1405:            private void adjustLengths(int length) {
1406:                ddmScalarLen -= length;
1407:                for (int i = 0; i <= topDdmCollectionStack; i++) {
1408:                    ddmCollectionLenStack[i] -= length;
1409:                }
1410:                dssLength -= length;
1411:            }
1412:
1413:            /********************************************************************/
1414:            /*   NetworkServerControl  command protocol reading routines        
1415:             */
1416:            /********************************************************************/
1417:            /**
1418:             * Read string value
1419:             * @param length  - length of string to read
1420:             * @return value
1421:             *
1422:             * @exception DRDProtocolException
1423:             */
1424:            protected String readCmdString(int length)
1425:                    throws DRDAProtocolException,
1426:                    java.io.UnsupportedEncodingException {
1427:                if (length == 0)
1428:                    return null;
1429:
1430:                ensureBLayerDataInBuffer(length, ADJUST_LENGTHS);
1431:                String result = new String(buffer, pos, length,
1432:                        NetworkServerControlImpl.DEFAULT_ENCODING);
1433:                pos += length;
1434:                return result;
1435:            }
1436:
1437:            /**
1438:             * Read string value
1439:             * @return value
1440:             *
1441:             * @exception DRDProtocolException
1442:             */
1443:            protected String readCmdString() throws DRDAProtocolException,
1444:                    java.io.UnsupportedEncodingException {
1445:                int length = readNetworkShort();
1446:                return readCmdString(length);
1447:
1448:            }
1449:
1450:            /**************************************************************************/
1451:            /*   Private methods
1452:            /**************************************************************************/
1453:            /**
1454:             * Make sure a certain amount of Layer A data is in the buffer.
1455:             * The data will be in the buffer after this method is called.
1456:             *
1457:             * @param desiredDataSize - amount of data we need
1458:             *
1459:             * @exception	DRDAProtocolException
1460:             */
1461:            private void ensureALayerDataInBuffer(int desiredDataSize)
1462:                    throws DRDAProtocolException {
1463:                // calulate the the number of bytes in the buffer.
1464:                int avail = count - pos;
1465:
1466:                // read more bytes off the network if the data is not in the buffer already.
1467:                if (avail < desiredDataSize) {
1468:                    fill(desiredDataSize - avail);
1469:                }
1470:            }
1471:
1472:            /**
1473:             * Make sure a certain amount of Layer B data is in the buffer.
1474:             * The data will be in the buffer after this method is called.
1475:             *
1476:             * @param desiredDataSize - amount of data we need
1477:             * @param adjustLen	- whether to adjust the remaining lengths
1478:             *
1479:             * @exception DRDProtocolException
1480:             */
1481:            private void ensureBLayerDataInBuffer(int desiredDataSize,
1482:                    boolean adjustLen) throws DRDAProtocolException {
1483:                ensureALayerDataInBuffer(desiredDataSize);
1484:                if (dssIsContinued) {
1485:                    if (desiredDataSize > dssLength) {
1486:                        int continueDssHeaderCount = (((desiredDataSize - dssLength) / DssConstants.MAX_DSS_LENGTH) + 1);
1487:                        compressBLayerData(continueDssHeaderCount);
1488:                    }
1489:                }
1490:                if (adjustLen)
1491:                    adjustLengths(desiredDataSize);
1492:            }
1493:
1494:            /**
1495:             * Compress B Layer data if extended total length is used
1496:             * by removing the continuation headers
1497:             *
1498:             * @param continueDssHeaderCount - amount of data we need
1499:             *
1500:             * @exception	throws DRDAProtocolException
1501:             */
1502:            private void compressBLayerData(int continueDssHeaderCount)
1503:                    throws DRDAProtocolException {
1504:
1505:                // jump to the last continuation header.
1506:                int tempPos = 0;
1507:                for (int i = 0; i < continueDssHeaderCount; i++) {
1508:                    // the first may be less than the size of a full DSS
1509:                    if (i == 0) {
1510:                        // only jump by the number of bytes remaining in the current DSS
1511:                        tempPos = pos + dssLength;
1512:                    } else {
1513:                        // all other jumps are for a full continued DSS
1514:                        tempPos += DssConstants.MAX_DSS_LENGTH;
1515:                    }
1516:                }
1517:
1518:                // for each of the DSS headers to remove,
1519:                // read out the continuation header and increment the DSS length by the
1520:                // size of the continuation bytes,	then shift the continuation data as needed.
1521:                int shiftSize = 0;
1522:                int bytesToShift = 0;
1523:                int continueHeaderLength = 0;
1524:                int newdssLength = 0;
1525:
1526:                for (int i = 0; i < continueDssHeaderCount; i++) {
1527:                    continueHeaderLength = ((buffer[tempPos] & 0xff) << 8)
1528:                            + ((buffer[tempPos + 1] & 0xff) << 0);
1529:
1530:                    if (i == 0) {
1531:                        // if this is the last one (farthest down stream and first to strip out)
1532:
1533:                        if ((continueHeaderLength & DssConstants.CONTINUATION_BIT) == DssConstants.CONTINUATION_BIT) {
1534:                            // the last DSS header is again continued
1535:                            continueHeaderLength = DssConstants.MAX_DSS_LENGTH;
1536:                            dssIsContinued = true;
1537:                        } else {
1538:                            // the last DSS header was not contiued so update continue state flag
1539:                            dssIsContinued = false;
1540:                        }
1541:                        // the very first shift size is 2
1542:                        shiftSize = 2;
1543:                    } else {
1544:                        // already removed the last header so make sure the chaining flag is on
1545:                        if ((continueHeaderLength & DssConstants.CONTINUATION_BIT) == DssConstants.CONTINUATION_BIT) {
1546:                            continueHeaderLength = DssConstants.MAX_DSS_LENGTH;
1547:                        } else {
1548:                            // this is a syntax error but not really certain which one.
1549:                            // for now pick 0x02 which is DSS header Length does not 
1550:                            // match the number
1551:                            // of bytes of data found.
1552:                            agent
1553:                                    .throwSyntaxrm(
1554:                                            CodePoint.SYNERRCD_DSS_LENGTH_BYTE_NUMBER_MISMATCH,
1555:                                            DRDAProtocolException.NO_CODPNT_ARG);
1556:                        }
1557:                        // increase the shift size by 2
1558:                        shiftSize += 2;
1559:                    }
1560:
1561:                    // it is a syntax error if the DSS continuation is less 
1562:                    // than or equal to two
1563:                    if (continueHeaderLength <= 2) {
1564:                        agent.throwSyntaxrm(
1565:                                CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2,
1566:                                DRDAProtocolException.NO_CODPNT_ARG);
1567:                    }
1568:
1569:                    newdssLength += (continueHeaderLength - 2);
1570:
1571:                    // calculate the number of bytes to shift
1572:                    if (i != (continueDssHeaderCount - 1))
1573:                        bytesToShift = DssConstants.MAX_DSS_LENGTH;
1574:                    else
1575:                        bytesToShift = dssLength;
1576:
1577:                    tempPos -= (bytesToShift - 2);
1578:                    System.arraycopy(buffer, tempPos - shiftSize, buffer,
1579:                            tempPos, bytesToShift);
1580:                }
1581:                // reposition the start of the data after the final DSS shift.
1582:                pos = tempPos;
1583:                dssLength += newdssLength;
1584:            }
1585:
1586:            /**
1587:             * Methods to manage the data buffer.
1588:             * Methods orginally from JCC
1589:             * RESOLVE: need to check if this is the best performing way of doing this
1590:             */
1591:
1592:            /**
1593:             * This is a helper method which shifts the buffered bytes from
1594:             * wherever they are in the current buffer to the beginning of
1595:             * different buffer (note these buffers could be the same).
1596:             * State information is updated as needed after the shift.
1597:             * @param destinationBuffer - buffer to shift data to
1598:             */
1599:            private void shiftBuffer(byte[] destinationBuffer) {
1600:                // calculate the size of the data in the current buffer.
1601:                int sz = count - pos;
1602:                if (SanityManager.DEBUG) {
1603:                    if ((sz < 0 || pos < 0)) {
1604:                        SanityManager
1605:                                .THROWASSERT("Unexpected data size or position. sz="
1606:                                        + sz
1607:                                        + " count="
1608:                                        + count
1609:                                        + " pos="
1610:                                        + pos);
1611:                    }
1612:                }
1613:
1614:                // copy this data to the new buffer startsing at position 0.
1615:                System.arraycopy(buffer, pos, destinationBuffer, 0, sz);
1616:
1617:                // update the state information for data in the new buffer.
1618:                pos = 0;
1619:                count = sz;
1620:
1621:                // replace the old buffer with the new buffer.
1622:                buffer = destinationBuffer;
1623:            }
1624:
1625:            /**
1626:             * This method makes sure there is enough room in the buffer
1627:             * for a certain number of bytes.  This method will allocate
1628:             * a new buffer if needed and shift the bytes in the current buffer
1629:             * to make ensure space is available for a fill.  Right now
1630:             * this method will shift bytes as needed to make sure there is
1631:             * as much room as possible in the buffer before trying to
1632:             * do the read.  The idea is to try to have space to get as much data as possible
1633:             * if we need to do a read on the socket's stream.
1634:             *
1635:             * @param desiredSpace - amount of data we need
1636:             */
1637:            private void ensureSpaceInBufferForFill(int desiredSpace) {
1638:                // calculate the total unused space in the buffer.
1639:                // this includes any space at the end of the buffer and any free
1640:                // space at the beginning resulting from bytes already read.
1641:                int currentAvailableSpace = (buffer.length - count) + pos;
1642:
1643:                // check to see if there is enough free space.
1644:                if (currentAvailableSpace < desiredSpace) {
1645:
1646:                    // there is not enough free space so we need more storage.
1647:                    // we are going to double the buffer unless that happens to still be 
1648:                    // too small. If more than double the buffer is needed, 
1649:                    // use the smallest amount over this as possible.
1650:                    int doubleBufferSize = (2 * buffer.length);
1651:                    int minumNewBufferSize = (desiredSpace - currentAvailableSpace)
1652:                            + buffer.length;
1653:                    int newsz = minumNewBufferSize <= doubleBufferSize ? doubleBufferSize
1654:                            : minumNewBufferSize;
1655:
1656:                    byte[] newBuffer = new byte[newsz];
1657:
1658:                    // shift everything from the old buffer to the new buffer
1659:                    shiftBuffer(newBuffer);
1660:                } else {
1661:
1662:                    // there is enough free space in the buffer but let's make sure
1663:                    // it is all at the end.
1664:                    // this is also important because if we are going to do a read, 
1665:                    // it would be nice
1666:                    // to get as much data as possible and making room at the end 
1667:                    // if the buffer helps to ensure this.
1668:                    if (pos != 0) {
1669:                        shiftBuffer(buffer);
1670:                    }
1671:                }
1672:            }
1673:
1674:            /**
1675:             * This method will attempt to read a minimum number of bytes
1676:             * from the underlying stream.	This method will keep trying to
1677:             * read bytes until it has obtained at least the minimum number.
1678:             * @param minimumBytesNeeded - minimum required bytes
1679:             *
1680:             * @exception DRDProtocolException
1681:             */
1682:            private void fill(int minimumBytesNeeded)
1683:                    throws DRDAProtocolException {
1684:                // make sure that there is enough space in the buffer to hold
1685:                // the minimum number of bytes needed.
1686:                ensureSpaceInBufferForFill(minimumBytesNeeded);
1687:
1688:                // read until the minimum number of bytes needed is now in the buffer.
1689:                // hopefully the read method will return as many bytes as it can.
1690:                int totalBytesRead = 0;
1691:                int actualBytesRead = 0;
1692:                do {
1693:                    try {
1694:                        actualBytesRead = inputStream.read(buffer, count,
1695:                                buffer.length - count);
1696:                    } catch (java.io.IOException ioe) {
1697:                        agent.markCommunicationsFailure("DDMReader.fill()",
1698:                                "InputStream.read()", ioe.getMessage(), "*");
1699:                    } finally {
1700:                        if ((dssTrace != null) && dssTrace.isComBufferTraceOn())
1701:                            dssTrace.writeComBufferData(buffer, count,
1702:                                    actualBytesRead,
1703:                                    DssTrace.TYPE_TRACE_RECEIVE, "Request",
1704:                                    "fill", 5);
1705:                    }
1706:                    if (actualBytesRead != -1) {
1707:                        count += actualBytesRead;
1708:                        totalBytesRead += actualBytesRead;
1709:                    }
1710:
1711:                } while ((totalBytesRead < minimumBytesNeeded)
1712:                        && (actualBytesRead != -1));
1713:                if (actualBytesRead == -1) {
1714:                    if (totalBytesRead < minimumBytesNeeded) {
1715:                        agent.markCommunicationsFailure("DDMReader.fill()",
1716:                                "InputStream.read()", "insufficient data", "*");
1717:                    }
1718:                }
1719:            }
1720:
1721:            /**
1722:             * Print a internal trace message
1723:             */
1724:            private void trace(String msg) {
1725:                if (agent != null)
1726:                    agent.trace(msg);
1727:            }
1728:
1729:            protected String toDebugString(String indent) {
1730:                String s = indent + "***** DDMReader toDebugString ******\n";
1731:                int buflen = 0;
1732:                if (buffer != null)
1733:                    buflen = buffer.length;
1734:                s += indent + "Reader buffer length = " + buffer.length + "\n";
1735:                return s;
1736:            }
1737:
1738:            /**
1739:             * Return chaining bit for current DSS.
1740:             */
1741:            protected byte getCurrChainState() {
1742:
1743:                if (!dssIsChainedWithSameID && !dssIsChainedWithDiffID)
1744:                    return DssConstants.DSS_NOCHAIN;
1745:
1746:                if (dssIsChainedWithSameID)
1747:                    return DssConstants.DSSCHAIN_SAME_ID;
1748:
1749:                return DssConstants.DSSCHAIN;
1750:
1751:            }
1752:
1753:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.