Source Code Cross Referenced for CDRInputStream.java in  » Collaboration » JacORB » org » jacorb » orb » 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 » Collaboration » JacORB » org.jacorb.orb 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.jacorb.orb;
0002:
0003:        /*
0004:         *        JacORB - a free Java ORB
0005:         *
0006:         *   Copyright (C) 1997-2004 Gerald Brose.
0007:         *
0008:         *   This library is free software; you can redistribute it and/or
0009:         *   modify it under the terms of the GNU Library General Public
0010:         *   License as published by the Free Software Foundation; either
0011:         *   version 2 of the License, or (at your option) any later version.
0012:         *
0013:         *   This library is distributed in the hope that it will be useful,
0014:         *   but WITHOUT ANY WARRANTY; without even the implied warranty of
0015:         *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016:         *   Library General Public License for more details.
0017:         *
0018:         *   You should have received a copy of the GNU Library General Public
0019:         *   License along with this library; if not, write to the Free
0020:         *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
0021:         */
0022:
0023:        import java.io.IOException;
0024:        import java.io.Serializable;
0025:        import java.math.BigDecimal;
0026:        import java.util.*;
0027:
0028:        import org.apache.avalon.framework.configuration.*;
0029:        import org.apache.avalon.framework.logger.*;
0030:
0031:        import org.jacorb.orb.giop.CodeSet;
0032:        import org.jacorb.orb.giop.GIOPConnection;
0033:        import org.jacorb.util.ObjectUtil;
0034:        import org.jacorb.util.Stack;
0035:        import org.jacorb.util.ValueHandler;
0036:
0037:        import org.omg.CORBA.BAD_PARAM;
0038:        import org.omg.CORBA.INTERNAL;
0039:        import org.omg.CORBA.MARSHAL;
0040:        import org.omg.CORBA.NO_IMPLEMENT;
0041:        import org.omg.CORBA.StructMember;
0042:        import org.omg.CORBA.TCKind;
0043:        import org.omg.CORBA.UnionMember;
0044:        import org.omg.CORBA.ValueMember;
0045:        import org.omg.CORBA.portable.IDLEntity;
0046:        import org.omg.CORBA.TypeCodePackage.BadKind;
0047:        import org.omg.CORBA.TypeCodePackage.Bounds;
0048:
0049:        /**
0050:         * Read CDR encoded data
0051:         *
0052:         * @author Gerald Brose, FU Berlin
0053:         * $Id: CDRInputStream.java,v 1.114 2007/01/08 12:18:45 alphonse.bendt Exp $
0054:         */
0055:
0056:        public class CDRInputStream extends
0057:                org.omg.CORBA_2_3.portable.InputStream {
0058:            /**
0059:             * <code>encaps_stack</code> is used to saving/restoring
0060:             * encapsulation information.
0061:             */
0062:            private Stack encaps_stack;
0063:
0064:            /**
0065:             * This Map is basically a one-entry map pool to be used in
0066:             * read_TypeCode() as the repeatedTCMap.
0067:             */
0068:            private Map repeatedTCMap;
0069:
0070:            /**
0071:             * <code>cachedTypecodes</code> stores a mapping of ID/Typecode to
0072:             * speed reading from the stream. Do NOT access this variable directly. It
0073:             * is initialized on demand. Use the methods
0074:             * {@link #getCachedTypecode(Object id)} and
0075:             * {@link #putCachedTypecode(Object id, Pair result)}
0076:             * Skip amount is
0077:             * skip (size - ((pos - start_pos) - 4 - 4));
0078:             * EncapsulationSize -
0079:             * ( PositionAfterReadingId - start_pos
0080:             *   - 4 [Size] - 4 [KindSize] ) = RemainingSizeToSkip
0081:             */
0082:            private Map cachedTypecodes;
0083:
0084:            /** indexes to support mark/reset */
0085:            private int marked_pos;
0086:            private int marked_index;
0087:
0088:            private boolean closed;
0089:
0090:            /** configurable properties */
0091:            private Logger logger;
0092:            private boolean cometInteropFix;
0093:            private boolean laxBooleanEncoding;
0094:            private boolean cacheTypecodes;
0095:
0096:            /* character encoding code sets for char and wchar, default ISO8859_1 */
0097:            private int codeSet = CodeSet.getTCSDefault();
0098:            private int codeSetW = CodeSet.getTCSWDefault();
0099:            protected int giop_minor = 2; // needed to determine size in chars
0100:
0101:            /**
0102:             * <code>valueMap</code> maps indices within the buffer
0103:             * (java.lang.Integer) to the values that appear at these indices. Do
0104:             * NOT access this variable directly. It is initialized on demand.
0105:             * Use the method {@link #getValueMap()}
0106:             */
0107:            private Map valueMap;
0108:
0109:            /**
0110:             * Index of the current IDL value that is being unmarshalled.
0111:             * This is kept here so that when the value object has been
0112:             * created, the value factory can immediately store it into this
0113:             * stream's valueMap by calling `register_value()'.
0114:             */
0115:            private int currentValueIndex;
0116:
0117:            /**
0118:             * <code>repIdMap</code> maps indices within the buffer
0119:             * (java.lang.Integer) to repository ids that appear at these indices.
0120:             * Do NOT access this variable directly. It is initialized on demand.
0121:             * Use the method {@link #getRepIdMap()}
0122:             */
0123:            private Map repIdMap;
0124:
0125:            /**
0126:             * <code>codebaseMap</code> maps indices within the buffer
0127:             * (java.lang.Integer) to codebase strings that appear at these indices.
0128:             * Do NOT access this variable directly. It is initialized on demand.
0129:             * Use the method {@link #getCodebaseMap()}
0130:             */
0131:            private Map codebaseMap;
0132:
0133:            public boolean littleEndian = false;
0134:
0135:            /** indices into the actual buffer */
0136:            protected byte[] buffer = null;
0137:            protected int pos = 0;
0138:            protected int index = 0;
0139:
0140:            /** Last value tag read had the chunking bit on */
0141:            private boolean chunkedValue = false;
0142:
0143:            /** Nesting level of chunked valuetypes */
0144:            private int valueNestingLevel = 0;
0145:
0146:            /** Ending position of the current chunk */
0147:            private int chunk_end_pos = -1; // -1 means we're not within a chunk
0148:
0149:            /**
0150:             * <code>mutator</code> is a pluggable IOR mutator.
0151:             */
0152:            private IORMutator mutator;
0153:
0154:            private boolean isMutatorEnabled;
0155:
0156:            /**
0157:             * <code>codesetEnabled</code> denotes whether codeset marshalling is enabled.
0158:             */
0159:            private boolean codesetEnabled;
0160:
0161:            /**
0162:             * for this stream to be able to return a live object reference, a
0163:             * full ORB (not the Singleton!) must be known. If this stream is
0164:             * used only to demarshal base type data, the Singleton is enough
0165:             */
0166:            private final org.omg.CORBA.ORB orb;
0167:
0168:            /**
0169:             * this is the lowest possible value_tag indicating the
0170:             * begin of a valuetype (15.3.4)
0171:             */
0172:            private static final int MAX_BLOCK_SIZE = 0x7fffff00;
0173:
0174:            /**
0175:             * fixes RMI/IIOP related interoperability issues with the
0176:             * sun the orb that occured
0177:             * while receiving serialized collections.
0178:             * see mailing list for details:
0179:             * {@link http://lists.spline.inf.fu-berlin.de/mailman/htdig/jacorb-developer/2006-May/008251.html}
0180:             */
0181:            private boolean sunInteropFix;
0182:
0183:            private Map tcMap;
0184:
0185:            public CDRInputStream(final org.omg.CORBA.ORB orb, final byte[] buf) {
0186:                super ();
0187:
0188:                buffer = buf;
0189:                // orb may be null!
0190:                if (orb != null) {
0191:                    this .orb = orb;
0192:                    // orb may be the singleton!
0193:                    if (orb instanceof  org.jacorb.orb.ORB) {
0194:                        try {
0195:
0196:                            configure(((org.jacorb.orb.ORB) orb)
0197:                                    .getConfiguration());
0198:                        } catch (ConfigurationException ce) {
0199:                            throw new INTERNAL("ConfigurationException: " + ce);
0200:                        }
0201:                    }
0202:                } else {
0203:                    this .orb = org.omg.CORBA.ORB.init();
0204:                }
0205:            }
0206:
0207:            public CDRInputStream(final org.omg.CORBA.ORB orb,
0208:                    final byte[] buf, final boolean littleEndian) {
0209:                this (orb, buf);
0210:                this .littleEndian = littleEndian;
0211:            }
0212:
0213:            public CDRInputStream(byte[] buffer, boolean littleEndian) {
0214:                this (null, buffer, littleEndian);
0215:            }
0216:
0217:            /**
0218:             * This stream is self-configuring, i.e. configure() is private
0219:             * and only called from the constructors.
0220:             */
0221:
0222:            private void configure(Configuration configuration)
0223:                    throws ConfigurationException {
0224:                final org.jacorb.config.Configuration jacorbConfig = (org.jacorb.config.Configuration) configuration;
0225:                logger = jacorbConfig.getNamedLogger("jacorb.orb.cdr");
0226:
0227:                codesetEnabled = configuration.getAttribute("jacorb.codeset",
0228:                        "on").equals("on");
0229:                cometInteropFix = configuration.getAttribute(
0230:                        "jacorb.interop.comet", "off").equals("on");
0231:                laxBooleanEncoding = configuration.getAttribute(
0232:                        "jacorb.interop.lax_boolean_encoding", "off").equals(
0233:                        "on");
0234:                cacheTypecodes = configuration.getAttribute(
0235:                        "jacorb.cacheTypecodes", "off").equals("on");
0236:                sunInteropFix = configuration.getAttribute(
0237:                        "jacorb.interop.sun", "off").equalsIgnoreCase("on");
0238:                isMutatorEnabled = configuration.getAttribute(
0239:                        "jacorb.iormutator", "").length() > 0;
0240:
0241:                if (isMutatorEnabled) {
0242:                    mutator = (IORMutator) jacorbConfig
0243:                            .getAttributeAsObject("jacorb.iormutator");
0244:                }
0245:            }
0246:
0247:            /**
0248:             * Gets the Map that is used to demarshal shared valuetype instances.
0249:             *
0250:             * @return a <code>Map</code> value
0251:             */
0252:            private Map getValueMap() {
0253:                if (valueMap == null) {
0254:                    // Unlike the valueMap in CDROutputStream, this one
0255:                    // does need to be an equality-based HashMap.
0256:                    valueMap = new HashMap();
0257:                }
0258:                return valueMap;
0259:            }
0260:
0261:            /**
0262:             * Gets the Map that is used to implement indirections for RepositoryIDs.
0263:             *
0264:             * @return a <code>Map</code> value
0265:             */
0266:            private Map getRepIdMap() {
0267:                if (repIdMap == null) {
0268:                    repIdMap = new HashMap();
0269:                }
0270:                return repIdMap;
0271:            }
0272:
0273:            /**
0274:             * Gets the Map that is used to implement sharing for codebase
0275:             * specifications.
0276:             *
0277:             * @return a <code>Map</code> value
0278:             */
0279:            private Map getCodebaseMap() {
0280:                if (codebaseMap == null) {
0281:                    codebaseMap = new HashMap();
0282:                }
0283:                return codebaseMap;
0284:            }
0285:
0286:            /**
0287:             * <code>getCachedTypecode</code> to retrieve a value from cachedTypecodes.
0288:             * It may initialize the value on demand.
0289:             *
0290:             * @param id a <code>Object</code> value, can be String (id) or actual TypeCode
0291:             * for sequence/array tcs
0292:             * @return a <code>org.omg.CORBA.TypeCode</code> value, possibly null.
0293:             */
0294:            private Pair getCachedTypecode(Object id) {
0295:                final Pair result;
0296:
0297:                if (cacheTypecodes) {
0298:                    if (cachedTypecodes == null) {
0299:                        cachedTypecodes = new HashMap();
0300:                        result = null;
0301:                    } else {
0302:                        result = (Pair) cachedTypecodes.get(id);
0303:                    }
0304:                } else {
0305:                    result = null;
0306:                }
0307:                return result;
0308:            }
0309:
0310:            /**
0311:             * <code>putCachedTypecode</code> is used to store typecodes within the
0312:             * cachedTypecodes. It will only do it cacheTypecodes is on.
0313:             *
0314:             * @param id a <code>String</code> or <code>TypeCode</code> value
0315:             * @param result an Pair value
0316:             */
0317:            private void putCachedTypecode(Object id, Pair result) {
0318:                if (cacheTypecodes) {
0319:                    // By definition get/put should be paired so cachedTypecodes should
0320:                    // never be null here.
0321:                    cachedTypecodes.put(id, result);
0322:                }
0323:            }
0324:
0325:            public void setGIOPMinor(final int giop_minor) {
0326:                this .giop_minor = giop_minor;
0327:            }
0328:
0329:            public int getGIOPMinor() {
0330:                return giop_minor;
0331:            }
0332:
0333:            public void close() {
0334:                // Don't need to call super.close as super is noop.
0335:
0336:                if (closed) {
0337:                    return;
0338:                }
0339:
0340:                // commented out as this caused test failures.
0341:                // as the buffer has been passed into this CDRInputStream
0342:                // we cannot assume ownership of the buffer here (alphonse).
0343:                // BufferManager.getInstance().returnBuffer(buffer);
0344:
0345:                buffer = null;
0346:                encaps_stack = null;
0347:                closed = true;
0348:
0349:                if (tcMap != null) {
0350:                    tcMap.clear();
0351:                }
0352:            }
0353:
0354:            public org.omg.CORBA.ORB orb() {
0355:                return orb;
0356:            }
0357:
0358:            public void setCodeSet(final int codeSet, final int codeSetWide) {
0359:                this .codeSet = codeSet;
0360:                this .codeSetW = codeSetWide;
0361:            }
0362:
0363:            private static final int _read4int(final boolean _littleEndian,
0364:                    final byte[] _buffer, final int _pos) {
0365:                if (_littleEndian) {
0366:                    return (((_buffer[_pos + 3] & 0xff) << 24)
0367:                            + ((_buffer[_pos + 2] & 0xff) << 16)
0368:                            + ((_buffer[_pos + 1] & 0xff) << 8) + ((_buffer[_pos] & 0xff) << 0));
0369:                }
0370:                return (((_buffer[_pos] & 0xff) << 24)
0371:                        + ((_buffer[_pos + 1] & 0xff) << 16)
0372:                        + ((_buffer[_pos + 2] & 0xff) << 8) + ((_buffer[_pos + 3] & 0xff) << 0));
0373:            }
0374:
0375:            private static final short _read2int(final boolean _littleEndian,
0376:                    final byte[] _buffer, final int _pos) {
0377:                if (_littleEndian) {
0378:                    return (short) (((_buffer[_pos + 1] & 0xff) << 8) + ((_buffer[_pos] & 0xff) << 0));
0379:                }
0380:                return (short) (((_buffer[_pos] & 0xff) << 8) + ((_buffer[_pos + 1] & 0xff) << 0));
0381:            }
0382:
0383:            private final int _read_long() {
0384:                int result;
0385:
0386:                result = _read4int(littleEndian, buffer, pos);
0387:
0388:                index += 4;
0389:                pos += 4;
0390:                return result;
0391:            }
0392:
0393:            private final long _read_longlong() {
0394:                if (littleEndian) {
0395:                    return (_read_long() & 0xFFFFFFFFL)
0396:                            + ((long) _read_long() << 32);
0397:                }
0398:
0399:                return ((long) _read_long() << 32)
0400:                        + (_read_long() & 0xFFFFFFFFL);
0401:            }
0402:
0403:            private final void handle_chunking() {
0404:                int remainder = 4 - (index % 4);
0405:                int aligned_pos = (remainder != 4) ? pos + remainder : pos;
0406:
0407:                if (chunk_end_pos >= pos && chunk_end_pos <= aligned_pos) {
0408:                    chunk_end_pos = -1;
0409:                    int saved_pos = pos;
0410:                    int saved_index = index;
0411:                    int tag = read_long();
0412:
0413:                    if (tag < 0) {
0414:
0415:                        // tag is an end tag
0416:
0417:                        if (!(-tag <= valueNestingLevel)) {
0418:                            throw new INTERNAL("received end tag " + tag
0419:                                    + " with value nesting level "
0420:                                    + valueNestingLevel);
0421:                        }
0422:                        valueNestingLevel = -tag;
0423:                        valueNestingLevel--;
0424:
0425:                        if (valueNestingLevel > 0) {
0426:                            chunk_end_pos = pos;
0427:                            handle_chunking();
0428:                        }
0429:                    } else if (tag < 0x7fffff00) {
0430:                        // tag is the chunk size tag of another chunk
0431:
0432:                        chunk_end_pos = pos + tag;
0433:                    } else // (tag >= 0x7fffff00)
0434:                    {
0435:                        // tag is the value tag of a nested value
0436:
0437:                        pos = saved_pos; // "unread" the value tag
0438:                        index = saved_index;
0439:                    }
0440:                }
0441:            }
0442:
0443:            protected final void skip(final int distance) {
0444:                pos += distance;
0445:                index += distance;
0446:            }
0447:
0448:            /**
0449:             * close a CDR encapsulation and
0450:             * restore index and byte order information
0451:             */
0452:
0453:            public final void closeEncapsulation() {
0454:                if (encaps_stack == null) {
0455:                    throw new MARSHAL(
0456:                            "Internal Error - closeEncapsulation failed");
0457:                }
0458:
0459:                EncapsInfo ei = (EncapsInfo) encaps_stack.pop();
0460:                littleEndian = ei.littleEndian;
0461:                int size = ei.size;
0462:                int start = ei.start;
0463:
0464:                if (pos < start + size) {
0465:                    pos = start + size;
0466:                }
0467:
0468:                index = ei.index + size;
0469:            }
0470:
0471:            /**
0472:             * open a CDR encapsulation and
0473:             * restore index and byte order information
0474:             */
0475:
0476:            public final int openEncapsulation() {
0477:                boolean old_endian = littleEndian;
0478:                int size = read_long();
0479:
0480:                // Check if size looks sane. If not try changing byte order.
0481:                // This is a specific fix for interoperability with the Iona
0482:                // Comet COM/CORBA bridge that has problems with size marshalling.
0483:
0484:                if (cometInteropFix && ((size < 0) || (size > buffer.length))) {
0485:                    int temp = (((size >> 24) & 0x000000FF)
0486:                            + ((size >> 8) & 0x0000FF00)
0487:                            + ((size << 8) & 0x00FF0000) + ((size << 24) & 0xFF000000));
0488:
0489:                    if (logger.isDebugEnabled()) {
0490:                        logger
0491:                                .debug("Size of CDR encapsulation larger than buffer, swapping byte order\n"
0492:                                        + "Size of CDR encapsulation was "
0493:                                        + size + ", is now " + temp);
0494:                    }
0495:
0496:                    size = temp;
0497:                }
0498:                /* save current index plus size of the encapsulation on the stack.
0499:                   When the encapsulation is closed, this value will be restored as
0500:                   index */
0501:
0502:                if (encaps_stack == null) {
0503:                    encaps_stack = new Stack();
0504:                }
0505:                encaps_stack.push(new EncapsInfo(old_endian, index, pos, size));
0506:
0507:                openEncapsulatedArray();
0508:
0509:                return size;
0510:            }
0511:
0512:            public final void openEncapsulatedArray() {
0513:                /* reset index  to zero, i.e. align relative  to the beginning
0514:                   of the encaps. */
0515:                resetIndex();
0516:                littleEndian = read_boolean();
0517:            }
0518:
0519:            /*
0520:             * Return a copy of the current buffer.
0521:             *
0522:             * @return a <code>byte[]</code> value.
0523:             */
0524:            public byte[] getBufferCopy() {
0525:                byte[] result = new byte[buffer.length];
0526:                System.arraycopy(buffer, 0, result, 0, buffer.length);
0527:                return result;
0528:            }
0529:
0530:            /**
0531:             * Reads the next byte of data from the input stream. The value byte is
0532:             * returned as an <code>int</code> in the range <code>0</code> to
0533:             * <code>255</code>. If no byte is available because the end of the stream
0534:             * has been reached, the value <code>-1</code> is returned.
0535:             * @return the next byte of data, or <code>-1</code> if the end of the
0536:             *         stream is reached.
0537:             * @throws java.io.IOException if stream is closed.
0538:             */
0539:            public int read() throws java.io.IOException {
0540:                if (closed) {
0541:                    throw new java.io.IOException("Stream already closed!");
0542:                }
0543:
0544:                if (available() < 1) {
0545:                    return -1;
0546:                }
0547:
0548:                ++index;
0549:                return buffer[pos++]; // read_index++];
0550:            }
0551:
0552:            /**
0553:             * @return the number of bytes that can be read (or skipped over) from this
0554:             *         input stream.  This is not necessarily the number of 'valid' bytes.
0555:             */
0556:            public int available() {
0557:                return buffer.length - index;
0558:            }
0559:
0560:            /**
0561:             * Has the effect of read(b, 0, b.length);
0562:             * @see #read(byte[], int, int)
0563:             */
0564:            public int read(final byte[] b) throws java.io.IOException {
0565:                return read(b, 0, b.length);
0566:            }
0567:
0568:            /**
0569:             * Performs as described by <code>java.io.InputStream.read(byte[], int, int)</code>,
0570:             * but never blocks.
0571:             */
0572:            public int read(final byte[] b, final int off, final int len)
0573:                    throws java.io.IOException {
0574:                if (b == null) {
0575:                    throw new java.io.IOException("buffer may not be null");
0576:                }
0577:
0578:                if (off < 0 || len < 0 || off + len > b.length) {
0579:                    throw new java.io.IOException("buffer index out of bounds");
0580:                }
0581:
0582:                if (len == 0) {
0583:                    return 0;
0584:                }
0585:
0586:                if (available() < 1) {
0587:                    return -1;
0588:                }
0589:
0590:                if (closed) {
0591:                    throw new java.io.IOException("Stream already closed!");
0592:                }
0593:
0594:                int min = Math.min(len, available());
0595:                System.arraycopy(buffer, index, b, off, min);
0596:                pos += min;
0597:                index += min;
0598:                return min;
0599:            }
0600:
0601:            public final org.omg.CORBA.Any read_any() {
0602:                org.omg.CORBA.TypeCode _tc = read_TypeCode();
0603:                org.omg.CORBA.Any any = orb.create_any();
0604:                any.read_value(this , _tc);
0605:                return any;
0606:            }
0607:
0608:            public final boolean read_boolean() {
0609:                handle_chunking();
0610:                index++;
0611:                byte value = buffer[pos++];
0612:
0613:                if (value == 0) {
0614:                    return false;
0615:                }
0616:
0617:                if (value == 1) {
0618:                    return true;
0619:                }
0620:
0621:                if (laxBooleanEncoding) {
0622:                    // Technically only valid values are 0 (false) and 1 (true)
0623:                    // however some ORBs send values other than 1 for true.
0624:                    return true;
0625:                }
0626:
0627:                throw new MARSHAL("Unexpected boolean value: " + value
0628:                        + " pos: " + pos + " index: " + index);
0629:            }
0630:
0631:            /** arrays */
0632:
0633:            public final void read_boolean_array(final boolean[] value,
0634:                    final int offset, final int length) {
0635:                handle_chunking();
0636:                byte bb;
0637:                for (int j = offset; j < offset + length; j++) {
0638:                    index++;
0639:                    bb = buffer[pos++];
0640:                    if (bb == 1) {
0641:                        value[j] = true;
0642:                    } else if (bb == 0) {
0643:                        value[j] = false;
0644:                    } else {
0645:                        throw new MARSHAL("Unexpected boolean value: " + bb
0646:                                + " pos: " + pos + " index: " + index);
0647:                    }
0648:                }
0649:            }
0650:
0651:            /**
0652:             * <code>read_char</code> reads a character from the stream.
0653:             *
0654:             * @return a <code>char</code> value
0655:             */
0656:            public final char read_char() {
0657:                handle_chunking();
0658:
0659:                index++;
0660:                return (char) (buffer[pos++] & 0xFF);
0661:            }
0662:
0663:            /**
0664:             * <code>read_char_array</code> reads an character array from the stream.
0665:             *
0666:             * @param value a <code>char[]</code>, the result array.
0667:             * @param offset an <code>int</code>, an offset into <code>value</code>
0668:             * @param length an <code>int</code>, the length of the array to read
0669:             */
0670:            public final void read_char_array(final char[] value,
0671:                    final int offset, final int length) {
0672:                if (value == null) {
0673:                    throw new MARSHAL("Cannot marshall result into null array.");
0674:                } else if (offset + length > value.length || length < 0
0675:                        || offset < 0) {
0676:                    throw new MARSHAL(
0677:                            "Cannot marshall as indices for array are out bounds.");
0678:                }
0679:
0680:                handle_chunking();
0681:
0682:                for (int j = offset; j < offset + length; j++) {
0683:                    index++;
0684:                    value[j] = (char) (0xff & buffer[pos++]);
0685:                }
0686:            }
0687:
0688:            public final double read_double() {
0689:                return Double.longBitsToDouble(read_longlong());
0690:            }
0691:
0692:            public final void read_double_array(final double[] value,
0693:                    final int offset, final int length) {
0694:                if (length == 0) {
0695:                    return;
0696:                }
0697:
0698:                handle_chunking();
0699:
0700:                int remainder = 8 - (index % 8);
0701:                if (remainder != 8) {
0702:                    index += remainder;
0703:                    pos += remainder;
0704:                }
0705:
0706:                for (int j = offset; j < offset + length; j++) {
0707:                    value[j] = Double.longBitsToDouble(_read_longlong());
0708:                }
0709:            }
0710:
0711:            public final BigDecimal read_fixed() {
0712:                handle_chunking();
0713:
0714:                final StringBuffer sb = new StringBuffer();
0715:
0716:                final int c = read_fixed_internal(sb);
0717:
0718:                final java.math.BigDecimal result = new java.math.BigDecimal(
0719:                        new java.math.BigInteger(sb.toString()));
0720:
0721:                return read_fixed_negate(c, result);
0722:            }
0723:
0724:            private BigDecimal read_fixed_negate(final int c,
0725:                    final java.math.BigDecimal result) {
0726:                if (c == 0xD) {
0727:                    return result.negate();
0728:                }
0729:
0730:                return result;
0731:            }
0732:
0733:            private int read_fixed_internal(StringBuffer sb) {
0734:                int b = buffer[pos++];
0735:                int c = b & 0x0F; // second half byte
0736:                index++;
0737:
0738:                while (true) {
0739:                    c = (b & 0xF0) >>> 4;
0740:                    sb.append(c);
0741:
0742:                    c = b & 0x0F;
0743:                    if (c == 0xC || c == 0xD) {
0744:                        break;
0745:                    }
0746:                    sb.append(c);
0747:
0748:                    b = buffer[pos++];
0749:                    index++;
0750:                }
0751:                return c;
0752:            }
0753:
0754:            public final java.math.BigDecimal read_fixed(short digits,
0755:                    short scale) {
0756:                handle_chunking();
0757:
0758:                final StringBuffer sb = new StringBuffer();
0759:
0760:                final int c = read_fixed_internal(sb);
0761:
0762:                final java.math.BigDecimal result = new java.math.BigDecimal(
0763:                        new java.math.BigInteger(sb.toString()), scale);
0764:
0765:                return read_fixed_negate(c, result);
0766:            }
0767:
0768:            public final float read_float() {
0769:                return Float.intBitsToFloat(read_long());
0770:            }
0771:
0772:            public final void read_float_array(final float[] value,
0773:                    final int offset, final int length) {
0774:                if (length == 0) {
0775:                    return;
0776:                }
0777:
0778:                handle_chunking();
0779:
0780:                int remainder = 4 - (index % 4);
0781:                if (remainder != 4) {
0782:                    index += remainder;
0783:                    pos += remainder;
0784:                }
0785:
0786:                for (int j = offset; j < offset + length; j++) {
0787:                    value[j] = Float.intBitsToFloat(_read_long());
0788:                }
0789:            }
0790:
0791:            public final int read_long() {
0792:                handle_chunking();
0793:
0794:                int result;
0795:
0796:                int remainder = 4 - (index % 4);
0797:                if (remainder != 4) {
0798:                    index += remainder;
0799:                    pos += remainder;
0800:                }
0801:
0802:                result = _read4int(littleEndian, buffer, pos);
0803:
0804:                index += 4;
0805:                pos += 4;
0806:                return result;
0807:            }
0808:
0809:            public final void read_long_array(final int[] value,
0810:                    final int offset, final int length) {
0811:                if (length == 0) {
0812:                    return;
0813:                }
0814:
0815:                handle_chunking();
0816:
0817:                int remainder = 4 - (index % 4);
0818:                if (remainder != 4) {
0819:                    index += remainder;
0820:                    pos += remainder;
0821:                }
0822:
0823:                for (int j = offset; j < offset + length; j++) {
0824:                    value[j] = _read4int(littleEndian, buffer, pos);
0825:                    pos += 4;
0826:                }
0827:
0828:                index += 4 * length;
0829:            }
0830:
0831:            public final long read_longlong() {
0832:                handle_chunking();
0833:
0834:                int remainder = 8 - (index % 8);
0835:                if (remainder != 8) {
0836:                    index += remainder;
0837:                    pos += remainder;
0838:                }
0839:
0840:                if (littleEndian) {
0841:                    return (_read_long() & 0xFFFFFFFFL)
0842:                            + ((long) _read_long() << 32);
0843:                }
0844:
0845:                return ((long) _read_long() << 32)
0846:                        + (_read_long() & 0xFFFFFFFFL);
0847:            }
0848:
0849:            public final void read_longlong_array(final long[] value,
0850:                    final int offset, final int length) {
0851:                if (length == 0) {
0852:                    return;
0853:                }
0854:
0855:                handle_chunking();
0856:
0857:                int remainder = 8 - (index % 8);
0858:                if (remainder != 8) {
0859:                    index += remainder;
0860:                    pos += remainder;
0861:                }
0862:
0863:                if (littleEndian) {
0864:                    for (int j = offset; j < offset + length; j++) {
0865:                        value[j] = (_read_long() & 0xFFFFFFFFL)
0866:                                + ((long) _read_long() << 32);
0867:                    }
0868:                } else {
0869:                    for (int j = offset; j < offset + length; j++) {
0870:                        value[j] = ((long) _read_long() << 32)
0871:                                + (_read_long() & 0xFFFFFFFFL);
0872:                    }
0873:                }
0874:
0875:                // Do not need to modify pos and index as use read_long above
0876:            }
0877:
0878:            public final org.omg.CORBA.Object read_Object() {
0879:                if (!(orb instanceof  org.jacorb.orb.ORB)) {
0880:                    throw new MARSHAL(
0881:                            "Cannot use the singleton ORB to receive object references, "
0882:                                    + "please initialize a full ORB instead.");
0883:                }
0884:
0885:                handle_chunking();
0886:
0887:                org.omg.IOP.IOR ior = org.omg.IOP.IORHelper.read(this );
0888:
0889:                if (isMutatorEnabled) {
0890:                    ior = mutator.mutateIncoming(ior);
0891:                }
0892:
0893:                ParsedIOR pior = new ParsedIOR((org.jacorb.orb.ORB) orb, ior);
0894:
0895:                if (pior.isNull()) {
0896:                    return null;
0897:                }
0898:
0899:                return ((org.jacorb.orb.ORB) orb)._getObject(pior);
0900:            }
0901:
0902:            public org.omg.CORBA.Object read_Object(final java.lang.Class clazz) {
0903:                if (org.omg.CORBA.portable.ObjectImpl.class
0904:                        .isAssignableFrom(clazz)) {
0905:                    org.omg.CORBA.Object obj = read_Object();
0906:                    if (obj instanceof  org.omg.CORBA.portable.ObjectImpl) {
0907:                        org.omg.CORBA.portable.ObjectImpl stub = null;
0908:                        try {
0909:                            stub = (org.omg.CORBA.portable.ObjectImpl) clazz
0910:                                    .newInstance();
0911:                        } catch (InstantiationException e) {
0912:                            throw new MARSHAL(
0913:                                    "Exception in stub instantiation: " + e);
0914:                        } catch (IllegalAccessException e) {
0915:                            throw new MARSHAL(
0916:                                    "Exception in stub instantiation: " + e);
0917:                        }
0918:                        stub
0919:                                ._set_delegate(((org.omg.CORBA.portable.ObjectImpl) obj)
0920:                                        ._get_delegate());
0921:                        return stub;
0922:                    }
0923:                    return obj;
0924:                } else if (clazz.isInterface()
0925:                        && java.rmi.Remote.class.isAssignableFrom(clazz)) {
0926:                    return (org.omg.CORBA.Object) org.jacorb.util.ValueHandler
0927:                            .portableRemoteObject_narrow(read_Object(), clazz);
0928:                } else {
0929:                    return read_Object();
0930:                }
0931:            }
0932:
0933:            public final byte read_octet() {
0934:                handle_chunking();
0935:                index++;
0936:                return buffer[pos++];
0937:            }
0938:
0939:            public final void read_octet_array(final byte[] value,
0940:                    final int offset, final int length) {
0941:                handle_chunking();
0942:                System.arraycopy(buffer, pos, value, offset, length);
0943:                index += length;
0944:                pos += length;
0945:            }
0946:
0947:            /*
0948:             * @deprecated
0949:             * @see org.omg.CORBA.portable.InputStream#read_Principal()
0950:             */
0951:            public final org.omg.CORBA.Principal read_Principal() {
0952:                throw new NO_IMPLEMENT("Principal deprecated");
0953:            }
0954:
0955:            /**
0956:             *   Read methods for big-endian as well as little endian data input
0957:             *   contributed by Mark Allerton <MAllerton@img.seagatesoftware.com>
0958:             */
0959:
0960:            public final short read_short() {
0961:                handle_chunking();
0962:
0963:                int remainder = 2 - (index % 2);
0964:                if (remainder != 2) {
0965:                    index += remainder;
0966:                    pos += remainder;
0967:                }
0968:
0969:                short result = _read2int(littleEndian, buffer, pos);
0970:                pos += 2;
0971:                index += 2;
0972:                return result;
0973:            }
0974:
0975:            public final void read_short_array(final short[] value,
0976:                    final int offset, final int length) {
0977:                if (length == 0) {
0978:                    return;
0979:                }
0980:
0981:                handle_chunking();
0982:
0983:                int remainder = 2 - (index % 2);
0984:
0985:                if (remainder != 2) {
0986:                    index += remainder;
0987:                    pos += remainder;
0988:                }
0989:
0990:                for (int j = offset; j < offset + length; j++) {
0991:                    value[j] = _read2int(littleEndian, buffer, pos);
0992:                    pos += 2;
0993:                }
0994:
0995:                index += length * 2;
0996:            }
0997:
0998:            /**
0999:             * <code>read_string</code> reads a string from the buffer. It is optimized
1000:             * for whether it is reading a blank string, and whether codeset translation
1001:             * is active.
1002:             *
1003:             * @return a <code>String</code> value, possibly blank, never null.
1004:             */
1005:            public final String read_string() {
1006:                String result = null;
1007:
1008:                handle_chunking();
1009:
1010:                int remainder = 4 - (index % 4);
1011:                if (remainder != 4) {
1012:                    index += remainder;
1013:                    pos += remainder;
1014:                }
1015:
1016:                // read size (#bytes)
1017:                int size = _read4int(littleEndian, buffer, pos);
1018:                int start = pos + 4;
1019:
1020:                index += (size + 4);
1021:                pos += (size + 4);
1022:
1023:                if ((size > 0) && (buffer[start + size - 1] == 0)) {
1024:                    size--;
1025:                }
1026:                // Optimize for empty strings.
1027:                if (size == 0) {
1028:                    return "";
1029:                }
1030:
1031:                if (start + size > buffer.length) {
1032:                    if (logger.isDebugEnabled()) {
1033:                        logger
1034:                                .debug("Size ("
1035:                                        + size
1036:                                        + ") invalid for string extraction from buffer length of "
1037:                                        + buffer.length + " from position "
1038:                                        + start);
1039:                    }
1040:                    throw new MARSHAL("Invalid size for string extraction");
1041:                }
1042:
1043:                if (codesetEnabled) {
1044:                    String csname = CodeSet.csName(codeSet);
1045:
1046:                    try {
1047:                        result = new String(buffer, start, size, csname);
1048:                    } catch (java.io.UnsupportedEncodingException ex) {
1049:                        if (logger != null && logger.isErrorEnabled()) {
1050:                            logger.error("Charset " + csname
1051:                                    + " is unsupported");
1052:                            result = "";
1053:                        }
1054:                    }
1055:                } else {
1056:                    char[] buf = new char[size];
1057:
1058:                    for (int i = 0; i < size; i++) {
1059:                        buf[i] = (char) (0xff & buffer[start + i]);
1060:                    }
1061:                    result = new String(buf);
1062:                }
1063:
1064:                return result;
1065:            }
1066:
1067:            public final org.omg.CORBA.TypeCode read_TypeCode() {
1068:                if (tcMap == null) {
1069:                    // Initialise tcMap. We keep it for the lifetime of this
1070:                    // stream so it is possible to examine any found recursive
1071:                    // typecodes.
1072:                    tcMap = new TreeMap();
1073:                }
1074:
1075:                if (repeatedTCMap == null) {
1076:                    repeatedTCMap = new HashMap();
1077:                }
1078:
1079:                try {
1080:                    return read_TypeCode(tcMap, repeatedTCMap);
1081:                } finally {
1082:                    repeatedTCMap.clear();
1083:                }
1084:            }
1085:
1086:            private final org.omg.CORBA.TypeCode read_TypeCode(
1087:                    final Map recursiveTCMap, final Map repeatedTCMap) {
1088:                final String id;
1089:                final String name;
1090:                final Pair cachedObject;
1091:                final int member_count;
1092:                final int length;
1093:                final int size;
1094:                final org.omg.CORBA.TypeCode result;
1095:                final org.omg.CORBA.TypeCode content_type;
1096:                final String[] member_names;
1097:
1098:                final int kind = read_long();
1099:                final int start_pos = pos - 4;
1100:                final Integer startPosition = ObjectUtil.newInteger(start_pos);
1101:
1102:                if (logger != null && logger.isDebugEnabled()) {
1103:                    logger.debug("Read Type code of kind " + kind + " at pos: "
1104:                            + start_pos);
1105:                }
1106:
1107:                switch (kind) {
1108:                case -1: //0xffffffff:
1109:                {
1110:                    // recursive or repeated TC
1111:                    int negative_offset = read_long();
1112:
1113:                    final Integer origTCStartPos = ObjectUtil.newInteger(pos
1114:                            - 4 + negative_offset);
1115:
1116:                    // need to check for repeated typecode first since a recursive
1117:                    // typecode may also be repeated (i.e. both maps have an entry
1118:                    // for the given origTCStartPos), but if we find an entry in
1119:                    // the repeatedTCMap, we know the typecode must have
1120:                    // completely been read already, so the marker can't indicate
1121:                    // a recursive typecode
1122:                    final org.omg.CORBA.TypeCode repeatedTC = (org.omg.CORBA.TypeCode) repeatedTCMap
1123:                            .get(origTCStartPos);
1124:
1125:                    if (repeatedTC != null) {
1126:                        result = repeatedTC;
1127:                        break;
1128:                    }
1129:
1130:                    final String recursiveId = (String) recursiveTCMap
1131:                            .get(origTCStartPos);
1132:                    if (recursiveId != null) {
1133:                        try {
1134:                            result = orb.create_recursive_tc(recursiveId);
1135:                            break;
1136:                        } catch (org.omg.CORBA.SystemException e) {
1137:                            throw new MARSHAL(
1138:                                    "Failed to create recursive typecode: " + e);
1139:                        }
1140:                    }
1141:
1142:                    //if we end up here, we didn't find an entry in either
1143:                    //repeatedTCMap and recursiveTCMap
1144:                    throw new MARSHAL(
1145:                            "Found indirection marker, but no corresponding "
1146:                                    + "original typecode (pos: "
1147:                                    + origTCStartPos + ")");
1148:                }
1149:                case TCKind._tk_null: // 0
1150:                case TCKind._tk_void: // 1
1151:                case TCKind._tk_short: // 2
1152:                case TCKind._tk_long: // 3
1153:                case TCKind._tk_ushort: // 4
1154:                case TCKind._tk_ulong: // 5
1155:                case TCKind._tk_float: // 6
1156:                case TCKind._tk_double: // 7
1157:                case TCKind._tk_boolean: // 8
1158:                case TCKind._tk_char: // 9
1159:                case TCKind._tk_octet: // 10
1160:                case TCKind._tk_any: // 11
1161:                case TCKind._tk_TypeCode: // 12
1162:                case TCKind._tk_Principal: // 13
1163:                {
1164:                    result = orb.get_primitive_tc(org.omg.CORBA.TCKind
1165:                            .from_int(kind));
1166:                    break;
1167:                }
1168:                case TCKind._tk_objref: // 14
1169:                {
1170:                    size = openEncapsulation();
1171:                    id = validateID(read_string());
1172:                    cachedObject = getCachedTypecode(id);
1173:
1174:                    if (cachedObject == null) {
1175:                        name = validateName(read_string());
1176:                        result = orb.create_interface_tc(id, name);
1177:                        putCachedTypecode(id, new Pair(result, startPosition));
1178:                    } else {
1179:                        final int skipAmount = calcSkipAmount(size, start_pos);
1180:                        skip(skipAmount);
1181:                        result = cachedObject.typeCode;
1182:                    }
1183:
1184:                    closeEncapsulation();
1185:                    break;
1186:                }
1187:                case TCKind._tk_struct: // 15
1188:                {
1189:                    size = openEncapsulation();
1190:                    id = validateID(read_string());
1191:                    cachedObject = getCachedTypecode(id);
1192:
1193:                    if (cachedObject == null) {
1194:                        name = validateName(read_string());
1195:                        member_count = read_long();
1196:                        recursiveTCMap.put(startPosition, id);
1197:                        StructMember[] struct_members = new StructMember[member_count];
1198:
1199:                        for (int i = 0; i < member_count; i++) {
1200:                            struct_members[i] = new StructMember(
1201:                                    read_string(),
1202:                                    read_TypeCode(recursiveTCMap, repeatedTCMap),
1203:                                    null);
1204:                        }
1205:
1206:                        result = ((ORBSingleton) orb).create_struct_tc(id,
1207:                                name, struct_members, false);
1208:                        putCachedTypecode(id, new Pair(result, startPosition));
1209:                    } else {
1210:                        final int skipAmount = calcSkipAmount(size, start_pos);
1211:                        updateTcMap(recursiveTCMap, start_pos, skipAmount,
1212:                                cachedObject.position);
1213:                        skip(skipAmount);
1214:                        recursiveTCMap.put(startPosition, id);
1215:                        result = cachedObject.typeCode;
1216:                    }
1217:
1218:                    closeEncapsulation();
1219:                    break;
1220:                }
1221:                case TCKind._tk_union: // 16
1222:                {
1223:                    size = openEncapsulation();
1224:                    id = validateID(read_string());
1225:                    cachedObject = getCachedTypecode(id);
1226:
1227:                    if (cachedObject == null) {
1228:                        name = validateName(read_string());
1229:
1230:                        recursiveTCMap.put(startPosition, id);
1231:
1232:                        org.omg.CORBA.TypeCode discriminator_type = read_TypeCode(
1233:                                recursiveTCMap, repeatedTCMap);
1234:                        // Use the dealiased discriminator type for the label types.
1235:                        // This works because the JacORB IDL compiler ignores any aliasing
1236:                        // of label types and only the discriminator type is passed on the
1237:                        // wire.
1238:                        org.omg.CORBA.TypeCode orig_disc_type = TypeCode
1239:                                .originalType(discriminator_type);
1240:
1241:                        int default_index = read_long();
1242:                        member_count = read_long();
1243:
1244:                        UnionMember[] union_members = new UnionMember[member_count];
1245:                        for (int i = 0; i < member_count; i++) {
1246:                            org.omg.CORBA.Any label = orb.create_any();
1247:
1248:                            if (i == default_index) {
1249:                                // Default discriminator
1250:                                label.insert_octet(read_octet());
1251:                            } else {
1252:                                // use the dealiased discriminator type to construct labels
1253:                                label.read_value(this , orig_disc_type);
1254:                            }
1255:
1256:                            union_members[i] = new UnionMember(read_string(),
1257:                                    label, read_TypeCode(recursiveTCMap,
1258:                                            repeatedTCMap), null);
1259:                        }
1260:
1261:                        result = ((ORBSingleton) orb).create_union_tc(id, name,
1262:                                discriminator_type, union_members, false);
1263:                        putCachedTypecode(id, new Pair(result, startPosition));
1264:                    } else {
1265:                        final int skipAmount = calcSkipAmount(size, start_pos);
1266:                        updateTcMap(recursiveTCMap, start_pos, skipAmount,
1267:                                cachedObject.position);
1268:                        skip(skipAmount);
1269:                        recursiveTCMap.put(startPosition, id);
1270:                        result = cachedObject.typeCode;
1271:                    }
1272:
1273:                    closeEncapsulation();
1274:                    break;
1275:                }
1276:                case TCKind._tk_enum: // 17
1277:                {
1278:                    size = openEncapsulation();
1279:                    id = validateID(read_string());
1280:                    cachedObject = getCachedTypecode(id);
1281:
1282:                    if (cachedObject == null) {
1283:                        name = validateName(read_string());
1284:                        member_count = read_long();
1285:                        member_names = new String[member_count];
1286:
1287:                        for (int i = 0; i < member_count; i++) {
1288:                            member_names[i] = read_string();
1289:                        }
1290:
1291:                        result = ((ORBSingleton) orb).create_enum_tc(id, name,
1292:                                member_names, false);
1293:                        putCachedTypecode(id, new Pair(result, startPosition));
1294:                    } else {
1295:                        final int skipAmount = calcSkipAmount(size, start_pos);
1296:                        skip(skipAmount);
1297:                        result = cachedObject.typeCode;
1298:                    }
1299:                    closeEncapsulation();
1300:                    break;
1301:                }
1302:                case TCKind._tk_string: // 18
1303:                {
1304:                    result = orb.create_string_tc(read_long());
1305:                    break;
1306:                }
1307:                case TCKind._tk_sequence: // 19
1308:                {
1309:                    size = openEncapsulation();
1310:                    content_type = read_TypeCode(recursiveTCMap, repeatedTCMap);
1311:                    cachedObject = getCachedTypecode(content_type);
1312:
1313:                    if (cachedObject == null) {
1314:                        length = read_long();
1315:                        result = orb.create_sequence_tc(length, content_type);
1316:                        putCachedTypecode(result, new Pair(result,
1317:                                startPosition));
1318:                    } else {
1319:                        final int skipAmount = calcSkipAmount(size, start_pos);
1320:                        skip(skipAmount);
1321:                        result = cachedObject.typeCode;
1322:                    }
1323:
1324:                    closeEncapsulation();
1325:
1326:                    break;
1327:                }
1328:                case TCKind._tk_array: // 20
1329:                {
1330:                    size = openEncapsulation();
1331:                    content_type = read_TypeCode(recursiveTCMap, repeatedTCMap);
1332:                    cachedObject = getCachedTypecode(content_type);
1333:
1334:                    if (cachedObject == null) {
1335:                        result = orb.create_array_tc(read_long(), content_type);
1336:
1337:                        // Store in cache
1338:                        putCachedTypecode(result, new Pair(result,
1339:                                startPosition));
1340:                    } else {
1341:                        int skipAmount = calcSkipAmount(size, start_pos);
1342:
1343:                        skip(skipAmount);
1344:                        result = cachedObject.typeCode;
1345:                    }
1346:
1347:                    closeEncapsulation();
1348:
1349:                    break;
1350:                }
1351:                case TCKind._tk_alias: // 21
1352:                {
1353:                    size = openEncapsulation();
1354:                    id = validateID(read_string());
1355:                    cachedObject = getCachedTypecode(id);
1356:
1357:                    if (cachedObject == null) {
1358:                        name = validateName(read_string());
1359:
1360:                        recursiveTCMap.put(startPosition, id);
1361:
1362:                        content_type = read_TypeCode(recursiveTCMap,
1363:                                repeatedTCMap);
1364:                        result = orb.create_alias_tc(id, name, content_type);
1365:                        putCachedTypecode(id, new Pair(result, startPosition));
1366:                    } else {
1367:                        final int skipAmount = calcSkipAmount(size, start_pos);
1368:                        updateTcMap(recursiveTCMap, start_pos, skipAmount,
1369:                                cachedObject.position);
1370:                        skip(skipAmount);
1371:                        recursiveTCMap.put(startPosition, id);
1372:                        result = cachedObject.typeCode;
1373:                    }
1374:                    closeEncapsulation();
1375:                    break;
1376:                }
1377:                case TCKind._tk_except: // 22
1378:                {
1379:                    size = openEncapsulation();
1380:                    id = validateID(read_string());
1381:                    cachedObject = getCachedTypecode(id);
1382:
1383:                    if (cachedObject == null) {
1384:                        name = validateName(read_string());
1385:                        member_count = read_long();
1386:
1387:                        recursiveTCMap.put(startPosition, id);
1388:
1389:                        StructMember[] members = new StructMember[member_count];
1390:                        for (int i = 0; i < member_count; i++) {
1391:                            members[i] = new StructMember(
1392:                                    read_string(),
1393:                                    read_TypeCode(recursiveTCMap, repeatedTCMap),
1394:                                    null);
1395:                        }
1396:                        result = ((ORBSingleton) orb).create_exception_tc(id,
1397:                                name, members, false);
1398:
1399:                        // Store in cache
1400:                        putCachedTypecode(id, new Pair(result, startPosition));
1401:                    } else {
1402:                        final int skipAmount = calcSkipAmount(size, start_pos);
1403:                        updateTcMap(recursiveTCMap, start_pos, skipAmount,
1404:                                cachedObject.position);
1405:                        skip(skipAmount);
1406:                        recursiveTCMap.put(startPosition, id);
1407:                        result = cachedObject.typeCode;
1408:                    }
1409:
1410:                    closeEncapsulation();
1411:                    break;
1412:                }
1413:                case TCKind._tk_longlong: // 23
1414:                case TCKind._tk_ulonglong: // 24
1415:                {
1416:                    result = orb.get_primitive_tc(org.omg.CORBA.TCKind
1417:                            .from_int(kind));
1418:                    break;
1419:                }
1420:                case TCKind._tk_longdouble: //25
1421:                {
1422:                    throw new MARSHAL("Cannot handle TypeCode with kind "
1423:                            + kind);
1424:                }
1425:                case TCKind._tk_wchar: // 26
1426:                {
1427:                    result = orb.get_primitive_tc(org.omg.CORBA.TCKind
1428:                            .from_int(kind));
1429:                    break;
1430:                }
1431:                case TCKind._tk_wstring: // 27
1432:                {
1433:                    result = orb.create_wstring_tc(read_long());
1434:                    break;
1435:                }
1436:                case TCKind._tk_fixed: // 28
1437:                {
1438:                    result = orb.create_fixed_tc(read_ushort(), read_short());
1439:                    break;
1440:                }
1441:                case TCKind._tk_value: // 29
1442:                {
1443:                    size = openEncapsulation();
1444:                    id = validateID(read_string());
1445:                    cachedObject = getCachedTypecode(id);
1446:
1447:                    if (cachedObject == null) {
1448:                        name = validateName(read_string());
1449:
1450:                        recursiveTCMap.put(startPosition, id);
1451:
1452:                        short type_modifier = read_short();
1453:                        org.omg.CORBA.TypeCode concrete_base_type = read_TypeCode(
1454:                                recursiveTCMap, repeatedTCMap);
1455:                        member_count = read_long();
1456:                        ValueMember[] vMembers = new ValueMember[member_count];
1457:
1458:                        for (int i = 0; i < member_count; i++) {
1459:                            vMembers[i] = new ValueMember(
1460:                                    read_string(),
1461:                                    null, // id
1462:                                    null, // defined_in
1463:                                    null, // version
1464:                                    read_TypeCode(recursiveTCMap, repeatedTCMap),
1465:                                    null, // type_def
1466:                                    read_short());
1467:                        }
1468:                        result = orb.create_value_tc(id, name, type_modifier,
1469:                                concrete_base_type, vMembers);
1470:                        putCachedTypecode(id, new Pair(result, startPosition));
1471:                    } else {
1472:                        final int skipAmount = calcSkipAmount(size, start_pos);
1473:                        updateTcMap(recursiveTCMap, start_pos, skipAmount,
1474:                                cachedObject.position);
1475:                        skip(skipAmount);
1476:                        recursiveTCMap.put(startPosition, id);
1477:                        result = cachedObject.typeCode;
1478:                    }
1479:                    closeEncapsulation();
1480:                    break;
1481:                }
1482:                case TCKind._tk_value_box: // 30
1483:                {
1484:                    size = openEncapsulation();
1485:                    id = validateID(read_string());
1486:                    cachedObject = getCachedTypecode(id);
1487:
1488:                    if (cachedObject == null) {
1489:                        name = validateName(read_string());
1490:
1491:                        recursiveTCMap.put(startPosition, id);
1492:
1493:                        content_type = read_TypeCode(recursiveTCMap,
1494:                                repeatedTCMap);
1495:                        result = orb
1496:                                .create_value_box_tc(id, name, content_type);
1497:                        putCachedTypecode(id, new Pair(result, startPosition));
1498:                    } else {
1499:                        final int skipAmount = calcSkipAmount(size, start_pos);
1500:                        updateTcMap(recursiveTCMap, start_pos, skipAmount,
1501:                                cachedObject.position);
1502:                        skip(skipAmount);
1503:                        recursiveTCMap.put(startPosition, id);
1504:                        result = cachedObject.typeCode;
1505:                    }
1506:                    closeEncapsulation();
1507:                    break;
1508:                }
1509:                case TCKind._tk_native: //31
1510:                {
1511:                    throw new MARSHAL("Cannot handle TypeCode with kind "
1512:                            + kind);
1513:                }
1514:                case TCKind._tk_abstract_interface: // 32
1515:                {
1516:                    size = openEncapsulation();
1517:                    id = validateID(read_string());
1518:                    cachedObject = getCachedTypecode(id);
1519:
1520:                    if (cachedObject == null) {
1521:                        name = validateName(read_string());
1522:                        recursiveTCMap.put(startPosition, id);
1523:                        result = orb.create_abstract_interface_tc(id, name);
1524:                        putCachedTypecode(id, new Pair(result, startPosition));
1525:                    } else {
1526:                        final int skipAmount = calcSkipAmount(size, start_pos);
1527:                        updateTcMap(recursiveTCMap, start_pos, skipAmount,
1528:                                cachedObject.position);
1529:                        skip(skipAmount);
1530:                        recursiveTCMap.put(startPosition, id);
1531:                        result = cachedObject.typeCode;
1532:                    }
1533:                    closeEncapsulation();
1534:                    break;
1535:                }
1536:                default: {
1537:                    // error, dump buffer contents for diagnosis
1538:                    throw new MARSHAL("Cannot handle TypeCode with kind "
1539:                            + kind);
1540:                }
1541:                }
1542:
1543:                repeatedTCMap.put(startPosition, result);
1544:                return result;
1545:            }
1546:
1547:            /**
1548:             * see cachedTypecodes for calculation.
1549:             * @param size
1550:             * @param start_pos
1551:             */
1552:            private int calcSkipAmount(final int size, final int start_pos) {
1553:                return (size - ((pos - start_pos) - 4 - 4));
1554:            }
1555:
1556:            /**
1557:             * <code>updateTcMap</code> is used during cached typecodes. As a cached
1558:             * typecode is being used we may miss placing markers for the recursive
1559:             * tcMap. Therefore, by recording the original typecodes start, and as we
1560:             * know the length it is possible find and calculate and extra positions
1561:             * that should be added.
1562:             *
1563:             * @param tcMap a <code>Map</code> value which may be updated.
1564:             * @param new_start an <code>int</code> value
1565:             * @param size an <code>int</code> value
1566:             * @param old_start an <code>Integer</code> value
1567:             */
1568:            private void updateTcMap(final Map tcMap, final int new_start,
1569:                    final int size, final Integer old_start) {
1570:                final SortedMap sortedMap = ((TreeMap) tcMap).subMap(old_start,
1571:                        ObjectUtil.newInteger(size + old_start.intValue()));
1572:
1573:                // If we have found anything between the original start position and the size.
1574:                if (sortedMap.size() > 0) {
1575:                    final TreeMap toMerge = new TreeMap();
1576:                    final Iterator iterator = sortedMap.entrySet().iterator();
1577:
1578:                    while (iterator.hasNext()) {
1579:                        final Map.Entry entry = (Map.Entry) iterator.next();
1580:
1581:                        int value = ((Integer) entry.getKey()).intValue();
1582:                        // This calculation is the offset; the distance between the missing
1583:                        // tc and the original start added onto the new start.
1584:                        toMerge.put(ObjectUtil.newInteger(new_start
1585:                                + (value - old_start.intValue())), entry
1586:                                .getValue());
1587:                    }
1588:                    tcMap.putAll(toMerge);
1589:                }
1590:            }
1591:
1592:            public final int read_ulong() {
1593:                handle_chunking();
1594:
1595:                int result;
1596:
1597:                int remainder = 4 - (index % 4);
1598:                if (remainder != 4) {
1599:                    index += remainder;
1600:                    pos += remainder;
1601:                }
1602:
1603:                result = _read4int(littleEndian, buffer, pos);
1604:
1605:                index += 4;
1606:                pos += 4;
1607:                return result;
1608:            }
1609:
1610:            public final void read_ulong_array(final int[] value,
1611:                    final int offset, final int length) {
1612:                if (length == 0) {
1613:                    return;
1614:                }
1615:
1616:                handle_chunking();
1617:
1618:                int remainder = 4 - (index % 4);
1619:                if (remainder != 4) {
1620:                    index += remainder;
1621:                    pos += remainder;
1622:                }
1623:
1624:                for (int j = offset; j < offset + length; j++) {
1625:                    value[j] = _read4int(littleEndian, buffer, pos);
1626:                    pos += 4;
1627:                }
1628:
1629:                index += 4 * length;
1630:            }
1631:
1632:            public final long read_ulonglong() {
1633:                handle_chunking();
1634:
1635:                int remainder = 8 - (index % 8);
1636:                if (remainder != 8) {
1637:                    index += remainder;
1638:                    pos += remainder;
1639:                }
1640:
1641:                if (littleEndian) {
1642:                    return (_read_long() & 0xFFFFFFFFL)
1643:                            + ((long) _read_long() << 32);
1644:                }
1645:
1646:                return ((long) _read_long() << 32)
1647:                        + (_read_long() & 0xFFFFFFFFL);
1648:            }
1649:
1650:            public final void read_ulonglong_array(final long[] value,
1651:                    final int offset, final int length) {
1652:                if (length == 0) {
1653:                    return;
1654:                }
1655:
1656:                handle_chunking();
1657:
1658:                int remainder = 8 - (index % 8);
1659:                if (remainder != 8) {
1660:                    index += remainder;
1661:                    pos += remainder;
1662:                }
1663:
1664:                if (littleEndian) {
1665:                    for (int j = offset; j < offset + length; j++) {
1666:                        value[j] = (_read_long() & 0xFFFFFFFFL)
1667:                                + ((long) _read_long() << 32);
1668:                    }
1669:                } else {
1670:                    for (int j = offset; j < offset + length; j++) {
1671:                        value[j] = ((long) _read_long() << 32)
1672:                                + (_read_long() & 0xFFFFFFFFL);
1673:                    }
1674:                }
1675:
1676:                // Do not need to modify pos and index as use read_long above
1677:            }
1678:
1679:            public final short read_ushort() {
1680:                handle_chunking();
1681:
1682:                int remainder = 2 - (index % 2);
1683:                if (remainder != 2) {
1684:                    index += remainder;
1685:                    pos += remainder;
1686:                }
1687:
1688:                short result = _read2int(littleEndian, buffer, pos);
1689:                pos += 2;
1690:                index += 2;
1691:                return result;
1692:            }
1693:
1694:            public final void read_ushort_array(final short[] value,
1695:                    final int offset, final int length) {
1696:                if (length == 0) {
1697:                    return;
1698:                }
1699:
1700:                handle_chunking();
1701:
1702:                int remainder = 2 - (index % 2);
1703:
1704:                if (remainder != 2) {
1705:                    index += remainder;
1706:                    pos += remainder;
1707:                }
1708:
1709:                for (int j = offset; j < offset + length; j++) {
1710:                    value[j] = _read2int(littleEndian, buffer, pos);
1711:                    pos += 2;
1712:                }
1713:
1714:                index += length * 2;
1715:            }
1716:
1717:            public final char read_wchar() {
1718:                handle_chunking();
1719:
1720:                if (giop_minor == 2) {
1721:                    //ignore size indicator
1722:                    read_wchar_size();
1723:
1724:                    boolean wchar_little_endian = readBOM();
1725:
1726:                    return read_wchar(wchar_little_endian);
1727:                }
1728:
1729:                return read_wchar(littleEndian);
1730:            }
1731:
1732:            /**
1733:             * The number of bytes this char takes. This is actually not
1734:             * necessary since the encodings used are either fixed-length
1735:             * (UTF-16) or have their length encoded internally (UTF-8).
1736:             */
1737:            private final int read_wchar_size() {
1738:                index++;
1739:
1740:                return buffer[pos++];
1741:            }
1742:
1743:            private final char read_wchar(final boolean wchar_little_endian) {
1744:                switch (codeSetW) {
1745:                case CodeSet.UTF8: {
1746:                    if (giop_minor < 2) {
1747:                        throw new MARSHAL(
1748:                                "GIOP 1."
1749:                                        + giop_minor
1750:                                        + " only allows 2 Byte encodings for wchar, but the selected TCSW is UTF-8");
1751:                    }
1752:
1753:                    short value = (short) (0xff & buffer[pos++]);
1754:                    index++;
1755:
1756:                    if ((value & 0x80) == 0) {
1757:                        return (char) value;
1758:                    } else if ((value & 0xe0) == 0xc0) {
1759:                        index++;
1760:                        return (char) (((value & 0x1F) << 6) | (buffer[pos++] & 0x3F));
1761:                    } else {
1762:                        index += 2;
1763:                        short b2 = (short) (0xff & buffer[pos++]);
1764:                        return (char) (((value & 0x0F) << 12)
1765:                                | ((b2 & 0x3F) << 6) | (buffer[pos++] & 0x3F));
1766:                    }
1767:                }
1768:                case CodeSet.UTF16: {
1769:                    char value;
1770:
1771:                    if (wchar_little_endian) {
1772:                        value = (char) ((buffer[pos++] & 0xFF) | (buffer[pos++] << 8));
1773:                    } else {
1774:                        value = (char) ((buffer[pos++] << 8) | (buffer[pos++] & 0xFF));
1775:                    }
1776:
1777:                    index += 2;
1778:                    return value;
1779:                }
1780:                default: {
1781:                    throw new MARSHAL("Bad CodeSet: " + codeSetW);
1782:                }
1783:                }
1784:            }
1785:
1786:            /**
1787:             * Read the byte order marker indicating the endianess.
1788:             *
1789:             * @return true for little endianess, false otherwise (including
1790:             * no BOM present. In this case, big endianess is assumed per
1791:             * spec).
1792:             */
1793:            private final boolean readBOM() {
1794:                if ((buffer[pos] == (byte) 0xFE)
1795:                        && (buffer[pos + 1] == (byte) 0xFF)) {
1796:                    //encountering a byte order marker indicating big
1797:                    //endianess
1798:
1799:                    pos += 2;
1800:                    index += 2;
1801:
1802:                    return false;
1803:                } else if ((buffer[pos] == (byte) 0xFF)
1804:                        && (buffer[pos + 1] == (byte) 0xFE)) {
1805:                    //encountering a byte order marker indicating
1806:                    //little endianess
1807:
1808:                    pos += 2;
1809:                    index += 2;
1810:
1811:                    return true;
1812:                } else {
1813:                    //no BOM so big endian per spec.
1814:                    return false;
1815:                }
1816:            }
1817:
1818:            public final void read_wchar_array(final char[] value,
1819:                    final int offset, final int length) {
1820:                handle_chunking();
1821:                for (int j = offset; j < offset + length; j++) {
1822:                    value[j] = read_wchar(); // inlining later...
1823:                }
1824:            }
1825:
1826:            public final String read_wstring() {
1827:                String result = null;
1828:                char buf[] = null;
1829:
1830:                handle_chunking();
1831:
1832:                int remainder = 4 - (index % 4);
1833:                if (remainder != 4) {
1834:                    index += remainder;
1835:                    pos += remainder;
1836:                }
1837:                if (giop_minor == 2) {
1838:                    // read size in bytes
1839:                    int size = _read4int(littleEndian, buffer, pos);
1840:                    index += 4;
1841:                    pos += 4;
1842:
1843:                    if (size == 0) {
1844:                        return "";
1845:                    }
1846:
1847:                    buf = new char[size];
1848:
1849:                    int i = 0;
1850:                    int endPos = pos + size;
1851:
1852:                    boolean wchar_litte_endian = readBOM();
1853:
1854:                    while (pos < endPos) {
1855:                        //ignore size
1856:                        //read_wchar_size();
1857:
1858:                        buf[i++] = read_wchar(wchar_litte_endian);
1859:                    }
1860:
1861:                    result = new String(buf, 0, i);
1862:                } else //GIOP 1.1 / 1.0
1863:                {
1864:                    // read size
1865:                    int size = _read4int(littleEndian, buffer, pos);
1866:                    index += 4;
1867:                    pos += 4;
1868:                    buf = new char[size];
1869:
1870:                    int endPos = pos + size;
1871:
1872:                    if (codeSetW == CodeSet.UTF16) {
1873:                        //size is in chars, but char has 2 bytes
1874:                        endPos += size;
1875:                    }
1876:
1877:                    int i = 0;
1878:
1879:                    while (pos < endPos) {
1880:                        //use the stream-wide endianess
1881:                        buf[i++] = read_wchar(littleEndian);
1882:                    }
1883:
1884:                    if ((i != 0) && (buf[i - 1] == 0)) {
1885:                        //don't return terminating NUL
1886:                        result = new String(buf, 0, i - 1);
1887:                    } else {
1888:                        //doesn't have a terminating NUL. This is actually not
1889:                        //allowed.
1890:                        result = new String(buf, 0, i);
1891:                    }
1892:                }
1893:                buf = null;
1894:                return result;
1895:            }
1896:
1897:            public boolean markSupported() {
1898:                return true;
1899:            }
1900:
1901:            public void mark(final int readLimit) {
1902:                marked_pos = pos;
1903:                marked_index = index;
1904:            }
1905:
1906:            public void reset() throws IOException {
1907:                if (pos < 0) {
1908:                    throw new MARSHAL("Mark has not been set!");
1909:                }
1910:                pos = marked_pos;
1911:                index = marked_index;
1912:            }
1913:
1914:            // JacORB-specific
1915:
1916:            private final void resetIndex() {
1917:                index = 0;
1918:            }
1919:
1920:            public final void setLittleEndian(final boolean b) {
1921:                littleEndian = b;
1922:            }
1923:
1924:            /**
1925:             * Reads an instance of the type described by type code <code>tc</code>
1926:             * from this CDRInputStream, and remarshals it to the given OutputStream,
1927:             * <code>out</code>.  Called from Any.
1928:             */
1929:            final void read_value(final org.omg.CORBA.TypeCode typeCode,
1930:                    final org.omg.CORBA.portable.OutputStream out) {
1931:                if (typeCode == null) {
1932:                    throw new BAD_PARAM("TypeCode is null");
1933:                }
1934:
1935:                int kind = typeCode.kind().value();
1936:
1937:                try {
1938:                    switch (kind) {
1939:                    case TCKind._tk_null: // 0
1940:                        // fallthrough
1941:                    case TCKind._tk_void: // 1
1942:                    {
1943:                        break;
1944:                    }
1945:                    case TCKind._tk_short: // 2
1946:                    {
1947:                        out.write_short(read_short());
1948:                        break;
1949:                    }
1950:                    case TCKind._tk_long: // 3
1951:                    {
1952:                        out.write_long(read_long());
1953:                        break;
1954:                    }
1955:                    case TCKind._tk_ushort: // 4
1956:                    {
1957:                        out.write_ushort(read_ushort());
1958:                        break;
1959:                    }
1960:                    case TCKind._tk_ulong: // 5
1961:                    {
1962:                        out.write_ulong(read_ulong());
1963:                        break;
1964:                    }
1965:                    case TCKind._tk_float: // 6
1966:                    {
1967:                        out.write_float(read_float());
1968:                        break;
1969:                    }
1970:                    case TCKind._tk_double: // 7
1971:                    {
1972:                        out.write_double(read_double());
1973:                        break;
1974:                    }
1975:                    case TCKind._tk_boolean: // 8
1976:                    {
1977:                        out.write_boolean(read_boolean());
1978:                        break;
1979:                    }
1980:                    case TCKind._tk_char: // 9
1981:                    {
1982:                        out.write_char(read_char());
1983:                        break;
1984:                    }
1985:                    case TCKind._tk_octet: // 10
1986:                    {
1987:                        out.write_octet(read_octet());
1988:                        break;
1989:                    }
1990:                    case TCKind._tk_any: // 11
1991:                    {
1992:                        out.write_any(read_any());
1993:                        break;
1994:                    }
1995:                    case TCKind._tk_TypeCode: // 12
1996:                    {
1997:                        out.write_TypeCode(read_TypeCode());
1998:                        break;
1999:                    }
2000:                    case TCKind._tk_Principal: // 13
2001:                    {
2002:                        throw new NO_IMPLEMENT("Principal deprecated");
2003:                    }
2004:                    case TCKind._tk_objref: // 14
2005:                    {
2006:                        out.write_Object(read_Object());
2007:                        break;
2008:                    }
2009:                    case TCKind._tk_struct: // 15
2010:                    {
2011:                        for (int i = 0; i < typeCode.member_count(); i++) {
2012:                            read_value(typeCode.member_type(i), out);
2013:                        }
2014:                        break;
2015:                    }
2016:                    case TCKind._tk_union: // 16
2017:                    {
2018:                        org.omg.CORBA.TypeCode disc = typeCode
2019:                                .discriminator_type();
2020:                        disc = TypeCode.originalType(disc);
2021:                        int def_idx = typeCode.default_index();
2022:                        int member_idx = -1;
2023:                        switch (disc.kind().value()) {
2024:                        case TCKind._tk_short: // 2
2025:                        {
2026:                            short s = read_short();
2027:                            out.write_short(s);
2028:                            for (int i = 0; i < typeCode.member_count(); i++) {
2029:                                if (i != def_idx) {
2030:                                    if (s == typeCode.member_label(i)
2031:                                            .extract_short()) {
2032:                                        member_idx = i;
2033:                                        break;
2034:                                    }
2035:                                }
2036:                            }
2037:                            break;
2038:                        }
2039:
2040:                        case TCKind._tk_long: // 3
2041:                        {
2042:                            int s = read_long();
2043:                            out.write_long(s);
2044:                            for (int i = 0; i < typeCode.member_count(); i++) {
2045:                                if (i != def_idx) {
2046:                                    if (s == typeCode.member_label(i)
2047:                                            .extract_long()) {
2048:                                        member_idx = i;
2049:                                        break;
2050:                                    }
2051:                                }
2052:                            }
2053:                            break;
2054:                        }
2055:                        case TCKind._tk_ushort: // 4
2056:                        {
2057:                            short s = read_ushort();
2058:                            out.write_ushort(s);
2059:                            for (int i = 0; i < typeCode.member_count(); i++) {
2060:                                if (i != def_idx) {
2061:                                    if (s == typeCode.member_label(i)
2062:                                            .extract_ushort()) {
2063:                                        member_idx = i;
2064:                                        break;
2065:                                    }
2066:                                }
2067:                            }
2068:                            break;
2069:                        }
2070:
2071:                        case TCKind._tk_ulong: // 5
2072:                        {
2073:                            int s = read_ulong();
2074:                            out.write_ulong(s);
2075:                            for (int i = 0; i < typeCode.member_count(); i++) {
2076:                                if (i != def_idx) {
2077:                                    if (s == typeCode.member_label(i)
2078:                                            .extract_ulong()) {
2079:                                        member_idx = i;
2080:                                        break;
2081:                                    }
2082:                                }
2083:                            }
2084:                            break;
2085:                        }
2086:                        case TCKind._tk_float: // 6
2087:                            // fallthrough
2088:                        case TCKind._tk_double: // 7
2089:                        {
2090:                            throw new MARSHAL(
2091:                                    "Invalid union discriminator type: " + disc);
2092:                        }
2093:                        case TCKind._tk_boolean: // 8
2094:                        {
2095:                            boolean b = read_boolean();
2096:                            out.write_boolean(b);
2097:                            for (int i = 0; i < typeCode.member_count(); i++) {
2098:                                if (i != def_idx) {
2099:                                    if (b == typeCode.member_label(i)
2100:                                            .extract_boolean()) {
2101:                                        member_idx = i;
2102:                                        break;
2103:                                    }
2104:                                }
2105:                            }
2106:                            break;
2107:                        }
2108:                        case TCKind._tk_char: // 9
2109:                        {
2110:                            char s = read_char();
2111:                            out.write_char(s);
2112:                            for (int i = 0; i < typeCode.member_count(); i++) {
2113:                                if (i != def_idx) {
2114:                                    if (s == typeCode.member_label(i)
2115:                                            .extract_char()) {
2116:                                        member_idx = i;
2117:                                        break;
2118:                                    }
2119:                                }
2120:                            }
2121:                            break;
2122:                        }
2123:                        case TCKind._tk_octet: // 10
2124:                            // fallthrough
2125:                        case TCKind._tk_any: // 11
2126:                            // fallthrough
2127:                        case TCKind._tk_TypeCode: // 12
2128:                            // fallthrough
2129:                        case TCKind._tk_Principal: // 13
2130:                            // fallthrough
2131:                        case TCKind._tk_objref: // 14
2132:                            // fallthrough
2133:                        case TCKind._tk_struct: // 15
2134:                            // fallthrough
2135:                        case TCKind._tk_union: // 16
2136:                        {
2137:                            throw new MARSHAL(
2138:                                    "Invalid union discriminator type: " + disc);
2139:                        }
2140:                        case TCKind._tk_enum: // 17
2141:                        {
2142:                            int s = read_long();
2143:                            out.write_long(s);
2144:                            for (int i = 0; i < typeCode.member_count(); i++) {
2145:                                if (i != def_idx) {
2146:                                    int label = typeCode.member_label(i)
2147:                                            .create_input_stream().read_long();
2148:                                    if (s == label) {
2149:                                        member_idx = i;
2150:                                        break;
2151:                                    }
2152:                                }
2153:                            }
2154:                            break;
2155:                        }
2156:                        case TCKind._tk_string: // 18
2157:                            // fallthrough
2158:                        case TCKind._tk_sequence: // 19
2159:                            // fallthrough
2160:                        case TCKind._tk_array: // 20
2161:                            // fallthrough
2162:                        case TCKind._tk_alias: // 21
2163:                            // fallthrough
2164:                        case TCKind._tk_except: // 22
2165:                        {
2166:                            throw new MARSHAL(
2167:                                    "Invalid union discriminator type: " + disc);
2168:                        }
2169:                        case TCKind._tk_longlong: // 23
2170:                        {
2171:                            long s = read_longlong();
2172:                            out.write_longlong(s);
2173:                            for (int i = 0; i < typeCode.member_count(); i++) {
2174:                                if (i != def_idx) {
2175:                                    if (s == typeCode.member_label(i)
2176:                                            .extract_longlong()) {
2177:                                        member_idx = i;
2178:                                        break;
2179:                                    }
2180:                                }
2181:                            }
2182:                            break;
2183:                        }
2184:                        case TCKind._tk_ulonglong: // 24
2185:                        {
2186:                            long s = read_ulonglong();
2187:                            out.write_ulonglong(s);
2188:                            for (int i = 0; i < typeCode.member_count(); i++) {
2189:                                if (i != def_idx) {
2190:                                    if (s == typeCode.member_label(i)
2191:                                            .extract_ulonglong()) {
2192:                                        member_idx = i;
2193:                                        break;
2194:                                    }
2195:                                }
2196:                            }
2197:                            break;
2198:                        }
2199:                        default: {
2200:                            throw new MARSHAL(
2201:                                    "Invalid union discriminator type: " + disc);
2202:                        }
2203:                        } // switch
2204:
2205:                        if (member_idx != -1) {
2206:                            read_value(typeCode.member_type(member_idx), out);
2207:                        } else if (def_idx != -1) {
2208:                            read_value(typeCode.member_type(def_idx), out);
2209:                        }
2210:                        break;
2211:                    }
2212:                    case TCKind._tk_enum: // 17
2213:                    {
2214:                        out.write_long(read_long());
2215:                        break;
2216:                    }
2217:                    case TCKind._tk_string: // 18
2218:                    {
2219:                        out.write_string(read_string());
2220:                        break;
2221:                    }
2222:                    case TCKind._tk_sequence: // 19
2223:                    {
2224:                        int len = read_long();
2225:                        out.write_long(len);
2226:                        for (int i = 0; i < len; i++) {
2227:                            read_value(typeCode.content_type(), out);
2228:                        }
2229:                        break;
2230:                    }
2231:                    case TCKind._tk_array: // 20
2232:                    {
2233:                        int length = typeCode.length();
2234:                        for (int i = 0; i < length; i++) {
2235:                            read_value(typeCode.content_type(), out);
2236:                        }
2237:                        break;
2238:                    }
2239:                    case TCKind._tk_alias: // 21
2240:                    {
2241:                        read_value(typeCode.content_type(), out);
2242:                        break;
2243:                    }
2244:                    case TCKind._tk_except: // 22
2245:                    {
2246:                        out.write_string(read_string());
2247:
2248:                        for (int i = 0; i < typeCode.member_count(); i++) {
2249:                            read_value(typeCode.member_type(i), out);
2250:                        }
2251:
2252:                        break;
2253:                    }
2254:                    case TCKind._tk_longlong: // 23
2255:                    {
2256:                        out.write_longlong(read_longlong());
2257:                        break;
2258:                    }
2259:                    case TCKind._tk_ulonglong: // 24
2260:                    {
2261:                        out.write_ulonglong(read_ulonglong());
2262:                        break;
2263:                    }
2264:                    case TCKind._tk_longdouble: // 25
2265:                    {
2266:                        throw new org.omg.CORBA.BAD_TYPECODE(
2267:                                "type longdouble not supported in java");
2268:                    }
2269:                    case TCKind._tk_wchar: // 26
2270:                    {
2271:                        out.write_wchar(read_wchar());
2272:                        break;
2273:                    }
2274:                    case TCKind._tk_wstring: // 27
2275:                    {
2276:                        out.write_wstring(read_wstring());
2277:                        break;
2278:                    }
2279:                    case TCKind._tk_fixed: // 28
2280:                    {
2281:                        out.write_fixed(read_fixed());
2282:                        break;
2283:                    }
2284:                    case TCKind._tk_value: // 29
2285:                    {
2286:                        Serializable val = read_value();
2287:                        ((org.omg.CORBA_2_3.portable.OutputStream) out)
2288:                                .write_value(val, typeCode.id());
2289:                        break;
2290:                    }
2291:                    case TCKind._tk_value_box: // 30
2292:                    {
2293:                        String id = typeCode.id();
2294:                        org.omg.CORBA.portable.BoxedValueHelper helper = ((org.jacorb.orb.ORB) orb)
2295:                                .getBoxedValueHelper(id);
2296:                        if (helper == null) {
2297:                            throw new MARSHAL("No BoxedValueHelper for id "
2298:                                    + id);
2299:                        }
2300:                        java.io.Serializable value = read_value(helper);
2301:                        ((org.omg.CORBA_2_3.portable.OutputStream) out)
2302:                                .write_value(value, helper);
2303:                        break;
2304:                    }
2305:                    default: {
2306:                        throw new MARSHAL("Cannot handle TypeCode with kind "
2307:                                + kind);
2308:                    }
2309:                    }
2310:                } catch (BadKind ex) {
2311:                    throw new MARSHAL("When processing TypeCode with kind: "
2312:                            + kind + " caught " + ex);
2313:                } catch (Bounds ex) {
2314:                    throw new MARSHAL("When processing TypeCode with kind: "
2315:                            + kind + " caught " + ex);
2316:                }
2317:            }
2318:
2319:            public java.io.Serializable read_value() {
2320:                int tag = read_long();
2321:                int start_offset = pos - 4;
2322:
2323:                if (tag == 0xffffffff) {
2324:                    // indirection
2325:                    return read_indirect_value();
2326:                } else if (tag == 0x00000000) {
2327:                    // null tag
2328:                    return null;
2329:                }
2330:
2331:                String codebase = ((tag & 1) != 0) ? read_codebase() : null;
2332:                chunkedValue = ((tag & 8) != 0);
2333:
2334:                int theTag = tag;
2335:                tag = tag & 0xfffffff6;
2336:
2337:                if (tag == 0x7fffff00) {
2338:                    throw new MARSHAL("missing value type information");
2339:                } else if (tag == 0x7fffff02) {
2340:                    return read_typed_value(start_offset, codebase);
2341:                } else if (tag == 0x7fffff06) {
2342:                    return read_multi_typed_value(start_offset, codebase);
2343:                } else {
2344:                    throw new MARSHAL("unknown value tag: 0x"
2345:                            + Integer.toHexString(theTag) + " (offset=0x"
2346:                            + Integer.toHexString(start_offset) + ")");
2347:                }
2348:            }
2349:
2350:            /**
2351:             * Overrides read_value(java.io.Serializable value) in
2352:             * org.omg.CORBA_2_3.portable.InputStream
2353:             */
2354:            public java.io.Serializable read_value(final String rep_id) {
2355:                int tag = read_long();
2356:                final int start_offset = pos - 4;
2357:
2358:                if (tag == 0xffffffff) {
2359:                    // indirection
2360:                    return read_indirect_value();
2361:                } else if (tag == 0x00000000) {
2362:                    // null tag
2363:                    return null;
2364:                }
2365:
2366:                final String codebase = ((tag & 1) != 0) ? read_codebase()
2367:                        : null;
2368:                chunkedValue = ((tag & 8) != 0);
2369:
2370:                int theTag = tag;
2371:                tag = tag & 0xfffffff6;
2372:
2373:                if (tag == 0x7fffff00) {
2374:                    return read_untyped_value(new String[] { rep_id },
2375:                            start_offset, codebase);
2376:                } else if (tag == 0x7fffff02) {
2377:                    return read_typed_value(start_offset, codebase);
2378:                } else if (tag == 0x7fffff06) {
2379:                    return read_multi_typed_value(start_offset, codebase);
2380:                } else {
2381:                    throw new MARSHAL("unknown value tag: 0x"
2382:                            + Integer.toHexString(theTag) + " (offset=0x"
2383:                            + Integer.toHexString(start_offset) + ")");
2384:                }
2385:            }
2386:
2387:            /**
2388:             * Unmarshals a valuetype instance from this stream.  The value returned
2389:             * is the same value passed in, with all the data unmarshaled
2390:             * (IDL-to-Java Mapping 1.2, August 2002, 1.13.1, p. 1-39).  The specified
2391:             * value is an uninitialized value that is added to the ORB's indirection
2392:             * table before unmarshaling (1.21.4.1, p. 1-117).
2393:             *
2394:             * This method is intended to be called from custom valuetype factories.
2395:             * Unlike the other read_value() methods in this class, this method does
2396:             * not expect a GIOP value tag nor a repository id in the stream.
2397:             *
2398:             * Overrides read_value(value) in
2399:             * org.omg.CORBA_2_3.portable.InputStream
2400:             */
2401:            public java.io.Serializable read_value(java.io.Serializable value) {
2402:                if (value instanceof  org.omg.CORBA.portable.Streamable) {
2403:                    register_value(value);
2404:                    ((org.omg.CORBA.portable.Streamable) value)._read(this );
2405:                } else if (value instanceof  org.omg.CORBA.portable.CustomValue) {
2406:                    register_value(value);
2407:                    ((org.omg.CORBA.portable.CustomValue) value)
2408:                            .unmarshal(new DataInputStream(this ));
2409:                } else {
2410:                    throw new BAD_PARAM(
2411:                            "read_value is only implemented for Streamables");
2412:                }
2413:                return value;
2414:            }
2415:
2416:            /**
2417:             * Overrides read_value(clz) in
2418:             * org.omg.CORBA_2_3.portable.InputStream
2419:             */
2420:
2421:            public java.io.Serializable read_value(final java.lang.Class clz) {
2422:                int tag = read_long();
2423:                int start_offset = pos - 4;
2424:
2425:                if (tag == 0xffffffff) {
2426:                    // indirection
2427:                    return read_indirect_value();
2428:                } else if (tag == 0x00000000) {
2429:                    // null tag
2430:                    return null;
2431:                }
2432:
2433:                String codebase = ((tag & 1) != 0) ? read_codebase() : null;
2434:                chunkedValue = ((tag & 8) != 0);
2435:
2436:                int theTag = tag;
2437:                tag = tag & 0xfffffff6;
2438:
2439:                if (tag == 0x7fffff00) {
2440:                    return read_untyped_value(new String[] { ValueHandler
2441:                            .getRMIRepositoryID(clz) }, start_offset, codebase);
2442:                } else if (tag == 0x7fffff02) {
2443:                    return read_typed_value(start_offset, codebase);
2444:                } else if (tag == 0x7fffff06) {
2445:                    return read_multi_typed_value(start_offset, codebase);
2446:                } else {
2447:                    throw new MARSHAL("unknown value tag: 0x"
2448:                            + Integer.toHexString(theTag) + " (offset=0x"
2449:                            + Integer.toHexString(start_offset) + ")");
2450:                }
2451:            }
2452:
2453:            /**
2454:             * Overrides read_value(factory) in
2455:             * org.omg.CORBA_2_3.portable.InputStream
2456:             */
2457:            public java.io.Serializable read_value(
2458:                    final org.omg.CORBA.portable.BoxedValueHelper factory) {
2459:                int tag = read_long();
2460:                int start_offset = pos - 4;
2461:
2462:                if (tag == 0xffffffff) {
2463:                    // indirection
2464:                    return read_indirect_value();
2465:                } else if (tag == 0x00000000) {
2466:                    // null tag, explicit representation of null value
2467:                    return null;
2468:                }
2469:
2470:                String codebase = ((tag & 1) != 0) ? read_codebase() : null;
2471:                chunkedValue = ((tag & 8) != 0);
2472:
2473:                int theTag = tag;
2474:                tag = tag & 0xfffffff6;
2475:
2476:                if (tag == 0x7fffff00) {
2477:                    java.io.Serializable result = factory.read_value(this );
2478:
2479:                    if (result != null) {
2480:                        getValueMap().put(ObjectUtil.newInteger(start_offset),
2481:                                result);
2482:                    }
2483:
2484:                    return result;
2485:                } else if (tag == 0x7fffff02) {
2486:                    // Read value according to type information.
2487:                    // Possible optimization: ignore type info and use factory for
2488:                    // reading the value anyway, since the type information is
2489:                    // most likely redundant.
2490:                    return read_typed_value(start_offset, codebase);
2491:                } else {
2492:                    throw new MARSHAL("unknown value tag: 0x"
2493:                            + Integer.toHexString(theTag) + " (offset=0x"
2494:                            + Integer.toHexString(start_offset) + ")");
2495:                }
2496:            }
2497:
2498:            /**
2499:             * Immediately reads a value from this stream; i.e. without any
2500:             * repository id preceding it.  The expected type of the value is given
2501:             * by `repository_id', and the index at which the value started is
2502:             * `index'.
2503:             */
2504:            private java.io.Serializable read_untyped_value(
2505:                    final String[] repository_ids, final int index,
2506:                    final String codebase) {
2507:                java.io.Serializable result = null;
2508:
2509:                if (chunkedValue || valueNestingLevel > 0) {
2510:                    valueNestingLevel++;
2511:                    int chunk_size_tag = readChunkSizeTag();
2512:                    chunk_end_pos = pos + chunk_size_tag;
2513:                }
2514:
2515:                for (int i = 0; i < repository_ids.length; i++) {
2516:                    if (repository_ids[i]
2517:                            .equals("IDL:omg.org/CORBA/WStringValue:1.0")) {
2518:                        // special handling of strings, according to spec
2519:                        result = read_wstring();
2520:                        break;
2521:                    } else if (repository_ids[i]
2522:                            .startsWith("RMI:javax.rmi.CORBA.ClassDesc:")) {
2523:                        // special handling of java.lang.Class instances
2524:                        final String classCodebase = (String) read_value(String.class);
2525:                        final String reposId = (String) read_value(String.class);
2526:                        final String className = org.jacorb.ir.RepositoryID
2527:                                .className(reposId, null);
2528:
2529:                        try {
2530:                            result = loadClass(className, classCodebase);
2531:                        } catch (ClassNotFoundException e) {
2532:                            if (i < repository_ids.length - 1) {
2533:                                continue;
2534:                            }
2535:
2536:                            throw new MARSHAL("class not found: " + className);
2537:                        }
2538:                        break;
2539:                    } else if (repository_ids[i].startsWith("IDL:")) {
2540:                        org.omg.CORBA.portable.ValueFactory factory = ((org.omg.CORBA_2_3.ORB) orb())
2541:                                .lookup_value_factory(repository_ids[i]);
2542:
2543:                        if (factory != null) {
2544:                            currentValueIndex = index;
2545:                            result = factory.read_value(this );
2546:                            break;
2547:                        }
2548:
2549:                        if (i < repository_ids.length - 1) {
2550:                            continue;
2551:                        }
2552:
2553:                        throw new MARSHAL("No factory found for: "
2554:                                + repository_ids[0]);
2555:                    } else // RMI
2556:                    {
2557:                        final String className = org.jacorb.ir.RepositoryID
2558:                                .className(repository_ids[i], null);
2559:
2560:                        try {
2561:                            final Class clazz = loadClass(className, codebase);
2562:
2563:                            if (IDLEntity.class.isAssignableFrom(clazz)) {
2564:                                java.lang.reflect.Method readMethod = null;
2565:                                if (clazz != org.omg.CORBA.Any.class) {
2566:                                    String helperClassName = clazz.getName()
2567:                                            + "Helper";
2568:
2569:                                    try {
2570:                                        final ClassLoader classLoader = clazz
2571:                                                .getClassLoader();
2572:                                        final Class helperClass;
2573:                                        if (classLoader == null) {
2574:                                            helperClass = ObjectUtil
2575:                                                    .classForName(helperClassName);
2576:                                        } else {
2577:                                            helperClass = classLoader
2578:                                                    .loadClass(helperClassName);
2579:                                        }
2580:
2581:                                        Class[] paramTypes = { org.omg.CORBA.portable.InputStream.class };
2582:                                        readMethod = helperClass.getMethod(
2583:                                                "read", paramTypes);
2584:                                    } catch (ClassNotFoundException e) {
2585:                                        throw new MARSHAL(
2586:                                                "Error loading class "
2587:                                                        + helperClassName
2588:                                                        + ": " + e);
2589:                                    } catch (NoSuchMethodException e) {
2590:                                        throw new MARSHAL(
2591:                                                "No read method in helper class "
2592:                                                        + helperClassName
2593:                                                        + ": " + e);
2594:                                    }
2595:                                }
2596:
2597:                                if (readMethod == null) {
2598:                                    result = read_any();
2599:                                } else {
2600:                                    try {
2601:                                        result = (java.io.Serializable) readMethod
2602:                                                .invoke(
2603:                                                        null,
2604:                                                        new java.lang.Object[] { this  });
2605:                                    } catch (IllegalAccessException e) {
2606:                                        throw new MARSHAL("Internal error: "
2607:                                                + e);
2608:                                    } catch (java.lang.reflect.InvocationTargetException e) {
2609:                                        throw new MARSHAL(
2610:                                                "Exception unmarshaling IDLEntity: "
2611:                                                        + e
2612:                                                                .getTargetException());
2613:                                    }
2614:                                }
2615:                            } else {
2616:                                result = ValueHandler.readValue(this , index,
2617:                                        clazz, repository_ids[i], null);
2618:                            }
2619:                        } catch (ClassNotFoundException e) {
2620:                            if (i < repository_ids.length - 1) {
2621:                                continue;
2622:                            }
2623:
2624:                            throw new MARSHAL("class not found: " + className);
2625:                        }
2626:                    }
2627:                }
2628:
2629:                // value type instances may be null...
2630:                if (result != null) {
2631:                    getValueMap().put(ObjectUtil.newInteger(index), result);
2632:                }
2633:
2634:                return result;
2635:            }
2636:
2637:            /** Load the value's class, using the context class loader
2638:             *  of the current thread if possible.  Here's Francisco
2639:             *  Reverbel's <reverbel@ime.usp.br> explanation of why
2640:             *  this is needed in JBoss:
2641:             *
2642:             *  "It seems that ValueHandler.loadClass() uses the thread
2643:             *  context classloader only after it looks for other
2644:             *  classloaders in the call stack (weird). In some
2645:             *  situations (when EJBs are undeployed and then
2646:             *  redeployed) it finds in the call stack a classloader
2647:             *  used for an undeployed EJB. A value of class Foo is
2648:             *  then unmarshalled with type
2649:             *  classloaderOfEJB1:Foo, when the expected type is
2650:             *  classloaderOfEJB2:Foo. I am getting ClassCastExceptions is this
2651:             *  situation.
2652:             *  Explicitly using the thread context class loader in the
2653:             *  first place solves the problem."
2654:             */
2655:            private Class loadClass(String className, final String codebase)
2656:                    throws ClassNotFoundException {
2657:                Class clazz;
2658:                //#ifjdk 1.2
2659:                ClassLoader clazzLoader = Thread.currentThread()
2660:                        .getContextClassLoader();
2661:                //#else
2662:                //# ClassLoader ctxcl = null;
2663:                //#endif
2664:
2665:                if (clazzLoader == null) {
2666:                    clazz = ValueHandler.loadClass(className, codebase, null);
2667:                } else {
2668:                    try {
2669:                        clazz = clazzLoader.loadClass(className);
2670:                    } catch (ClassNotFoundException e) {
2671:                        clazz = ValueHandler.loadClass(className, codebase,
2672:                                null);
2673:                    }
2674:                }
2675:                return clazz;
2676:            }
2677:
2678:            /**
2679:             * try to read in the chunk size.
2680:             * special handling if there's no chunk size
2681:             * in the stream.
2682:             */
2683:            private int readChunkSizeTag() {
2684:                int savedPos = pos;
2685:                int savedIndex = index;
2686:                int chunk_size_tag = read_long();
2687:
2688:                if (!sunInteropFix || chunk_size_tag > 0
2689:                        && chunk_size_tag < MAX_BLOCK_SIZE) {
2690:                    // looks like the correct chunk size
2691:                    return chunk_size_tag;
2692:                }
2693:
2694:                // reset buffer
2695:                pos = savedPos;
2696:                index = savedIndex;
2697:                return MAX_BLOCK_SIZE;
2698:            }
2699:
2700:            /**
2701:             * Reads a value with type information, i.e. one that is preceded
2702:             * by a single RepositoryID.  It is assumed that the tag and the codebase
2703:             * of the value have already been read.
2704:             */
2705:            private java.io.Serializable read_typed_value(final int index,
2706:                    final String codebase) {
2707:                return read_untyped_value(
2708:                        new String[] { read_repository_id() }, index, codebase);
2709:            }
2710:
2711:            /**
2712:             * Reads a value with type information, i.e. one that is preceded
2713:             * by an array of RepositoryIDs.  It is assumed that the tag and the codebase
2714:             * of the value have already been read.
2715:             */
2716:            private java.io.Serializable read_multi_typed_value(
2717:                    final int index, final String codebase) {
2718:                int id_count = read_long();
2719:                String[] ids = new String[id_count];
2720:
2721:                for (int i = 0; i < id_count; i++) {
2722:                    ids[i] = read_repository_id();
2723:                }
2724:
2725:                return read_untyped_value(ids, index, codebase);
2726:            }
2727:
2728:            /**
2729:             * Reads a RepositoryID from the buffer, either directly or via
2730:             * indirection.
2731:             */
2732:            private String read_repository_id() {
2733:                int tag = read_long();
2734:                if (tag == 0xffffffff) {
2735:                    // indirection
2736:                    int index = read_long();
2737:                    index = index + pos - 4;
2738:
2739:                    String repId = (String) getRepIdMap().get(
2740:                            ObjectUtil.newInteger(index));
2741:                    if (repId == null) {
2742:                        throw new MARSHAL("stale RepositoryID indirection");
2743:                    }
2744:                    return repId;
2745:                }
2746:
2747:                // a new id
2748:                pos -= 4;
2749:                index -= 4;
2750:                int start_offset = pos;
2751:                String repId = read_string();
2752:
2753:                getRepIdMap().put(ObjectUtil.newInteger(start_offset), repId);
2754:                return repId;
2755:            }
2756:
2757:            /**
2758:             * Reads a codebase from the buffer, either directly or via
2759:             * indirection.
2760:             */
2761:            private String read_codebase() {
2762:                int tag = read_long();
2763:
2764:                if (tag == 0xffffffff) {
2765:                    // indirection
2766:                    int index = read_long();
2767:                    index = index + pos - 4;
2768:                    String codebase = (String) getCodebaseMap().get(
2769:                            ObjectUtil.newInteger(index));
2770:                    if (codebase == null) {
2771:                        throw new MARSHAL("stale codebase indirection");
2772:                    }
2773:
2774:                    return codebase;
2775:                }
2776:                // a new codebase string
2777:                pos -= 4;
2778:                index -= 4;
2779:                int start_offset = pos;
2780:                String codebase = read_string();
2781:                getCodebaseMap().put(ObjectUtil.newInteger(start_offset),
2782:                        codebase);
2783:                return codebase;
2784:            }
2785:
2786:            /**
2787:             * Reads an indirect value from this stream. It is assumed that the
2788:             * value tag (0xffffffff) has already been read.
2789:             */
2790:            private java.io.Serializable read_indirect_value() {
2791:                // indirection
2792:                int index = read_long();
2793:                index = index + pos - 4;
2794:                java.lang.Object value = getValueMap().get(
2795:                        ObjectUtil.newInteger(index));
2796:
2797:                if (value == null) {
2798:                    // Java to IDL Language Mapping, v1.1, page 1-44:
2799:                    //
2800:                    // "The ValueHandler object may receive an IndirectionException
2801:                    // from the ORB stream. The ORB input stream throws this exception
2802:                    // when it is called to unmarshal a value encoded as an indirection
2803:                    // that is in the process of being unmarshaled. This can occur when
2804:                    // the ORB stream calls the ValueHandler object to unmarshal an RMI
2805:                    // value whose state contains a recursive reference to itself.
2806:                    // Because the top-level ValueHandler.readValue call has not yet
2807:                    // returned a value, the ORB stream's indirection table contains no
2808:                    // entry for an object with the stream offset specified by the
2809:                    // indirection tag. This stream offset is returned in the
2810:                    // exception's offset field."
2811:
2812:                    throw new org.omg.CORBA.portable.IndirectionException(index);
2813:                }
2814:
2815:                return (java.io.Serializable) value;
2816:            }
2817:
2818:            private String validateName(String name) {
2819:                if (name != null && name.length() == 0) {
2820:                    return null;
2821:                }
2822:                return name;
2823:            }
2824:
2825:            private String validateID(String id) {
2826:                if (id == null || id.length() == 0) {
2827:                    return "IDL:";
2828:                }
2829:                return id;
2830:            }
2831:
2832:            /**
2833:             * Reads an abstract interface from this stream. The abstract interface
2834:             * Reads an abstract interface from this stream. The abstract interface
2835:             * appears as a union with a boolean discriminator, which is true if the
2836:             * union contains a CORBA object reference, or false if the union contains
2837:             * a value.
2838:             */
2839:            public java.lang.Object read_abstract_interface() {
2840:                return read_boolean() ? (java.lang.Object) read_Object()
2841:                        : (java.lang.Object) read_value();
2842:            }
2843:
2844:            /**
2845:             * Reads an abstract interface from this stream. The abstract interface
2846:             * appears as a union with a boolean discriminator, which is true if the
2847:             * union contains a CORBA object reference, or false if the union contains
2848:             * a value.
2849:             */
2850:            public java.lang.Object read_abstract_interface(
2851:                    final java.lang.Class clazz) {
2852:                return read_boolean() ? (java.lang.Object) read_Object(clazz)
2853:                        : (java.lang.Object) read_value(clazz);
2854:            }
2855:
2856:            public int get_pos() {
2857:                return pos;
2858:            }
2859:
2860:            /**
2861:             * Stores `value' into this stream's valueMap.  This is provided
2862:             * as a callback for value factories, so that a value factory can
2863:             * store an object into the map before actually reading its state.
2864:             * This is essential for unmarshalling recursive values.
2865:             */
2866:            public void register_value(final java.io.Serializable value) {
2867:                getValueMap().put(ObjectUtil.newInteger(currentValueIndex),
2868:                        value);
2869:            }
2870:
2871:            /**
2872:             * <code>updateMutatorConnection</code> is an accessor that updates the
2873:             * ior mutator.
2874:             *
2875:             * By making callers pass in a GIOPConnection not a transport this allows
2876:             * callers to not have to call getTransport which would require a synchronized
2877:             * lock. Therefore if the mutator has not been enabled this is effectively a
2878:             * NOP.
2879:             *
2880:             * @param connection an <code>org.omg.ETF.Connection</code> value
2881:             */
2882:            public void updateMutatorConnection(GIOPConnection connection) {
2883:                if (isMutatorEnabled) {
2884:                    mutator.updateConnection(connection.getTransport());
2885:                }
2886:            }
2887:
2888:            /**
2889:             * <code>Pair</code> is merely a private storage class used by
2890:             * {@link #cachedTypecodes}.
2891:             */
2892:            private static final class Pair {
2893:                /**
2894:                 * <code>first</code> is the typecode we are caching.
2895:                 */
2896:                public final org.omg.CORBA.TypeCode typeCode;
2897:                /**
2898:                 * <code>second</code> is the location the original typecode was found.
2899:                 */
2900:                public final Integer position;
2901:
2902:                /**
2903:                 * Create a new <code>Pair</code>.
2904:                 *
2905:                 * @param typeCode an <code>org.omg.CORBA.TypeCode</code> value
2906:                 * @param position an <code>Integer</code> value
2907:                 */
2908:                public Pair(org.omg.CORBA.TypeCode typeCode, Integer position) {
2909:                    this .typeCode = typeCode;
2910:                    this .position = position;
2911:                }
2912:
2913:                /**
2914:                 * <code>toString</code> used for debugging ONLY.
2915:                 *
2916:                 * @return a <code>String</code> value
2917:                 */
2918:                public String toString() {
2919:                    return (typeCode + " and " + position);
2920:                }
2921:            }
2922:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.