src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java

Thu, 31 Aug 2017 18:10:36 +0800

author
aoqi
date
Thu, 31 Aug 2017 18:10:36 +0800
changeset 748
6845b95cba6b
parent 443
3c73273667ae
parent 0
7ef37b2cdcad
child 1655
bfd167e38830
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 /*
    27  * Licensed Materials - Property of IBM
    28  * RMI-IIOP v1.0
    29  * Copyright IBM Corp. 1998 1999  All Rights Reserved
    30  *
    31  */
    33 package com.sun.corba.se.impl.encoding;
    35 import java.io.IOException;
    36 import java.io.Serializable;
    37 import java.io.ByteArrayInputStream;
    38 import java.io.ObjectInputStream;
    39 import java.io.IOException;
    40 import java.io.StreamCorruptedException;
    41 import java.io.OptionalDataException;
    42 import java.io.IOException;
    44 import java.util.Stack;
    46 import java.net.URL;
    47 import java.net.MalformedURLException;
    49 import java.nio.ByteBuffer;
    51 import java.lang.reflect.InvocationTargetException;
    52 import java.lang.reflect.Method;
    54 import java.math.BigDecimal;
    56 import java.rmi.Remote;
    57 import java.rmi.StubNotFoundException;
    59 import java.security.AccessController;
    60 import java.security.PrivilegedExceptionAction;
    61 import java.security.PrivilegedActionException;
    63 import org.omg.CORBA.SystemException;
    64 import org.omg.CORBA.Object;
    65 import org.omg.CORBA.Principal;
    66 import org.omg.CORBA.TypeCode;
    67 import org.omg.CORBA.Any;
    68 import org.omg.CORBA.portable.Delegate;
    69 import org.omg.CORBA.portable.ValueBase;
    70 import org.omg.CORBA.portable.IndirectionException;
    71 import org.omg.CORBA.CompletionStatus;
    72 import org.omg.CORBA.TCKind;
    73 import org.omg.CORBA.TypeCodePackage.BadKind;
    74 import org.omg.CORBA.CustomMarshal;
    75 import org.omg.CORBA.TypeCode;
    76 import org.omg.CORBA.Principal;
    77 import org.omg.CORBA.Any;
    78 import org.omg.CORBA.portable.BoxedValueHelper;
    79 import org.omg.CORBA.portable.ValueFactory;
    80 import org.omg.CORBA.portable.CustomValue;
    81 import org.omg.CORBA.portable.StreamableValue;
    82 import org.omg.CORBA.MARSHAL;
    83 import org.omg.CORBA.portable.IDLEntity;
    85 import javax.rmi.PortableRemoteObject;
    86 import javax.rmi.CORBA.Tie;
    87 import javax.rmi.CORBA.Util;
    88 import javax.rmi.CORBA.ValueHandler;
    90 import com.sun.corba.se.pept.protocol.MessageMediator;
    91 import com.sun.corba.se.pept.transport.ByteBufferPool;
    93 import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
    94 import com.sun.corba.se.spi.protocol.CorbaClientDelegate;
    96 import com.sun.corba.se.spi.ior.IOR;
    97 import com.sun.corba.se.spi.ior.IORFactories;
    98 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
   100 import com.sun.corba.se.spi.orb.ORB;
   101 import com.sun.corba.se.spi.orb.ORBVersionFactory;
   102 import com.sun.corba.se.spi.orb.ORBVersion;
   104 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
   106 import com.sun.corba.se.spi.logging.CORBALogDomains;
   107 import com.sun.corba.se.spi.presentation.rmi.PresentationManager;
   108 import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
   109 import com.sun.corba.se.spi.presentation.rmi.PresentationDefaults;
   111 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
   112 import com.sun.corba.se.impl.logging.OMGSystemException;
   114 import com.sun.corba.se.impl.corba.PrincipalImpl;
   115 import com.sun.corba.se.impl.corba.TypeCodeImpl;
   116 import com.sun.corba.se.impl.corba.CORBAObjectImpl;
   118 import com.sun.corba.se.impl.encoding.CDROutputObject;
   119 import com.sun.corba.se.impl.encoding.CodeSetConversion;
   121 import com.sun.corba.se.impl.util.Utility;
   122 import com.sun.corba.se.impl.util.RepositoryId;
   124 import com.sun.corba.se.impl.orbutil.RepositoryIdStrings;
   125 import com.sun.corba.se.impl.orbutil.RepositoryIdInterface;
   126 import com.sun.corba.se.impl.orbutil.RepositoryIdUtility;
   127 import com.sun.corba.se.impl.orbutil.RepositoryIdFactory;
   129 import com.sun.corba.se.impl.orbutil.ORBUtility;
   130 import com.sun.corba.se.impl.orbutil.CacheTable;
   133 import com.sun.org.omg.CORBA.portable.ValueHelper;
   135 import com.sun.org.omg.SendingContext.CodeBase;
   137 public class CDRInputStream_1_0 extends CDRInputStreamBase
   138     implements RestorableInputStream
   139 {
   140     private static final String kReadMethod = "read";
   141     private static final int maxBlockLength = 0x7fffff00;
   143     protected BufferManagerRead bufferManagerRead;
   144     protected ByteBufferWithInfo bbwi;
   146     // Set to the ORB's transportDebugFlag value.  This value is
   147     // used if the ORB is null.
   148     private boolean debug = false;
   150     protected boolean littleEndian;
   151     protected ORB orb;
   152     protected ORBUtilSystemException wrapper ;
   153     protected OMGSystemException omgWrapper ;
   154     protected ValueHandler valueHandler = null;
   156     // Value cache
   157     private CacheTable valueCache = null;
   159     // Repository ID cache
   160     private CacheTable repositoryIdCache = null;
   162     // codebase cache
   163     private CacheTable codebaseCache = null;
   165     // Current Class Stack (repository Ids of current class being read)
   166     // private Stack currentStack = null;
   168     // Length of current chunk, or a large positive number if not in a chunk
   169     protected int blockLength = maxBlockLength;
   171     // Read end flag (value nesting depth)
   172     protected int end_flag = 0;
   174     // Beginning with the resolution to interop issue 3526 (4328?),
   175     // only enclosing chunked valuetypes are taken into account
   176     // when computing the nesting level.  However, we still need
   177     // the old computation around for interoperability with our
   178     // older ORBs.
   179     private int chunkedValueNestingLevel = 0;
   181     // Flag used to determine whether blocksize was zero
   182     // private int checkForNullBlock = -1;
   184     // In block flag
   185     // private boolean inBlock = false;
   187     // Indicates whether we are inside a value
   188     // private boolean outerValueDone = true;
   190     // Int used by read_value(Serializable) that is set by this class
   191     // before calling ValueFactory.read_value
   192     protected int valueIndirection = 0;
   194     // Int set by readStringOrIndirection to communicate the actual
   195     // offset of the string length field back to the caller
   196     protected int stringIndirection = 0;
   198     // Flag indicating whether we are unmarshalling a chunked value
   199     protected boolean isChunked = false;
   201     // Repository ID handlers
   202     private RepositoryIdUtility repIdUtil;
   203     private RepositoryIdStrings repIdStrs;
   205     // Code set converters (created when first needed)
   206     private CodeSetConversion.BTCConverter charConverter;
   207     private CodeSetConversion.BTCConverter wcharConverter;
   209     // RMI-IIOP stream format version 2 case in which we know
   210     // that there is no more optional data available.  If the
   211     // Serializable's readObject method tries to read anything,
   212     // we must throw a MARSHAL with the special minor code
   213     // so that the ValueHandler can give the correct exception
   214     // to readObject.  The state is cleared when the ValueHandler
   215     // calls end_value after the readObject method exits.
   216     private boolean specialNoOptionalDataState = false;
   218     // Template method
   219     public CDRInputStreamBase dup()
   220     {
   221         CDRInputStreamBase result = null ;
   223         try {
   224             result = (CDRInputStreamBase)this.getClass().newInstance();
   225         } catch (Exception e) {
   226             throw wrapper.couldNotDuplicateCdrInputStream( e ) ;
   227         }
   228         result.init(this.orb,
   229                     this.bbwi.byteBuffer,
   230                     this.bbwi.buflen,
   231                     this.littleEndian,
   232                     this.bufferManagerRead);
   234         ((CDRInputStream_1_0)result).bbwi.position(this.bbwi.position());
   235         // To ensure we keep bbwi.byteBuffer.limit in sync with bbwi.buflen.
   236         ((CDRInputStream_1_0)result).bbwi.byteBuffer.limit(this.bbwi.buflen);
   238         return result;
   239     }
   241     /**
   242      * NOTE:  size passed to init means buffer size
   243      */
   244     public void init(org.omg.CORBA.ORB orb,
   245                      ByteBuffer byteBuffer,
   246                      int size,
   247                      boolean littleEndian,
   248                      BufferManagerRead bufferManager)
   249     {
   250         this.orb = (ORB)orb;
   251         this.wrapper = ORBUtilSystemException.get( (ORB)orb,
   252             CORBALogDomains.RPC_ENCODING ) ;
   253         this.omgWrapper = OMGSystemException.get( (ORB)orb,
   254             CORBALogDomains.RPC_ENCODING ) ;
   255         this.littleEndian = littleEndian;
   256         this.bufferManagerRead = bufferManager;
   257         this.bbwi = new ByteBufferWithInfo(orb,byteBuffer,0);
   258         this.bbwi.buflen = size;
   259         this.bbwi.byteBuffer.limit(bbwi.buflen);
   260         this.markAndResetHandler = bufferManagerRead.getMarkAndResetHandler();
   262         debug = ((ORB)orb).transportDebugFlag;
   263     }
   265     // See description in CDRInputStream
   266     void performORBVersionSpecificInit() {
   267         createRepositoryIdHandlers();
   268     }
   270     private final void createRepositoryIdHandlers()
   271     {
   272         repIdUtil = RepositoryIdFactory.getRepIdUtility();
   273         repIdStrs = RepositoryIdFactory.getRepIdStringsFactory();
   274     }
   276     public GIOPVersion getGIOPVersion() {
   277         return GIOPVersion.V1_0;
   278     }
   280     // Called by Request and Reply message. Valid for GIOP versions >= 1.2 only.
   281     // Illegal for GIOP versions < 1.2.
   282     void setHeaderPadding(boolean headerPadding) {
   283         throw wrapper.giopVersionError();
   284     }
   286     protected final int computeAlignment(int index, int align) {
   287         if (align > 1) {
   288             int incr = index & (align - 1);
   289             if (incr != 0)
   290                 return align - incr;
   291         }
   293         return 0;
   294     }
   296     public int getSize()
   297     {
   298         return bbwi.position();
   299     }
   301     protected void checkBlockLength(int align, int dataSize) {
   302         // Since chunks can end at arbitrary points (though not within
   303         // primitive CDR types, arrays of primitives, strings, wstrings,
   304         // or indirections),
   305         // we must check here for termination of the current chunk.
   306         if (!isChunked)
   307             return;
   309         // RMI-IIOP stream format version 2 case in which we know
   310         // that there is no more optional data available.  If the
   311         // Serializable's readObject method tries to read anything,
   312         // we must throw a MARSHAL exception with the special minor code
   313         // so that the ValueHandler can give the correct exception
   314         // to readObject.  The state is cleared when the ValueHandler
   315         // calls end_value after the readObject method exits.
   316         if (specialNoOptionalDataState) {
   317             throw omgWrapper.rmiiiopOptionalDataIncompatible1() ;
   318         }
   320         boolean checkForEndTag = false;
   322         // Are we at the end of the current chunk?  If so,
   323         // try to interpret the next long as a chunk length.
   324         // (It has to be either a chunk length, end tag,
   325         // or valuetag.)
   326         //
   327         // If it isn't a chunk length, blockLength will
   328         // remain set to maxBlockLength.
   329         if (blockLength == get_offset()) {
   331             blockLength = maxBlockLength;
   332             start_block();
   334             // What's next is either a valuetag or
   335             // an end tag.  If it's a valuetag, we're
   336             // probably being called as part of the process
   337             // to read the valuetag.  If it's an end tag,
   338             // then there isn't enough data left in
   339             // this valuetype to read!
   340             if (blockLength == maxBlockLength)
   341                 checkForEndTag = true;
   343         } else
   344         if (blockLength < get_offset()) {
   345             // Are we already past the end of the current chunk?
   346             // This is always an error.
   347             throw wrapper.chunkOverflow() ;
   348         }
   350         // If what's next on the wire isn't a chunk length or
   351         // what we want to read (which can't be split across chunks)
   352         // won't fit in the current chunk, throw this exception.
   353         // This probably means that we're in an RMI-IIOP
   354         // Serializable's readObject method or a custom marshaled
   355         // IDL type is reading too much/in an incorrect order
   356         int requiredNumBytes =
   357                             computeAlignment(bbwi.position(), align) + dataSize;
   359         if (blockLength != maxBlockLength &&
   360             blockLength < get_offset() + requiredNumBytes) {
   361             throw omgWrapper.rmiiiopOptionalDataIncompatible2() ;
   362         }
   364         // REVISIT - We should look at using the built in advancement
   365         //           of using ByteBuffer.get() rather than explicitly
   366         //           advancing the ByteBuffer's position.
   367         //           This is true for anywhere we are incrementing
   368         //           the ByteBuffer's position.
   369         if (checkForEndTag) {
   370             int nextLong = read_long();
   371             bbwi.position(bbwi.position() - 4);
   373             // It was an end tag, so there wasn't enough data
   374             // left in the valuetype's encoding on the wire
   375             // to read what we wanted
   376             if (nextLong < 0)
   377                 throw omgWrapper.rmiiiopOptionalDataIncompatible3() ;
   378         }
   379     }
   381     protected void alignAndCheck(int align, int n) {
   383         checkBlockLength(align, n);
   385         // WARNING: Must compute real alignment after calling
   386         // checkBlockLength since it may move the position
   387         int alignResult = computeAlignment(bbwi.position(), align);
   388         bbwi.position(bbwi.position() + alignResult);
   390         if (bbwi.position() + n > bbwi.buflen)
   391             grow(align, n);
   392     }
   394     //
   395     // This can be overridden....
   396     //
   397     protected void grow(int align, int n) {
   399         bbwi.needed = n;
   401         bbwi = bufferManagerRead.underflow(bbwi);
   403     }
   405     //
   406     // Marshal primitives.
   407     //
   409     public final void consumeEndian() {
   410         littleEndian = read_boolean();
   411     }
   413     // No such type in java
   414     public final double read_longdouble() {
   415         throw wrapper.longDoubleNotImplemented( CompletionStatus.COMPLETED_MAYBE);
   416     }
   418     public final boolean read_boolean() {
   419         return (read_octet() != 0);
   420     }
   422     public final char read_char() {
   423         alignAndCheck(1, 1);
   425         return getConvertedChars(1, getCharConverter())[0];
   426     }
   428     public char read_wchar() {
   430         // Don't allow transmission of wchar/wstring data with
   431         // foreign ORBs since it's against the spec.
   432         if (ORBUtility.isForeignORB((ORB)orb)) {
   433             throw wrapper.wcharDataInGiop10( CompletionStatus.COMPLETED_MAYBE);
   434         }
   436         // If we're talking to one of our legacy ORBs, do what
   437         // they did:
   438         int b1, b2;
   440         alignAndCheck(2, 2);
   442         if (littleEndian) {
   443             b2 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF;
   444             bbwi.position(bbwi.position() + 1);
   445             b1 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF;
   446             bbwi.position(bbwi.position() + 1);
   447         } else {
   448             b1 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF;
   449             bbwi.position(bbwi.position() + 1);
   450             b2 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF;
   451             bbwi.position(bbwi.position() + 1);
   452         }
   454         return (char)((b1 << 8) + (b2 << 0));
   455     }
   457     public final byte read_octet() {
   459         alignAndCheck(1, 1);
   461         byte b = bbwi.byteBuffer.get(bbwi.position());
   462         bbwi.position(bbwi.position() + 1);
   464         return b;
   465     }
   467     public final short read_short() {
   468         int b1, b2;
   470         alignAndCheck(2, 2);
   472         if (littleEndian) {
   473             b2 = (bbwi.byteBuffer.get(bbwi.position()) << 0) & 0x000000FF;
   474             bbwi.position(bbwi.position() + 1);
   475             b1 = (bbwi.byteBuffer.get(bbwi.position()) << 8) & 0x0000FF00;
   476             bbwi.position(bbwi.position() + 1);
   477         } else {
   478             b1 = (bbwi.byteBuffer.get(bbwi.position()) << 8) & 0x0000FF00;
   479             bbwi.position(bbwi.position() + 1);
   480             b2 = (bbwi.byteBuffer.get(bbwi.position()) << 0) & 0x000000FF;
   481             bbwi.position(bbwi.position() + 1);
   482         }
   484         return (short)(b1 | b2);
   485     }
   487     public final short read_ushort() {
   488         return read_short();
   489     }
   491     public final int read_long() {
   492         int b1, b2, b3, b4;
   494         alignAndCheck(4, 4);
   496         int bufPos = bbwi.position();
   497         if (littleEndian) {
   498             b4 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
   499             b3 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
   500             b2 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
   501             b1 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
   502         } else {
   503             b1 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
   504             b2 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
   505             b3 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
   506             b4 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
   507         }
   508         bbwi.position(bufPos);
   510         return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
   511     }
   513     public final int read_ulong() {
   514         return read_long();
   515     }
   517     public final long read_longlong() {
   518         long i1, i2;
   520         alignAndCheck(8, 8);
   522         if (littleEndian) {
   523             i2 = read_long() & 0xFFFFFFFFL;
   524             i1 = (long)read_long() << 32;
   525         } else {
   526             i1 = (long)read_long() << 32;
   527             i2 = read_long() & 0xFFFFFFFFL;
   528         }
   530         return (i1 | i2);
   531     }
   533     public final long read_ulonglong() {
   534         return read_longlong();
   535     }
   537     public final float read_float() {
   538         return Float.intBitsToFloat(read_long());
   539     }
   541     public final double read_double() {
   542         return Double.longBitsToDouble(read_longlong());
   543     }
   545     protected final void checkForNegativeLength(int length) {
   546         if (length < 0)
   547             throw wrapper.negativeStringLength( CompletionStatus.COMPLETED_MAYBE,
   548                 new Integer(length) ) ;
   549     }
   551     protected final String readStringOrIndirection(boolean allowIndirection) {
   553         int len = read_long();
   555         //
   556         // Check for indirection
   557         //
   558         if (allowIndirection) {
   559             if (len == 0xffffffff)
   560                 return null;
   561             else
   562                 stringIndirection = get_offset() - 4;
   563         }
   565         checkForNegativeLength(len);
   567         return internalReadString(len);
   568     }
   570     private final String internalReadString(int len) {
   571         // Workaround for ORBs which send string lengths of
   572         // zero to mean empty string.
   573         //
   574         // IMPORTANT: Do not replace 'new String("")' with "", it may result
   575         // in a Serialization bug (See serialization.zerolengthstring) and
   576         // bug id: 4728756 for details
   577         if (len == 0)
   578             return new String("");
   580         char[] result = getConvertedChars(len - 1, getCharConverter());
   582         // Skip over the 1 byte null
   583         read_octet();
   585         return new String(result, 0, getCharConverter().getNumChars());
   586     }
   588     public final String read_string() {
   589         return readStringOrIndirection(false);
   590     }
   592     public String read_wstring() {
   593         // Don't allow transmission of wchar/wstring data with
   594         // foreign ORBs since it's against the spec.
   595         if (ORBUtility.isForeignORB((ORB)orb)) {
   596             throw wrapper.wcharDataInGiop10( CompletionStatus.COMPLETED_MAYBE);
   597         }
   599         int len = read_long();
   601         //
   602         // Workaround for ORBs which send string lengths of
   603         // zero to mean empty string.
   604         //
   605         //
   606         // IMPORTANT: Do not replace 'new String("")' with "", it may result
   607         // in a Serialization bug (See serialization.zerolengthstring) and
   608         // bug id: 4728756 for details
   609         if (len == 0)
   610             return new String("");
   612         checkForNegativeLength(len);
   614         len--;
   615         char[] c = new char[len];
   617         for (int i = 0; i < len; i++)
   618             c[i] = read_wchar();
   620         // skip the two null terminator bytes
   621         read_wchar();
   622         // bbwi.position(bbwi.position() + 2);
   624         return new String(c);
   625     }
   627     public final void read_octet_array(byte[] b, int offset, int length) {
   628         if ( b == null )
   629             throw wrapper.nullParam() ;
   631         // Must call alignAndCheck at least once to ensure
   632         // we aren't at the end of a chunk.  Of course, we
   633         // should only call it if we actually need to read
   634         // something, otherwise we might end up with an
   635         // exception at the end of the stream.
   636         if (length == 0)
   637             return;
   639         alignAndCheck(1, 1);
   641         int n = offset;
   642         while (n < length+offset) {
   643             int avail;
   644             int bytes;
   645             int wanted;
   647             avail = bbwi.buflen - bbwi.position();
   648             if (avail <= 0) {
   649                 grow(1, 1);
   650                 avail = bbwi.buflen - bbwi.position();
   651             }
   652             wanted = (length + offset) - n;
   653             bytes = (wanted < avail) ? wanted : avail;
   654             // Microbenchmarks are showing a loop of ByteBuffer.get(int) being
   655             // faster than ByteBuffer.get(byte[], int, int).
   656             for (int i = 0; i < bytes; i++) {
   657                 b[n+i] = bbwi.byteBuffer.get(bbwi.position() + i);
   658             }
   660             bbwi.position(bbwi.position() + bytes);
   662             n += bytes;
   663         }
   664     }
   666     public Principal read_Principal() {
   667         int len = read_long();
   668         byte[] pvalue = new byte[len];
   669         read_octet_array(pvalue,0,len);
   671         Principal p = new PrincipalImpl();
   672         p.name(pvalue);
   673         return p;
   674     }
   676     public TypeCode read_TypeCode() {
   677         TypeCodeImpl tc = new TypeCodeImpl(orb);
   678         tc.read_value(parent);
   679         return tc;
   680     }
   682     public Any read_any() {
   683         Any any = orb.create_any();
   684         TypeCodeImpl tc = new TypeCodeImpl(orb);
   686         // read off the typecode
   688         // REVISIT We could avoid this try-catch if we could peek the typecode
   689         // kind off this stream and see if it is a tk_value.  Looking at the
   690         // code we know that for tk_value the Any.read_value() below
   691         // ignores the tc argument anyway (except for the kind field).
   692         // But still we would need to make sure that the whole typecode,
   693         // including encapsulations, is read off.
   694         try {
   695             tc.read_value(parent);
   696         } catch (MARSHAL ex) {
   697             if (tc.kind().value() != TCKind._tk_value)
   698                 throw ex;
   699             // We can be sure that the whole typecode encapsulation has been
   700             // read off.
   701             dprintThrowable(ex);
   702         }
   703         // read off the value of the any
   704         any.read_value(parent, tc);
   706         return any;
   707     }
   709     public org.omg.CORBA.Object read_Object() {
   710         return read_Object(null);
   711     }
   713     // ------------ RMI related methods --------------------------
   715     // IDL to Java ptc-00-01-08 1.21.4.1
   716     //
   717     // The clz argument to read_Object can be either a stub
   718     // Class or the "Class object for the RMI/IDL interface type
   719     // that is statically expected."
   720     // This functions as follows:
   721     // 1. If clz==null, just use the repository ID from the stub
   722     // 2. If clz is a stub class, just use it as a static factory.
   723     //    clz is a stub class iff StubAdapter.isStubClass( clz ).
   724     //    In addition, clz is a IDL stub class iff
   725     //    IDLEntity.class.isAssignableFrom( clz ).
   726     // 3. If clz is an interface, use it to create the appropriate
   727     //    stub factory.
   728     public org.omg.CORBA.Object read_Object(Class clz)
   729     {
   730         // In any case, we must first read the IOR.
   731         IOR ior = IORFactories.makeIOR(parent) ;
   732         if (ior.isNil())
   733             return null ;
   735         PresentationManager.StubFactoryFactory sff = ORB.getStubFactoryFactory() ;
   736         String codeBase = ior.getProfile().getCodebase() ;
   737         PresentationManager.StubFactory stubFactory = null ;
   739         if (clz == null) {
   740             RepositoryId rid = RepositoryId.cache.getId( ior.getTypeId() ) ;
   741             String className = rid.getClassName() ;
   742             boolean isIDLInterface = rid.isIDLType() ;
   744             if (className == null || className.equals( "" ))
   745                 stubFactory = null ;
   746             else
   747                 try {
   748                     stubFactory = sff.createStubFactory( className,
   749                         isIDLInterface, codeBase, (Class)null,
   750                         (ClassLoader)null );
   751                 } catch (Exception exc) {
   752                     // Could not create stubFactory, so use null.
   753                     // XXX stubFactory handling is still too complex:
   754                     // Can we resolve the stubFactory question once in
   755                     // a single place?
   756                     stubFactory = null ;
   757                 }
   758         } else if (StubAdapter.isStubClass( clz )) {
   759             stubFactory = PresentationDefaults.makeStaticStubFactory(
   760                 clz ) ;
   761         } else {
   762             // clz is an interface class
   763             boolean isIDL = IDLEntity.class.isAssignableFrom( clz ) ;
   765             stubFactory = sff.createStubFactory( clz.getName(),
   766                 isIDL, codeBase, clz, clz.getClassLoader() ) ;
   767         }
   769         return internalIORToObject( ior, stubFactory, orb ) ;
   770     }
   772     /*
   773      * This is used as a general utility (e.g., the PortableInterceptor
   774      * implementation uses it.   If stubFactory is null, the ior's
   775      * IIOPProfile must support getServant.
   776      */
   777     public static org.omg.CORBA.Object internalIORToObject(
   778         IOR ior, PresentationManager.StubFactory stubFactory, ORB orb)
   779     {
   780         ORBUtilSystemException wrapper = ORBUtilSystemException.get(
   781             (ORB)orb, CORBALogDomains.RPC_ENCODING ) ;
   783         java.lang.Object servant = ior.getProfile().getServant() ;
   784         if (servant != null ) {
   785             if (servant instanceof Tie) {
   786                 String codebase = ior.getProfile().getCodebase();
   787                 org.omg.CORBA.Object objref = (org.omg.CORBA.Object)
   788                     Utility.loadStub( (Tie)servant, stubFactory, codebase,
   789                         false);
   791                 // If we managed to load a stub, return it, otherwise we
   792                 // must fail...
   793                 if (objref != null) {
   794                     return objref;
   795                 } else {
   796                     throw wrapper.readObjectException() ;
   797                 }
   798             } else if (servant instanceof org.omg.CORBA.Object) {
   799                 if (!(servant instanceof
   800                         org.omg.CORBA.portable.InvokeHandler)) {
   801                     return (org.omg.CORBA.Object) servant;
   802                 }
   803             } else
   804                 throw wrapper.badServantReadObject() ;
   805         }
   807         CorbaClientDelegate del = ORBUtility.makeClientDelegate( ior ) ;
   808         org.omg.CORBA.Object objref = null ;
   809         try {
   810             objref = stubFactory.makeStub() ;
   811         } catch (Throwable e) {
   812             wrapper.stubCreateError( e ) ;
   814             if (e instanceof ThreadDeath) {
   815                 throw (ThreadDeath) e;
   816             }
   818             // Return the "default" stub...
   819             objref = new CORBAObjectImpl() ;
   820         }
   822         StubAdapter.setDelegate( objref, del ) ;
   823         return objref;
   824     }
   826     public java.lang.Object read_abstract_interface()
   827     {
   828         return read_abstract_interface(null);
   829     }
   831     public java.lang.Object read_abstract_interface(java.lang.Class clz)
   832     {
   833         boolean object = read_boolean();
   835         if (object) {
   836             return read_Object(clz);
   837         } else {
   838             return read_value();
   839         }
   840     }
   842     public Serializable read_value()
   843     {
   844         return read_value((Class)null);
   845     }
   847     private Serializable handleIndirection() {
   848         int indirection = read_long() + get_offset() - 4;
   849         if (valueCache != null && valueCache.containsVal(indirection)) {
   851             java.io.Serializable cachedValue
   852                 = (java.io.Serializable)valueCache.getKey(indirection);
   853             return cachedValue;
   854         } else {
   855             // In RMI-IIOP the ValueHandler will recognize this
   856             // exception and use the provided indirection value
   857             // to lookup a possible indirection to an object
   858             // currently on the deserialization stack.
   859             throw new IndirectionException(indirection);
   860         }
   861     }
   863     private String readRepositoryIds(int valueTag,
   864                                      Class expectedType,
   865                                      String expectedTypeRepId) {
   866         return readRepositoryIds(valueTag, expectedType,
   867                                  expectedTypeRepId, null);
   868     }
   870     /**
   871      * Examines the valuetag to see how many (if any) repository IDs
   872      * are present on the wire.  If no repository ID information
   873      * is on the wire but the expectedType or expectedTypeRepId
   874      * is known, it will return one of those (favoring the
   875      * expectedType's repId). Failing that, it uses the supplied
   876      * BoxedValueHelper to obtain the repository ID, as a last resort.
   877      */
   878     private String readRepositoryIds(int valueTag,
   879                                      Class expectedType,
   880                                      String expectedTypeRepId,
   881                                      BoxedValueHelper factory) {
   882         switch(repIdUtil.getTypeInfo(valueTag)) {
   883             case RepositoryIdUtility.NO_TYPE_INFO :
   884                 // Throw an exception if we have no repository ID info and
   885                 // no expectedType to work with.  Otherwise, how would we
   886                 // know what to unmarshal?
   887                 if (expectedType == null) {
   888                     if (expectedTypeRepId != null) {
   889                         return expectedTypeRepId;
   890                     } else if (factory != null) {
   891                         return factory.get_id();
   892                     } else {
   893                         throw wrapper.expectedTypeNullAndNoRepId(
   894                             CompletionStatus.COMPLETED_MAYBE);
   895                     }
   896                 }
   897                 return repIdStrs.createForAnyType(expectedType);
   898             case RepositoryIdUtility.SINGLE_REP_TYPE_INFO :
   899                 return read_repositoryId();
   900             case RepositoryIdUtility.PARTIAL_LIST_TYPE_INFO :
   901                 return read_repositoryIds();
   902             default:
   903                 throw wrapper.badValueTag( CompletionStatus.COMPLETED_MAYBE,
   904                     Integer.toHexString(valueTag) ) ;
   905         }
   906     }
   908     public Serializable read_value(Class expectedType) {
   910         // Read value tag
   911         int vType = readValueTag();
   913         // Is value null?
   914         if (vType == 0)
   915             return null;
   917         // Is this an indirection to a previously
   918         // read valuetype?
   919         if (vType == 0xffffffff)
   920             return handleIndirection();
   922         // Save where this valuetype started so we
   923         // can put it in the indirection valueCache
   924         // later
   925         int indirection = get_offset() - 4;
   927         // Need to save this special marker variable
   928         // to restore its value during recursion
   929         boolean saveIsChunked = isChunked;
   931         isChunked = repIdUtil.isChunkedEncoding(vType);
   933         java.lang.Object value = null;
   935         String codebase_URL = null;
   936         if (repIdUtil.isCodeBasePresent(vType)) {
   937             codebase_URL = read_codebase_URL();
   938         }
   940         // Read repository id(s)
   941         String repositoryIDString
   942             = readRepositoryIds(vType, expectedType, null);
   944         // If isChunked was determined to be true based
   945         // on the valuetag, this will read a chunk length
   946         start_block();
   948         // Remember that end_flag keeps track of all nested
   949         // valuetypes and is used for older ORBs
   950         end_flag--;
   951         if (isChunked)
   952             chunkedValueNestingLevel--;
   954         if (repositoryIDString.equals(repIdStrs.getWStringValueRepId())) {
   955             value = read_wstring();
   956         } else
   957         if (repositoryIDString.equals(repIdStrs.getClassDescValueRepId())) {
   958             // read in the class whether with the old ClassDesc or the
   959             // new one
   960             value = readClass();
   961         } else {
   963             Class valueClass = expectedType;
   965             // By this point, either the expectedType or repositoryIDString
   966             // is guaranteed to be non-null.
   967             if (expectedType == null ||
   968                 !repositoryIDString.equals(repIdStrs.createForAnyType(expectedType))) {
   970                 valueClass = getClassFromString(repositoryIDString,
   971                                                 codebase_URL,
   972                                                 expectedType);
   973             }
   975             if (valueClass == null) {
   976                 // No point attempting to use value handler below, since the
   977                 // class information is not available.
   978                 throw wrapper.couldNotFindClass(
   979                     CompletionStatus.COMPLETED_MAYBE,
   980                     new ClassNotFoundException());
   981             }
   983             if (valueClass != null &&
   984                 org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(valueClass)) {
   986                 value =  readIDLValue(indirection,
   987                                       repositoryIDString,
   988                                       valueClass,
   989                                       codebase_URL);
   991             } else {
   993                 // Must be some form of RMI-IIOP valuetype
   995                 try {
   996                     if (valueHandler == null)
   997                         valueHandler = ORBUtility.createValueHandler();
   999                     value = valueHandler.readValue(parent,
  1000                                                    indirection,
  1001                                                    valueClass,
  1002                                                    repositoryIDString,
  1003                                                    getCodeBase());
  1005                 } catch(SystemException sysEx) {
  1006                     // Just rethrow any CORBA system exceptions
  1007                     // that come out of the ValueHandler
  1008                     throw sysEx;
  1009                 } catch(Exception ex) {
  1010                     throw wrapper.valuehandlerReadException(
  1011                         CompletionStatus.COMPLETED_MAYBE, ex ) ;
  1012                 } catch(Error e) {
  1013                     throw wrapper.valuehandlerReadError(
  1014                         CompletionStatus.COMPLETED_MAYBE, e ) ;
  1019         // Skip any remaining chunks until we get to
  1020         // an end tag or a valuetag.  If we see a valuetag,
  1021         // that means there was another valuetype in the sender's
  1022         // version of this class that we need to skip over.
  1023         handleEndOfValue();
  1025         // Read and process the end tag if we're chunking.
  1026         // Assumes that we're at the position of the end tag
  1027         // (handleEndOfValue should assure this)
  1028         readEndTag();
  1030         // Cache the valuetype that we read
  1031         if (valueCache == null)
  1032             valueCache = new CacheTable(orb,false);
  1033         valueCache.put(value, indirection);
  1035         // Allow for possible continuation chunk.
  1036         // If we're a nested valuetype inside of a chunked
  1037         // valuetype, and that enclosing valuetype has
  1038         // more data to write, it will need to have this
  1039         // new chunk begin after we wrote our end tag.
  1040         isChunked = saveIsChunked;
  1041         start_block();
  1043         return (java.io.Serializable)value;
  1046     public Serializable read_value(BoxedValueHelper factory) {
  1048         // Read value tag
  1049         int vType = readValueTag();
  1051         if (vType == 0)
  1052             return null; // value is null
  1053         else if (vType == 0xffffffff) { // Indirection tag
  1054             int indirection = read_long() + get_offset() - 4;
  1055             if (valueCache != null && valueCache.containsVal(indirection))
  1057                     java.io.Serializable cachedValue =
  1058                            (java.io.Serializable)valueCache.getKey(indirection);
  1059                     return cachedValue;
  1061             else {
  1062                 throw new IndirectionException(indirection);
  1065         else {
  1066             int indirection = get_offset() - 4;
  1068             // end_block();
  1070             boolean saveIsChunked = isChunked;
  1071             isChunked = repIdUtil.isChunkedEncoding(vType);
  1073             java.lang.Object value = null;
  1075             String codebase_URL = null;
  1076             if (repIdUtil.isCodeBasePresent(vType)){
  1077                 codebase_URL = read_codebase_URL();
  1080             // Read repository id
  1081             String repositoryIDString
  1082                 = readRepositoryIds(vType, null, null, factory);
  1084             // Compare rep. ids to see if we should use passed helper
  1085             if (!repositoryIDString.equals(factory.get_id()))
  1086                 factory = Utility.getHelper(null, codebase_URL, repositoryIDString);
  1088             start_block();
  1089             end_flag--;
  1090             if (isChunked)
  1091                 chunkedValueNestingLevel--;
  1093             if (factory instanceof ValueHelper) {
  1094                 value = readIDLValueWithHelper((ValueHelper)factory, indirection);
  1095             } else {
  1096                 valueIndirection = indirection;  // for callback
  1097                 value = factory.read_value(parent);
  1100             handleEndOfValue();
  1101             readEndTag();
  1103             // Put into valueCache
  1104             if (valueCache == null)
  1105                 valueCache = new CacheTable(orb,false);
  1106             valueCache.put(value, indirection);
  1108             // allow for possible continuation chunk
  1109             isChunked = saveIsChunked;
  1110             start_block();
  1112             return (java.io.Serializable)value;
  1116     private boolean isCustomType(ValueHelper helper) {
  1117         try{
  1118             TypeCode tc = helper.get_type();
  1119             int kind = tc.kind().value();
  1120             if (kind == TCKind._tk_value) {
  1121                 return (tc.type_modifier() == org.omg.CORBA.VM_CUSTOM.value);
  1123         } catch(BadKind ex) {
  1124             throw wrapper.badKind(ex) ;
  1127         return false;
  1130     // This method is actually called indirectly by
  1131     // read_value(String repositoryId).
  1132     // Therefore, it is not a truly independent read call that handles
  1133     // header information itself.
  1134     public java.io.Serializable read_value(java.io.Serializable value) {
  1136         // Put into valueCache using valueIndirection
  1137         if (valueCache == null)
  1138             valueCache = new CacheTable(orb,false);
  1139         valueCache.put(value, valueIndirection);
  1141         if (value instanceof StreamableValue)
  1142             ((StreamableValue)value)._read(parent);
  1143         else if (value instanceof CustomValue)
  1144             ((CustomValue)value).unmarshal(parent);
  1146         return value;
  1149     public java.io.Serializable read_value(java.lang.String repositoryId) {
  1151         // if (inBlock)
  1152         //    end_block();
  1154         // Read value tag
  1155         int vType = readValueTag();
  1157         if (vType == 0)
  1158             return null; // value is null
  1159         else if (vType == 0xffffffff) { // Indirection tag
  1160             int indirection = read_long() + get_offset() - 4;
  1161             if (valueCache != null && valueCache.containsVal(indirection))
  1163                     java.io.Serializable cachedValue =
  1164                           (java.io.Serializable)valueCache.getKey(indirection);
  1165                     return cachedValue;
  1167             else {
  1168                 throw new IndirectionException(indirection);
  1171         else {
  1172             int indirection = get_offset() - 4;
  1174             // end_block();
  1176             boolean saveIsChunked = isChunked;
  1177             isChunked = repIdUtil.isChunkedEncoding(vType);
  1179             java.lang.Object value = null;
  1181             String codebase_URL = null;
  1182             if (repIdUtil.isCodeBasePresent(vType)){
  1183                 codebase_URL = read_codebase_URL();
  1186             // Read repository id
  1187             String repositoryIDString
  1188                 = readRepositoryIds(vType, null, repositoryId);
  1190             ValueFactory factory =
  1191                Utility.getFactory(null, codebase_URL, orb, repositoryIDString);
  1193             start_block();
  1194             end_flag--;
  1195             if (isChunked)
  1196                 chunkedValueNestingLevel--;
  1198             valueIndirection = indirection;  // for callback
  1199             value = factory.read_value(parent);
  1201             handleEndOfValue();
  1202             readEndTag();
  1204             // Put into valueCache
  1205             if (valueCache == null)
  1206                 valueCache = new CacheTable(orb,false);
  1207             valueCache.put(value, indirection);
  1209             // allow for possible continuation chunk
  1210             isChunked = saveIsChunked;
  1211             start_block();
  1213             return (java.io.Serializable)value;
  1217     private Class readClass() {
  1219         String codebases = null, classRepId = null;
  1221         if (orb == null ||
  1222             ORBVersionFactory.getFOREIGN().equals(orb.getORBVersion()) ||
  1223             ORBVersionFactory.getNEWER().compareTo(orb.getORBVersion()) <= 0) {
  1225             codebases = (String)read_value(java.lang.String.class);
  1226             classRepId = (String)read_value(java.lang.String.class);
  1227         } else {
  1228             // Pre-Merlin/J2EE 1.3 ORBs wrote the repository ID
  1229             // and codebase strings in the wrong order.
  1230             classRepId = (String)read_value(java.lang.String.class);
  1231             codebases = (String)read_value(java.lang.String.class);
  1234         if (debug) {
  1235             dprint("readClass codebases: "
  1236                    + codebases
  1237                    + " rep Id: "
  1238                    + classRepId);
  1241         Class cl = null;
  1243         RepositoryIdInterface repositoryID
  1244             = repIdStrs.getFromString(classRepId);
  1246         try {
  1247             cl = repositoryID.getClassFromType(codebases);
  1248         } catch(ClassNotFoundException cnfe) {
  1249             throw wrapper.cnfeReadClass( CompletionStatus.COMPLETED_MAYBE,
  1250                 cnfe, repositoryID.getClassName() ) ;
  1251         } catch(MalformedURLException me) {
  1252             throw wrapper.malformedUrl( CompletionStatus.COMPLETED_MAYBE,
  1253                 me, repositoryID.getClassName(), codebases ) ;
  1256         return cl;
  1259     private java.lang.Object readIDLValueWithHelper(ValueHelper helper, int indirection)
  1261         // look for two-argument static read method
  1262         Method readMethod;
  1263         try {
  1264             Class argTypes[] = {org.omg.CORBA.portable.InputStream.class, helper.get_class()};
  1265             readMethod = helper.getClass().getDeclaredMethod(kReadMethod, argTypes);
  1267         catch(NoSuchMethodException nsme) { // must be boxed value helper
  1268             java.lang.Object result = helper.read_value(parent);
  1269             return result;
  1272         // found two-argument read method, so must be non-boxed value...
  1273         // ...create a blank instance
  1274         java.lang.Object val = null;
  1275         try {
  1276             val = helper.get_class().newInstance();
  1277         } catch(java.lang.InstantiationException ie) {
  1278             throw wrapper.couldNotInstantiateHelper( ie,
  1279                 helper.get_class() ) ;
  1280         } catch(IllegalAccessException iae){
  1281             // Value's constructor is protected or private
  1282             //
  1283             // So, use the helper to read the value.
  1284             //
  1285             // NOTE : This means that in this particular case a recursive ref.
  1286             // would fail.
  1287             return helper.read_value(parent);
  1290         // add blank instance to cache table
  1291         if (valueCache == null)
  1292             valueCache = new CacheTable(orb,false);
  1293         valueCache.put(val, indirection);
  1295         // if custom type, call unmarshal method
  1296         if (val instanceof CustomMarshal && isCustomType(helper)) {
  1297             ((CustomMarshal)val).unmarshal(parent);
  1298             return val;
  1301         // call two-argument read method using reflection
  1302         try {
  1303             java.lang.Object args[] = {parent, val};
  1304             readMethod.invoke(helper, args);
  1305             return val;
  1306         } catch(IllegalAccessException iae2) {
  1307             throw wrapper.couldNotInvokeHelperReadMethod( iae2, helper.get_class() ) ;
  1308         } catch(InvocationTargetException ite){
  1309             throw wrapper.couldNotInvokeHelperReadMethod( ite, helper.get_class() ) ;
  1313     private java.lang.Object readBoxedIDLEntity(Class clazz, String codebase)
  1315         Class cls = null ;
  1317         try {
  1318             ClassLoader clazzLoader = (clazz == null ? null : clazz.getClassLoader());
  1320             cls = Utility.loadClassForClass(clazz.getName()+"Helper", codebase,
  1321                                                    clazzLoader, clazz, clazzLoader);
  1322             final Class helperClass = cls ;
  1324             final Class argTypes[] = {org.omg.CORBA.portable.InputStream.class};
  1326             // getDeclaredMethod requires RuntimePermission accessDeclaredMembers
  1327             // if a different class loader is used (even though the javadoc says otherwise)
  1328             Method readMethod = null;
  1329             try {
  1330                 readMethod = (Method)AccessController.doPrivileged(
  1331                     new PrivilegedExceptionAction() {
  1332                         public java.lang.Object run() throws NoSuchMethodException {
  1333                             return helperClass.getDeclaredMethod(kReadMethod, argTypes);
  1336                 );
  1337             } catch (PrivilegedActionException pae) {
  1338                 // this gets caught below
  1339                 throw (NoSuchMethodException)pae.getException();
  1342             java.lang.Object args[] = {parent};
  1343             return readMethod.invoke(null, args);
  1345         } catch (ClassNotFoundException cnfe) {
  1346             throw wrapper.couldNotInvokeHelperReadMethod( cnfe, cls ) ;
  1347         } catch(NoSuchMethodException nsme) {
  1348             throw wrapper.couldNotInvokeHelperReadMethod( nsme, cls ) ;
  1349         } catch(IllegalAccessException iae) {
  1350             throw wrapper.couldNotInvokeHelperReadMethod( iae, cls ) ;
  1351         } catch(InvocationTargetException ite) {
  1352             throw wrapper.couldNotInvokeHelperReadMethod( ite, cls ) ;
  1356     private java.lang.Object readIDLValue(int indirection, String repId,
  1357                                           Class clazz, String codebase)
  1359         ValueFactory factory ;
  1361         // Always try to find a ValueFactory first, as required by the spec.
  1362         // There are some complications here in the IDL 3.0 mapping (see 1.13.8),
  1363         // but basically we must always be able to override the DefaultFactory
  1364         // or Helper mappings that are also used.  This appears to be the case
  1365         // even in the boxed value cases.  The original code only did the lookup
  1366         // in the case of class implementing either StreamableValue or CustomValue,
  1367         // but abstract valuetypes only implement ValueBase, and really require
  1368         // the use of the repId to find a factory (including the DefaultFactory).
  1369         try {
  1370             // use new-style OBV support (factory object)
  1371             factory = Utility.getFactory(clazz, codebase, orb, repId);
  1372         } catch (MARSHAL marshal) {
  1373             // XXX log marshal at one of the INFO levels
  1375             // Could not get a factory, so try alternatives
  1376             if (!StreamableValue.class.isAssignableFrom(clazz) &&
  1377                 !CustomValue.class.isAssignableFrom(clazz) &&
  1378                 ValueBase.class.isAssignableFrom(clazz)) {
  1379                 // use old-style OBV support (helper object)
  1380                 BoxedValueHelper helper = Utility.getHelper(clazz, codebase, repId);
  1381                 if (helper instanceof ValueHelper)
  1382                     return readIDLValueWithHelper((ValueHelper)helper, indirection);
  1383                 else
  1384                     return helper.read_value(parent);
  1385             } else {
  1386                 // must be a boxed IDLEntity, so make a reflective call to the
  1387                 // helper's static read method...
  1388                 return readBoxedIDLEntity(clazz, codebase);
  1392         // If there was no error in getting the factory, use it.
  1393         valueIndirection = indirection;  // for callback
  1394         return factory.read_value(parent);
  1397     /**
  1398      * End tags are only written for chunked valuetypes.
  1400      * Before Merlin, our ORBs wrote end tags which took into account
  1401      * all enclosing valuetypes.  This was changed by an interop resolution
  1402      * (see details around chunkedValueNestingLevel) to only include
  1403      * enclosing chunked types.
  1405      * ORB versioning and end tag compaction are handled here.
  1406      */
  1407     private void readEndTag() {
  1408         if (isChunked) {
  1410             // Read the end tag
  1411             int anEndTag = read_long();
  1413             // End tags should always be negative, and the outermost
  1414             // enclosing chunked valuetype should have a -1 end tag.
  1415             //
  1416             // handleEndOfValue should have assured that we were
  1417             // at the end tag position!
  1418             if (anEndTag >= 0) {
  1419                 throw wrapper.positiveEndTag( CompletionStatus.COMPLETED_MAYBE,
  1420                     new Integer(anEndTag), new Integer( get_offset() - 4 ) ) ;
  1423             // If the ORB is null, or if we're sure we're talking to
  1424             // a foreign ORB, Merlin, or something more recent, we
  1425             // use the updated end tag computation, and are more strenuous
  1426             // about the values.
  1427             if (orb == null ||
  1428                 ORBVersionFactory.getFOREIGN().equals(orb.getORBVersion()) ||
  1429                 ORBVersionFactory.getNEWER().compareTo(orb.getORBVersion()) <= 0) {
  1431                 // If the end tag we read was less than what we were expecting,
  1432                 // then the sender must think it's sent more enclosing
  1433                 // chunked valuetypes than we have.  Throw an exception.
  1434                 if (anEndTag < chunkedValueNestingLevel)
  1435                     throw wrapper.unexpectedEnclosingValuetype(
  1436                         CompletionStatus.COMPLETED_MAYBE, new Integer( anEndTag ),
  1437                         new Integer( chunkedValueNestingLevel ) ) ;
  1439                 // If the end tag is bigger than what we expected, but
  1440                 // still negative, then the sender has done some end tag
  1441                 // compaction.  We back up the stream 4 bytes so that the
  1442                 // next time readEndTag is called, it will get down here
  1443                 // again.  Even with fragmentation, we'll always be able
  1444                 // to do this.
  1445                 if (anEndTag != chunkedValueNestingLevel) {
  1446                     bbwi.position(bbwi.position() - 4);
  1449             } else {
  1451                 // When talking to Kestrel or Ladybird, we use our old
  1452                 // end tag rules and are less strict.  If the end tag
  1453                 // isn't what we expected, we back up, assuming
  1454                 // compaction.
  1455                 if (anEndTag != end_flag) {
  1456                     bbwi.position(bbwi.position() - 4);
  1460             // This only keeps track of the enclosing chunked
  1461             // valuetypes
  1462             chunkedValueNestingLevel++;
  1465         // This keeps track of all enclosing valuetypes
  1466         end_flag++;
  1469     protected int get_offset() {
  1470         return bbwi.position();
  1473     private void start_block() {
  1475         // if (outerValueDone)
  1476         if (!isChunked)
  1477             return;
  1479         // if called from alignAndCheck, need to reset blockLength
  1480         // to avoid an infinite recursion loop on read_long() call
  1481         blockLength = maxBlockLength;
  1483         blockLength = read_long();
  1485         // Must remember where we began the chunk to calculate how far
  1486         // along we are.  See notes above about chunkBeginPos.
  1488         if (blockLength > 0 && blockLength < maxBlockLength) {
  1489             blockLength += get_offset();  // _REVISIT_ unsafe, should use a Java long
  1491             // inBlock = true;
  1492         } else {
  1494             // System.out.println("start_block snooped a " + Integer.toHexString(blockLength));
  1496             // not a chunk length field
  1497             blockLength = maxBlockLength;
  1499             bbwi.position(bbwi.position() - 4);
  1503     // Makes sure that if we were reading a chunked value, we end up
  1504     // at the right place in the stream, no matter how little the
  1505     // unmarshalling code read.
  1506     //
  1507     // After calling this method, if we are chunking, we should be
  1508     // in position to read the end tag.
  1509     private void handleEndOfValue() {
  1511         // If we're not chunking, we don't have to worry about
  1512         // skipping remaining chunks or finding end tags
  1513         if (!isChunked)
  1514             return;
  1516         // Skip any remaining chunks
  1517         while (blockLength != maxBlockLength) {
  1518             end_block();
  1519             start_block();
  1522         // Now look for the end tag
  1524         // This is a little wasteful since we're reading
  1525         // this long up to 3 times in the worst cases (once
  1526         // in start_block, once here, and once in readEndTag
  1527         //
  1528         // Peek next long
  1529         int nextLong = read_long();
  1530         bbwi.position(bbwi.position() - 4);
  1532         // We did find an end tag, so we're done.  readEndTag
  1533         // should take care of making sure it's the correct
  1534         // end tag, etc.  Remember that since end tags,
  1535         // chunk lengths, and valuetags have non overlapping
  1536         // ranges, we can tell by the value what the longs are.
  1537         if (nextLong < 0)
  1538             return;
  1540         if (nextLong == 0 || nextLong >= maxBlockLength) {
  1542             // A custom marshaled valuetype left extra data
  1543             // on the wire, and that data had another
  1544             // nested value inside of it.  We've just
  1545             // read the value tag or null of that nested value.
  1546             //
  1547             // In an attempt to get by it, we'll try to call
  1548             // read_value() to get the nested value off of
  1549             // the wire.  Afterwards, we must call handleEndOfValue
  1550             // recursively to read any further chunks that the containing
  1551             // valuetype might still have after the nested
  1552             // value.
  1553             read_value();
  1554             handleEndOfValue();
  1555         } else {
  1556             // This probably means that the code to skip chunks has
  1557             // an error, and ended up setting blockLength to something
  1558             // other than maxBlockLength even though we weren't
  1559             // starting a new chunk.
  1560             throw wrapper.couldNotSkipBytes( CompletionStatus.COMPLETED_MAYBE,
  1561                 new Integer( nextLong ), new Integer( get_offset() ) ) ;
  1565     private void end_block() {
  1567         // if in a chunk, check for underflow or overflow
  1568         if (blockLength != maxBlockLength) {
  1569             if (blockLength == get_offset()) {
  1570                 // Chunk ended correctly
  1571                 blockLength = maxBlockLength;
  1572             } else {
  1573                 // Skip over anything left by bad unmarshaling code (ex:
  1574                 // a buggy custom unmarshaler).  See handleEndOfValue.
  1575                 if (blockLength > get_offset()) {
  1576                     skipToOffset(blockLength);
  1577                 } else {
  1578                     throw wrapper.badChunkLength( new Integer( blockLength ),
  1579                         new Integer( get_offset() ) ) ;
  1585     private int readValueTag(){
  1586         // outerValueDone = false;
  1587         return read_long();
  1590     public org.omg.CORBA.ORB orb() {
  1591         return orb;
  1594     // ------------ End RMI related methods --------------------------
  1596     public final void read_boolean_array(boolean[] value, int offset, int length) {
  1597         for(int i=0; i < length; i++) {
  1598             value[i+offset] = read_boolean();
  1602     public final void read_char_array(char[] value, int offset, int length) {
  1603         for(int i=0; i < length; i++) {
  1604             value[i+offset] = read_char();
  1608     public final void read_wchar_array(char[] value, int offset, int length) {
  1609         for(int i=0; i < length; i++) {
  1610             value[i+offset] = read_wchar();
  1614     public final void read_short_array(short[] value, int offset, int length) {
  1615         for(int i=0; i < length; i++) {
  1616             value[i+offset] = read_short();
  1620     public final void read_ushort_array(short[] value, int offset, int length) {
  1621         read_short_array(value, offset, length);
  1624     public final void read_long_array(int[] value, int offset, int length) {
  1625         for(int i=0; i < length; i++) {
  1626             value[i+offset] = read_long();
  1630     public final void read_ulong_array(int[] value, int offset, int length) {
  1631         read_long_array(value, offset, length);
  1634     public final void read_longlong_array(long[] value, int offset, int length) {
  1635         for(int i=0; i < length; i++) {
  1636             value[i+offset] = read_longlong();
  1640     public final void read_ulonglong_array(long[] value, int offset, int length) {
  1641         read_longlong_array(value, offset, length);
  1644     public final void read_float_array(float[] value, int offset, int length) {
  1645         for(int i=0; i < length; i++) {
  1646             value[i+offset] = read_float();
  1650     public final void read_double_array(double[] value, int offset, int length) {
  1651         for(int i=0; i < length; i++) {
  1652             value[i+offset] = read_double();
  1656     public final void read_any_array(org.omg.CORBA.Any[] value, int offset, int length) {
  1657         for(int i=0; i < length; i++) {
  1658             value[i+offset] = read_any();
  1662     //--------------------------------------------------------------------//
  1663     // CDRInputStream state management.
  1664     //
  1666     /**
  1667      * Are we at the end of the input stream?
  1668      */
  1669 //     public final boolean isAtEnd() {
  1670 //      return bbwi.position() == bbwi.buflen;
  1671 //     }
  1673 //     public int available() throws IOException {
  1674 //         return bbwi.buflen - bbwi.position();
  1675 //     }
  1677     private String read_repositoryIds() {
  1679         // Read # of repository ids
  1680         int numRepIds = read_long();
  1681         if (numRepIds == 0xffffffff) {
  1682             int indirection = read_long() + get_offset() - 4;
  1683             if (repositoryIdCache != null && repositoryIdCache.containsOrderedVal(indirection))
  1684                 return (String)repositoryIdCache.getKey(indirection);
  1685             else
  1686                 throw wrapper.unableToLocateRepIdArray( new Integer( indirection ) ) ;
  1687         } else {
  1689             // read first array element and store it as an indirection to the whole array
  1690             int indirection = get_offset();
  1691             String repID = read_repositoryId();
  1692             if (repositoryIdCache == null)
  1693                 repositoryIdCache = new CacheTable(orb,false);
  1694             repositoryIdCache.put(repID, indirection);
  1696             // read and ignore the subsequent array elements, but put them in the
  1697             // indirection table in case there are later indirections back to them
  1698             for (int i = 1; i < numRepIds; i++) {
  1699                 read_repositoryId();
  1702             return repID;
  1706     private final String read_repositoryId()
  1708         String result = readStringOrIndirection(true);
  1710         if (result == null) { // Indirection
  1711             int indirection = read_long() + get_offset() - 4;
  1713             if (repositoryIdCache != null && repositoryIdCache.containsOrderedVal(indirection))
  1714                 return (String)repositoryIdCache.getKey(indirection);
  1715             else
  1716                 throw wrapper.badRepIdIndirection( CompletionStatus.COMPLETED_MAYBE,
  1717                     new Integer(bbwi.position()) ) ;
  1718         } else {
  1719             if (repositoryIdCache == null)
  1720                 repositoryIdCache = new CacheTable(orb,false);
  1721             repositoryIdCache.put(result, stringIndirection);
  1724         return result ;
  1727     private final String read_codebase_URL()
  1729         String result = readStringOrIndirection(true);
  1731         if (result == null) { // Indirection
  1732             int indirection = read_long() + get_offset() - 4;
  1734             if (codebaseCache != null && codebaseCache.containsVal(indirection))
  1735                 return (String)codebaseCache.getKey(indirection);
  1736             else
  1737                 throw wrapper.badCodebaseIndirection(
  1738                     CompletionStatus.COMPLETED_MAYBE,
  1739                     new Integer(bbwi.position()) ) ;
  1740         } else {
  1741             if (codebaseCache == null)
  1742                 codebaseCache = new CacheTable(orb,false);
  1743             codebaseCache.put(result, stringIndirection);
  1746         return result;
  1749     /* DataInputStream methods */
  1751     public java.lang.Object read_Abstract () {
  1752         return read_abstract_interface();
  1755     public java.io.Serializable read_Value () {
  1756         return read_value();
  1759     public void read_any_array (org.omg.CORBA.AnySeqHolder seq, int offset, int length) {
  1760         read_any_array(seq.value, offset, length);
  1763     public void read_boolean_array (org.omg.CORBA.BooleanSeqHolder seq, int offset, int length) {
  1764         read_boolean_array(seq.value, offset, length);
  1767     public void read_char_array (org.omg.CORBA.CharSeqHolder seq, int offset, int length) {
  1768         read_char_array(seq.value, offset, length);
  1771     public void read_wchar_array (org.omg.CORBA.WCharSeqHolder seq, int offset, int length) {
  1772         read_wchar_array(seq.value, offset, length);
  1775     public void read_octet_array (org.omg.CORBA.OctetSeqHolder seq, int offset, int length) {
  1776         read_octet_array(seq.value, offset, length);
  1779     public void read_short_array (org.omg.CORBA.ShortSeqHolder seq, int offset, int length) {
  1780         read_short_array(seq.value, offset, length);
  1783     public void read_ushort_array (org.omg.CORBA.UShortSeqHolder seq, int offset, int length) {
  1784         read_ushort_array(seq.value, offset, length);
  1787     public void read_long_array (org.omg.CORBA.LongSeqHolder seq, int offset, int length) {
  1788         read_long_array(seq.value, offset, length);
  1791     public void read_ulong_array (org.omg.CORBA.ULongSeqHolder seq, int offset, int length) {
  1792         read_ulong_array(seq.value, offset, length);
  1795     public void read_ulonglong_array (org.omg.CORBA.ULongLongSeqHolder seq, int offset, int length) {
  1796         read_ulonglong_array(seq.value, offset, length);
  1799     public void read_longlong_array (org.omg.CORBA.LongLongSeqHolder seq, int offset, int length) {
  1800         read_longlong_array(seq.value, offset, length);
  1803     public void read_float_array (org.omg.CORBA.FloatSeqHolder seq, int offset, int length) {
  1804         read_float_array(seq.value, offset, length);
  1807     public void read_double_array (org.omg.CORBA.DoubleSeqHolder seq, int offset, int length) {
  1808         read_double_array(seq.value, offset, length);
  1811     public java.math.BigDecimal read_fixed(short digits, short scale) {
  1812         // digits isn't really needed here
  1813         StringBuffer buffer = read_fixed_buffer();
  1814         if (digits != buffer.length())
  1815             throw wrapper.badFixed( new Integer(digits),
  1816                 new Integer(buffer.length()) ) ;
  1817         buffer.insert(digits - scale, '.');
  1818         return new BigDecimal(buffer.toString());
  1821     // This method is unable to yield the correct scale.
  1822     public java.math.BigDecimal read_fixed() {
  1823         return new BigDecimal(read_fixed_buffer().toString());
  1826     // Each octet contains (up to) two decimal digits.
  1827     // If the fixed type has an odd number of decimal digits, then the representation
  1828     // begins with the first (most significant) digit.
  1829     // Otherwise, this first half-octet is all zero, and the first digit
  1830     // is in the second half-octet.
  1831     // The sign configuration, in the last half-octet of the representation,
  1832     // is 0xD for negative numbers and 0xC for positive and zero values.
  1833     private StringBuffer read_fixed_buffer() {
  1834         StringBuffer buffer = new StringBuffer(64);
  1835         byte doubleDigit;
  1836         int firstDigit;
  1837         int secondDigit;
  1838         boolean wroteFirstDigit = false;
  1839         boolean more = true;
  1840         while (more) {
  1841             doubleDigit = this.read_octet();
  1842             firstDigit = (int)((doubleDigit & 0xf0) >> 4);
  1843             secondDigit = (int)(doubleDigit & 0x0f);
  1844             if (wroteFirstDigit || firstDigit != 0) {
  1845                 buffer.append(Character.forDigit(firstDigit, 10));
  1846                 wroteFirstDigit = true;
  1848             if (secondDigit == 12) {
  1849                 // positive number or zero
  1850                 if ( ! wroteFirstDigit) {
  1851                     // zero
  1852                     return new StringBuffer("0.0");
  1853                 } else {
  1854                     // positive number
  1855                     // done
  1857                 more = false;
  1858             } else if (secondDigit == 13) {
  1859                 // negative number
  1860                 buffer.insert(0, '-');
  1861                 more = false;
  1862             } else {
  1863                 buffer.append(Character.forDigit(secondDigit, 10));
  1864                 wroteFirstDigit = true;
  1867         return buffer;
  1870     private final static String _id = "IDL:omg.org/CORBA/DataInputStream:1.0";
  1871     private final static String[] _ids = { _id };
  1873     public String[] _truncatable_ids() {
  1874         if (_ids == null)
  1875             return null;
  1877         return (String[])_ids.clone();
  1880     /* for debugging */
  1882     public void printBuffer() {
  1883         CDRInputStream_1_0.printBuffer(this.bbwi);
  1886     public static void printBuffer(ByteBufferWithInfo bbwi) {
  1888         System.out.println("----- Input Buffer -----");
  1889         System.out.println();
  1890         System.out.println("Current position: " + bbwi.position());
  1891         System.out.println("Total length : " + bbwi.buflen);
  1892         System.out.println();
  1894         try {
  1896             char[] charBuf = new char[16];
  1898             for (int i = 0; i < bbwi.buflen; i += 16) {
  1900                 int j = 0;
  1902                 // For every 16 bytes, there is one line
  1903                 // of output.  First, the hex output of
  1904                 // the 16 bytes with each byte separated
  1905                 // by a space.
  1906                 while (j < 16 && j + i < bbwi.buflen) {
  1907                     int k = bbwi.byteBuffer.get(i + j);
  1908                     if (k < 0)
  1909                         k = 256 + k;
  1910                     String hex = Integer.toHexString(k);
  1911                     if (hex.length() == 1)
  1912                         hex = "0" + hex;
  1913                     System.out.print(hex + " ");
  1914                     j++;
  1917                 // Add any extra spaces to align the
  1918                 // text column in case we didn't end
  1919                 // at 16
  1920                 while (j < 16) {
  1921                     System.out.print("   ");
  1922                     j++;
  1925                 // Now output the ASCII equivalents.  Non-ASCII
  1926                 // characters are shown as periods.
  1927                 int x = 0;
  1928                 while (x < 16 && x + i < bbwi.buflen) {
  1929                     if (ORBUtility.isPrintable((char)bbwi.byteBuffer.get(i + x)))
  1930                         charBuf[x] = (char)bbwi.byteBuffer.get(i + x);
  1931                     else
  1932                         charBuf[x] = '.';
  1933                     x++;
  1935                 System.out.println(new String(charBuf, 0, x));
  1938         } catch (Throwable t) {
  1939             t.printStackTrace();
  1942         System.out.println("------------------------");
  1945     public ByteBuffer getByteBuffer() {
  1946         ByteBuffer result = null;
  1947         if (bbwi != null) {
  1948             result = bbwi.byteBuffer;
  1950         return result;
  1953     public int getBufferLength() {
  1954         return bbwi.buflen;
  1957     public void setBufferLength(int value) {
  1958         bbwi.buflen = value;
  1959         bbwi.byteBuffer.limit(bbwi.buflen);
  1962     public void setByteBufferWithInfo(ByteBufferWithInfo bbwi) {
  1963         this.bbwi = bbwi;
  1966     public void setByteBuffer(ByteBuffer byteBuffer) {
  1967         bbwi.byteBuffer = byteBuffer;
  1970     public int getIndex() {
  1971         return bbwi.position();
  1974     public void setIndex(int value) {
  1975         bbwi.position(value);
  1978     public boolean isLittleEndian() {
  1979         return littleEndian;
  1982     public void orb(org.omg.CORBA.ORB orb) {
  1983         this.orb = (ORB)orb;
  1986     public BufferManagerRead getBufferManager() {
  1987         return bufferManagerRead;
  1990     private void skipToOffset(int offset) {
  1992         // Number of bytes to skip
  1993         int len = offset - get_offset();
  1995         int n = 0;
  1997         while (n < len) {
  1998             int avail;
  1999             int bytes;
  2000             int wanted;
  2002             avail = bbwi.buflen - bbwi.position();
  2003             if (avail <= 0) {
  2004                 grow(1, 1);
  2005                 avail = bbwi.buflen - bbwi.position();
  2008             wanted = len - n;
  2009             bytes = (wanted < avail) ? wanted : avail;
  2010             bbwi.position(bbwi.position() + bytes);
  2011             n += bytes;
  2016     // Mark and reset -------------------------------------------------
  2018     protected MarkAndResetHandler markAndResetHandler = null;
  2020     protected class StreamMemento
  2022         // These are the fields that may change after marking
  2023         // the stream position, so we need to save them.
  2024         private int blockLength_;
  2025         private int end_flag_;
  2026         private int chunkedValueNestingLevel_;
  2027         private int valueIndirection_;
  2028         private int stringIndirection_;
  2029         private boolean isChunked_;
  2030         private javax.rmi.CORBA.ValueHandler valueHandler_;
  2031         private ByteBufferWithInfo bbwi_;
  2032         private boolean specialNoOptionalDataState_;
  2034         public StreamMemento()
  2036             blockLength_ = blockLength;
  2037             end_flag_ = end_flag;
  2038             chunkedValueNestingLevel_ = chunkedValueNestingLevel;
  2039             valueIndirection_ = valueIndirection;
  2040             stringIndirection_ = stringIndirection;
  2041             isChunked_ = isChunked;
  2042             valueHandler_ = valueHandler;
  2043             specialNoOptionalDataState_ = specialNoOptionalDataState;
  2044             bbwi_ = new ByteBufferWithInfo(bbwi);
  2048     public java.lang.Object createStreamMemento() {
  2049         return new StreamMemento();
  2052     public void restoreInternalState(java.lang.Object streamMemento) {
  2054         StreamMemento mem = (StreamMemento)streamMemento;
  2056         blockLength = mem.blockLength_;
  2057         end_flag = mem.end_flag_;
  2058         chunkedValueNestingLevel = mem.chunkedValueNestingLevel_;
  2059         valueIndirection = mem.valueIndirection_;
  2060         stringIndirection = mem.stringIndirection_;
  2061         isChunked = mem.isChunked_;
  2062         valueHandler = mem.valueHandler_;
  2063         specialNoOptionalDataState = mem.specialNoOptionalDataState_;
  2064         bbwi = mem.bbwi_;
  2067     public int getPosition() {
  2068         return get_offset();
  2071     public void mark(int readlimit) {
  2072         markAndResetHandler.mark(this);
  2075     public void reset() {
  2076         markAndResetHandler.reset();
  2079     // ---------------------------------- end Mark and Reset
  2081     // Provides a hook so subclasses of CDRInputStream can provide
  2082     // a CodeBase.  This ultimately allows us to grab a Connection
  2083     // instance in IIOPInputStream, the only subclass where this
  2084     // is actually used.
  2085     CodeBase getCodeBase() {
  2086         return parent.getCodeBase();
  2089     /**
  2090      * Attempts to find the class described by the given
  2091      * repository ID string and expected type.  The first
  2092      * attempt is to find the class locally, falling back
  2093      * on the URL that came with the value.  The second
  2094      * attempt is to use a URL from the remote CodeBase.
  2095      */
  2096     private Class getClassFromString(String repositoryIDString,
  2097                                      String codebaseURL,
  2098                                      Class expectedType)
  2100         RepositoryIdInterface repositoryID
  2101             = repIdStrs.getFromString(repositoryIDString);
  2103         try {
  2104             try {
  2105                 // First try to load the class locally, then use
  2106                 // the provided URL (if it isn't null)
  2107                 return repositoryID.getClassFromType(expectedType,
  2108                                                      codebaseURL);
  2109             } catch (ClassNotFoundException cnfeOuter) {
  2111                 try {
  2113                     if (getCodeBase() == null) {
  2114                         return null; // class cannot be loaded remotely.
  2117                     // Get a URL from the remote CodeBase and retry
  2118                     codebaseURL = getCodeBase().implementation(repositoryIDString);
  2120                     // Don't bother trying to find it locally again if
  2121                     // we got a null URL
  2122                     if (codebaseURL == null)
  2123                         return null;
  2125                     return repositoryID.getClassFromType(expectedType,
  2126                                                          codebaseURL);
  2127                 } catch (ClassNotFoundException cnfeInner) {
  2128                     dprintThrowable(cnfeInner);
  2129                     // Failed to load the class
  2130                     return null;
  2133         } catch (MalformedURLException mue) {
  2134             // Always report a bad URL
  2135             throw wrapper.malformedUrl( CompletionStatus.COMPLETED_MAYBE,
  2136                 mue, repositoryIDString, codebaseURL ) ;
  2140     /**
  2141      * Attempts to find the class described by the given
  2142      * repository ID string.  At most, three attempts are made:
  2143      * Try to find it locally, through the provided URL, and
  2144      * finally, via a URL from the remote CodeBase.
  2145      */
  2146     private Class getClassFromString(String repositoryIDString,
  2147                                      String codebaseURL)
  2149         RepositoryIdInterface repositoryID
  2150             = repIdStrs.getFromString(repositoryIDString);
  2152         for (int i = 0; i < 3; i++) {
  2154             try {
  2156                 switch (i)
  2158                     case 0:
  2159                         // First try to load the class locally
  2160                         return repositoryID.getClassFromType();
  2161                     case 1:
  2162                         // Try to load the class using the provided
  2163                         // codebase URL (falls out below)
  2164                         break;
  2165                     case 2:
  2166                         // Try to load the class using a URL from the
  2167                         // remote CodeBase
  2168                         codebaseURL = getCodeBase().implementation(repositoryIDString);
  2169                         break;
  2172                 // Don't bother if the codebaseURL is null
  2173                 if (codebaseURL == null)
  2174                     continue;
  2176                 return repositoryID.getClassFromType(codebaseURL);
  2178             } catch(ClassNotFoundException cnfe) {
  2179                 // Will ultimately return null if all three
  2180                 // attempts fail, but don't do anything here.
  2181             } catch (MalformedURLException mue) {
  2182                 throw wrapper.malformedUrl( CompletionStatus.COMPLETED_MAYBE,
  2183                     mue, repositoryIDString, codebaseURL ) ;
  2187         // If we get here, we have failed to load the class
  2188         dprint("getClassFromString failed with rep id "
  2189                + repositoryIDString
  2190                + " and codebase "
  2191                + codebaseURL);
  2193         return null;
  2196     // Utility method used to get chars from bytes
  2197     char[] getConvertedChars(int numBytes,
  2198                              CodeSetConversion.BTCConverter converter) {
  2200         // REVISIT - Look at CodeSetConversion.BTCConverter to see
  2201         //           if it can work with an NIO ByteBuffer. We should
  2202         //           avoid getting the bytes into an array if possible.
  2204         // To be honest, I doubt this saves much real time
  2205         if (bbwi.buflen - bbwi.position() >= numBytes) {
  2206             // If the entire string is in this buffer,
  2207             // just convert directly from the bbwi rather than
  2208             // allocating and copying.
  2209             byte[] tmpBuf;
  2210             if (bbwi.byteBuffer.hasArray())
  2212                 tmpBuf = bbwi.byteBuffer.array();
  2214             else
  2216                  tmpBuf = new byte[bbwi.buflen];
  2217                  // Microbenchmarks are showing a loop of ByteBuffer.get(int)
  2218                  // being faster than ByteBuffer.get(byte[], int, int).
  2219                  for (int i = 0; i < bbwi.buflen; i++)
  2220                      tmpBuf[i] = bbwi.byteBuffer.get(i);
  2222             char[] result = converter.getChars(tmpBuf,bbwi.position(),numBytes);
  2224             bbwi.position(bbwi.position() + numBytes);
  2225             return result;
  2226         } else {
  2227             // Stretches across buffers.  Unless we provide an
  2228             // incremental conversion interface, allocate and
  2229             // copy the bytes.
  2230             byte[] bytes = new byte[numBytes];
  2231             read_octet_array(bytes, 0, bytes.length);
  2233             return converter.getChars(bytes, 0, numBytes);
  2237     protected CodeSetConversion.BTCConverter getCharConverter() {
  2238         if (charConverter == null)
  2239             charConverter = parent.createCharBTCConverter();
  2241         return charConverter;
  2244     protected CodeSetConversion.BTCConverter getWCharConverter() {
  2245         if (wcharConverter == null)
  2246             wcharConverter = parent.createWCharBTCConverter();
  2248         return wcharConverter;
  2251     protected void dprintThrowable(Throwable t) {
  2252         if (debug && t != null)
  2253             t.printStackTrace();
  2256     protected void dprint(String msg) {
  2257         if (debug) {
  2258             ORBUtility.dprint(this, msg);
  2262     /**
  2263      * Aligns the current position on the given octet boundary
  2264      * if there are enough bytes available to do so.  Otherwise,
  2265      * it just returns.  This is used for some (but not all)
  2266      * GIOP 1.2 message headers.
  2267      */
  2269     void alignOnBoundary(int octetBoundary) {
  2270         int needed = computeAlignment(bbwi.position(), octetBoundary);
  2272         if (bbwi.position() + needed <= bbwi.buflen)
  2274             bbwi.position(bbwi.position() + needed);
  2278     public void resetCodeSetConverters() {
  2279         charConverter = null;
  2280         wcharConverter = null;
  2283     public void start_value() {
  2284         // Read value tag
  2285         int vType = readValueTag();
  2287         if (vType == 0) {
  2288             // Stream needs to go into a state where it
  2289             // throws standard exception until end_value
  2290             // is called.  This means the sender didn't
  2291             // send any custom data.  If the reader here
  2292             // tries to read more, we need to throw an
  2293             // exception before reading beyond where
  2294             // we're supposed to
  2295             specialNoOptionalDataState = true;
  2297             return;
  2300         if (vType == 0xffffffff) {
  2301             // One should never indirect to a custom wrapper
  2302             throw wrapper.customWrapperIndirection(
  2303                 CompletionStatus.COMPLETED_MAYBE);
  2306         if (repIdUtil.isCodeBasePresent(vType)) {
  2307             throw wrapper.customWrapperWithCodebase(
  2308                 CompletionStatus.COMPLETED_MAYBE);
  2311         if (repIdUtil.getTypeInfo(vType)
  2312             != RepositoryIdUtility.SINGLE_REP_TYPE_INFO) {
  2313             throw wrapper.customWrapperNotSingleRepid(
  2314                 CompletionStatus.COMPLETED_MAYBE);
  2318         // REVISIT - Could verify repository ID even though
  2319         // it isn't used elsewhere
  2320         read_repositoryId();
  2322         // Note: isChunked should be true here.  Should have
  2323         // been set to true in the containing value's read_value
  2324         // method.
  2326         start_block();
  2327         end_flag--;
  2328         chunkedValueNestingLevel--;
  2331     public void end_value() {
  2333         if (specialNoOptionalDataState) {
  2334             specialNoOptionalDataState = false;
  2335             return;
  2338         handleEndOfValue();
  2339         readEndTag();
  2341         // Note that isChunked should still be true here.
  2342         // If the containing valuetype is the highest
  2343         // chunked value, it will get set to false
  2344         // at the end of read_value.
  2346         // allow for possible continuation chunk
  2347         start_block();
  2350     public void close() throws IOException
  2353         // tell BufferManagerRead to release any ByteBuffers
  2354         getBufferManager().close(bbwi);
  2356         // It's possible bbwi.byteBuffer is shared between
  2357         // this InputStream and an OutputStream. Thus, we check
  2358         // if the Input/Output streams are using the same ByteBuffer.
  2359         // If they sharing the same ByteBuffer we need to ensure only
  2360         // one of those ByteBuffers are released to the ByteBufferPool.
  2362         if (bbwi != null && getByteBuffer() != null)
  2364             MessageMediator messageMediator = parent.getMessageMediator();
  2365             if (messageMediator != null)
  2367                 CDROutputObject outputObj =
  2368                              (CDROutputObject)messageMediator.getOutputObject();
  2369                 if (outputObj != null)
  2371                     if (outputObj.isSharing(getByteBuffer()))
  2373                         // Set OutputStream's ByteBuffer and bbwi to null
  2374                         // so its ByteBuffer cannot be released to the pool
  2375                         outputObj.setByteBuffer(null);
  2376                         outputObj.setByteBufferWithInfo(null);
  2381             // release this stream's ByteBuffer to the pool
  2382             ByteBufferPool byteBufferPool = orb.getByteBufferPool();
  2383             if (debug)
  2385                 // print address of ByteBuffer being released
  2386                 int bbAddress = System.identityHashCode(bbwi.byteBuffer);
  2387                 StringBuffer sb = new StringBuffer(80);
  2388                 sb.append(".close - releasing ByteBuffer id (");
  2389                 sb.append(bbAddress).append(") to ByteBufferPool.");
  2390                 String msg = sb.toString();
  2391                 dprint(msg);
  2393             byteBufferPool.releaseByteBuffer(bbwi.byteBuffer);
  2394             bbwi.byteBuffer = null;
  2395             bbwi = null;

mercurial