- /*
- * @(#)CDRInputStream_1_0.java 1.132 04/06/21
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- /*
- * Licensed Materials - Property of IBM
- * RMI-IIOP v1.0
- * Copyright IBM Corp. 1998 1999 All Rights Reserved
- *
- * US Government Users Restricted Rights - Use, duplication or
- * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
-
- package com.sun.corba.se.impl.encoding;
-
- import java.io.IOException;
- import java.io.Serializable;
- import java.io.ByteArrayInputStream;
- import java.io.ObjectInputStream;
- import java.io.IOException;
- import java.io.StreamCorruptedException;
- import java.io.OptionalDataException;
- import java.io.IOException;
-
- import java.util.Stack;
-
- import java.net.URL;
- import java.net.MalformedURLException;
-
- import java.nio.ByteBuffer;
-
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
-
- import java.math.BigDecimal;
-
- import java.rmi.Remote;
- import java.rmi.StubNotFoundException;
-
- import java.security.AccessController;
- import java.security.PrivilegedExceptionAction;
- import java.security.PrivilegedActionException;
-
- import org.omg.CORBA.SystemException;
- import org.omg.CORBA.Object;
- import org.omg.CORBA.Principal;
- import org.omg.CORBA.TypeCode;
- import org.omg.CORBA.Any;
- import org.omg.CORBA.portable.Delegate;
- import org.omg.CORBA.portable.ValueBase;
- import org.omg.CORBA.portable.IndirectionException;
- import org.omg.CORBA.CompletionStatus;
- import org.omg.CORBA.TCKind;
- import org.omg.CORBA.TypeCodePackage.BadKind;
- import org.omg.CORBA.CustomMarshal;
- import org.omg.CORBA.TypeCode;
- import org.omg.CORBA.Principal;
- import org.omg.CORBA.Any;
- import org.omg.CORBA.portable.BoxedValueHelper;
- import org.omg.CORBA.portable.ValueFactory;
- import org.omg.CORBA.portable.CustomValue;
- import org.omg.CORBA.portable.StreamableValue;
- import org.omg.CORBA.MARSHAL;
- import org.omg.CORBA.portable.IDLEntity;
-
- import javax.rmi.PortableRemoteObject;
- import javax.rmi.CORBA.Tie;
- import javax.rmi.CORBA.Util;
- import javax.rmi.CORBA.ValueHandler;
-
- import com.sun.corba.se.pept.protocol.MessageMediator;
- import com.sun.corba.se.pept.transport.ByteBufferPool;
-
- import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
- import com.sun.corba.se.spi.protocol.CorbaClientDelegate;
-
- import com.sun.corba.se.spi.ior.IOR;
- import com.sun.corba.se.spi.ior.IORFactories;
- import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
-
- import com.sun.corba.se.spi.orb.ORB;
- import com.sun.corba.se.spi.orb.ORBVersionFactory;
- import com.sun.corba.se.spi.orb.ORBVersion;
-
- import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
-
- import com.sun.corba.se.spi.logging.CORBALogDomains;
- import com.sun.corba.se.spi.presentation.rmi.PresentationManager;
- import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
- import com.sun.corba.se.spi.presentation.rmi.PresentationDefaults;
-
- import com.sun.corba.se.impl.logging.ORBUtilSystemException;
- import com.sun.corba.se.impl.logging.OMGSystemException;
-
- import com.sun.corba.se.impl.corba.PrincipalImpl;
- import com.sun.corba.se.impl.corba.TypeCodeImpl;
- import com.sun.corba.se.impl.corba.CORBAObjectImpl;
-
- import com.sun.corba.se.impl.encoding.CDROutputObject;
- import com.sun.corba.se.impl.encoding.CodeSetConversion;
-
- import com.sun.corba.se.impl.util.Utility;
- import com.sun.corba.se.impl.util.RepositoryId;
-
- import com.sun.corba.se.impl.orbutil.RepositoryIdStrings;
- import com.sun.corba.se.impl.orbutil.RepositoryIdInterface;
- import com.sun.corba.se.impl.orbutil.RepositoryIdUtility;
- import com.sun.corba.se.impl.orbutil.RepositoryIdFactory;
-
- import com.sun.corba.se.impl.orbutil.ORBUtility;
- import com.sun.corba.se.impl.orbutil.CacheTable;
-
-
- import com.sun.org.omg.CORBA.portable.ValueHelper;
-
- import com.sun.org.omg.SendingContext.CodeBase;
-
- public class CDRInputStream_1_0 extends CDRInputStreamBase
- implements RestorableInputStream
- {
- private static final String kReadMethod = "read";
- private static final int maxBlockLength = 0x7fffff00;
-
- protected BufferManagerRead bufferManagerRead;
- protected ByteBufferWithInfo bbwi;
-
- // Set to the ORB's transportDebugFlag value. This value is
- // used if the ORB is null.
- private boolean debug = false;
-
- protected boolean littleEndian;
- protected ORB orb;
- protected ORBUtilSystemException wrapper ;
- protected OMGSystemException omgWrapper ;
- protected ValueHandler valueHandler = null;
-
- // Value cache
- private CacheTable valueCache = null;
-
- // Repository ID cache
- private CacheTable repositoryIdCache = null;
-
- // codebase cache
- private CacheTable codebaseCache = null;
-
- // Current Class Stack (repository Ids of current class being read)
- // private Stack currentStack = null;
-
- // Length of current chunk, or a large positive number if not in a chunk
- protected int blockLength = maxBlockLength;
-
- // Read end flag (value nesting depth)
- protected int end_flag = 0;
-
- // Beginning with the resolution to interop issue 3526 (4328?),
- // only enclosing chunked valuetypes are taken into account
- // when computing the nesting level. However, we still need
- // the old computation around for interoperability with our
- // older ORBs.
- private int chunkedValueNestingLevel = 0;
-
- // Flag used to determine whether blocksize was zero
- // private int checkForNullBlock = -1;
-
- // In block flag
- // private boolean inBlock = false;
-
- // Indicates whether we are inside a value
- // private boolean outerValueDone = true;
-
- // Int used by read_value(Serializable) that is set by this class
- // before calling ValueFactory.read_value
- protected int valueIndirection = 0;
-
- // Int set by readStringOrIndirection to communicate the actual
- // offset of the string length field back to the caller
- protected int stringIndirection = 0;
-
- // Flag indicating whether we are unmarshalling a chunked value
- protected boolean isChunked = false;
-
- // Repository ID handlers
- private RepositoryIdUtility repIdUtil;
- private RepositoryIdStrings repIdStrs;
-
- // Code set converters (created when first needed)
- private CodeSetConversion.BTCConverter charConverter;
- private CodeSetConversion.BTCConverter wcharConverter;
-
- // RMI-IIOP stream format version 2 case in which we know
- // that there is no more optional data available. If the
- // Serializable's readObject method tries to read anything,
- // we must throw a MARSHAL with the special minor code
- // so that the ValueHandler can give the correct exception
- // to readObject. The state is cleared when the ValueHandler
- // calls end_value after the readObject method exits.
- private boolean specialNoOptionalDataState = false;
-
- // Template method
- public CDRInputStreamBase dup()
- {
- CDRInputStreamBase result = null ;
-
- try {
- result = (CDRInputStreamBase)this.getClass().newInstance();
- } catch (Exception e) {
- throw wrapper.couldNotDuplicateCdrInputStream( e ) ;
- }
- result.init(this.orb,
- this.bbwi.byteBuffer,
- this.bbwi.buflen,
- this.littleEndian,
- this.bufferManagerRead);
-
- ((CDRInputStream_1_0)result).bbwi.position(this.bbwi.position());
- // To ensure we keep bbwi.byteBuffer.limit in sync with bbwi.buflen.
- ((CDRInputStream_1_0)result).bbwi.byteBuffer.limit(this.bbwi.buflen);
-
- return result;
- }
-
- /**
- * NOTE: size passed to init means buffer size
- */
- public void init(org.omg.CORBA.ORB orb,
- ByteBuffer byteBuffer,
- int size,
- boolean littleEndian,
- BufferManagerRead bufferManager)
- {
- this.orb = (ORB)orb;
- this.wrapper = ORBUtilSystemException.get( (ORB)orb,
- CORBALogDomains.RPC_ENCODING ) ;
- this.omgWrapper = OMGSystemException.get( (ORB)orb,
- CORBALogDomains.RPC_ENCODING ) ;
- this.littleEndian = littleEndian;
- this.bufferManagerRead = bufferManager;
- this.bbwi = new ByteBufferWithInfo(orb,byteBuffer,0);
- this.bbwi.buflen = size;
- this.bbwi.byteBuffer.limit(bbwi.buflen);
- this.markAndResetHandler = bufferManagerRead.getMarkAndResetHandler();
-
- debug = ((ORB)orb).transportDebugFlag;
- }
-
- // See description in CDRInputStream
- void performORBVersionSpecificInit() {
- createRepositoryIdHandlers();
- }
-
- private final void createRepositoryIdHandlers()
- {
- repIdUtil = RepositoryIdFactory.getRepIdUtility(orb);
- repIdStrs = RepositoryIdFactory.getRepIdStringsFactory(orb);
- }
-
- public GIOPVersion getGIOPVersion() {
- return GIOPVersion.V1_0;
- }
-
- // Called by Request and Reply message. Valid for GIOP versions >= 1.2 only.
- // Illegal for GIOP versions < 1.2.
- void setHeaderPadding(boolean headerPadding) {
- throw wrapper.giopVersionError();
- }
-
- protected final int computeAlignment(int index, int align) {
- if (align > 1) {
- int incr = index & (align - 1);
- if (incr != 0)
- return align - incr;
- }
-
- return 0;
- }
-
- public int getSize()
- {
- return bbwi.position();
- }
-
- protected void checkBlockLength(int align, int dataSize) {
- // Since chunks can end at arbitrary points (though not within
- // primitive CDR types, arrays of primitives, strings, wstrings,
- // or indirections),
- // we must check here for termination of the current chunk.
- if (!isChunked)
- return;
-
- // RMI-IIOP stream format version 2 case in which we know
- // that there is no more optional data available. If the
- // Serializable's readObject method tries to read anything,
- // we must throw a MARSHAL exception with the special minor code
- // so that the ValueHandler can give the correct exception
- // to readObject. The state is cleared when the ValueHandler
- // calls end_value after the readObject method exits.
- if (specialNoOptionalDataState) {
- throw omgWrapper.rmiiiopOptionalDataIncompatible1() ;
- }
-
- boolean checkForEndTag = false;
-
- // Are we at the end of the current chunk? If so,
- // try to interpret the next long as a chunk length.
- // (It has to be either a chunk length, end tag,
- // or valuetag.)
- //
- // If it isn't a chunk length, blockLength will
- // remain set to maxBlockLength.
- if (blockLength == get_offset()) {
-
- blockLength = maxBlockLength;
- start_block();
-
- // What's next is either a valuetag or
- // an end tag. If it's a valuetag, we're
- // probably being called as part of the process
- // to read the valuetag. If it's an end tag,
- // then there isn't enough data left in
- // this valuetype to read!
- if (blockLength == maxBlockLength)
- checkForEndTag = true;
-
- } else
- if (blockLength < get_offset()) {
- // Are we already past the end of the current chunk?
- // This is always an error.
- throw wrapper.chunkOverflow() ;
- }
-
- // If what's next on the wire isn't a chunk length or
- // what we want to read (which can't be split across chunks)
- // won't fit in the current chunk, throw this exception.
- // This probably means that we're in an RMI-IIOP
- // Serializable's readObject method or a custom marshaled
- // IDL type is reading too much/in an incorrect order
- int requiredNumBytes =
- computeAlignment(bbwi.position(), align) + dataSize;
-
- if (blockLength != maxBlockLength &&
- blockLength < get_offset() + requiredNumBytes) {
- throw omgWrapper.rmiiiopOptionalDataIncompatible2() ;
- }
-
- // REVISIT - We should look at using the built in advancement
- // of using ByteBuffer.get() rather than explicitly
- // advancing the ByteBuffer's position.
- // This is true for anywhere we are incrementing
- // the ByteBuffer's position.
- if (checkForEndTag) {
- int nextLong = read_long();
- bbwi.position(bbwi.position() - 4);
-
- // It was an end tag, so there wasn't enough data
- // left in the valuetype's encoding on the wire
- // to read what we wanted
- if (nextLong < 0)
- throw omgWrapper.rmiiiopOptionalDataIncompatible3() ;
- }
- }
-
- protected void alignAndCheck(int align, int n) {
-
- checkBlockLength(align, n);
-
- // WARNING: Must compute real alignment after calling
- // checkBlockLength since it may move the position
- int alignResult = computeAlignment(bbwi.position(), align);
- bbwi.position(bbwi.position() + alignResult);
-
- if (bbwi.position() + n > bbwi.buflen)
- grow(align, n);
- }
-
- //
- // This can be overridden....
- //
- protected void grow(int align, int n) {
-
- bbwi.needed = n;
-
- bbwi = bufferManagerRead.underflow(bbwi);
-
- }
-
- //
- // Marshal primitives.
- //
-
- public final void consumeEndian() {
- littleEndian = read_boolean();
- }
-
- // No such type in java
- public final double read_longdouble() {
- throw wrapper.longDoubleNotImplemented( CompletionStatus.COMPLETED_MAYBE);
- }
-
- public final boolean read_boolean() {
- return (read_octet() != 0);
- }
-
- public final char read_char() {
- alignAndCheck(1, 1);
-
- return getConvertedChars(1, getCharConverter())[0];
- }
-
- public char read_wchar() {
-
- // Don't allow transmission of wchar/wstring data with
- // foreign ORBs since it's against the spec.
- if (ORBUtility.isForeignORB((ORB)orb)) {
- throw wrapper.wcharDataInGiop10( CompletionStatus.COMPLETED_MAYBE);
- }
-
- // If we're talking to one of our legacy ORBs, do what
- // they did:
- int b1, b2;
-
- alignAndCheck(2, 2);
-
- if (littleEndian) {
- b2 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF;
- bbwi.position(bbwi.position() + 1);
- b1 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF;
- bbwi.position(bbwi.position() + 1);
- } else {
- b1 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF;
- bbwi.position(bbwi.position() + 1);
- b2 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF;
- bbwi.position(bbwi.position() + 1);
- }
-
- return (char)((b1 << 8) + (b2 << 0));
- }
-
- public final byte read_octet() {
-
- alignAndCheck(1, 1);
-
- byte b = bbwi.byteBuffer.get(bbwi.position());
- bbwi.position(bbwi.position() + 1);
-
- return b;
- }
-
- public final short read_short() {
- int b1, b2;
-
- alignAndCheck(2, 2);
-
- if (littleEndian) {
- b2 = (bbwi.byteBuffer.get(bbwi.position()) << 0) & 0x000000FF;
- bbwi.position(bbwi.position() + 1);
- b1 = (bbwi.byteBuffer.get(bbwi.position()) << 8) & 0x0000FF00;
- bbwi.position(bbwi.position() + 1);
- } else {
- b1 = (bbwi.byteBuffer.get(bbwi.position()) << 8) & 0x0000FF00;
- bbwi.position(bbwi.position() + 1);
- b2 = (bbwi.byteBuffer.get(bbwi.position()) << 0) & 0x000000FF;
- bbwi.position(bbwi.position() + 1);
- }
-
- return (short)(b1 | b2);
- }
-
- public final short read_ushort() {
- return read_short();
- }
-
- public final int read_long() {
- int b1, b2, b3, b4;
-
- alignAndCheck(4, 4);
-
- int bufPos = bbwi.position();
- if (littleEndian) {
- b4 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
- b3 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
- b2 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
- b1 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
- } else {
- b1 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
- b2 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
- b3 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
- b4 = bbwi.byteBuffer.get(bufPos++) & 0xFF;
- }
- bbwi.position(bufPos);
-
- return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
- }
-
- public final int read_ulong() {
- return read_long();
- }
-
- public final long read_longlong() {
- long i1, i2;
-
- alignAndCheck(8, 8);
-
- if (littleEndian) {
- i2 = read_long() & 0xFFFFFFFFL;
- i1 = (long)read_long() << 32;
- } else {
- i1 = (long)read_long() << 32;
- i2 = read_long() & 0xFFFFFFFFL;
- }
-
- return (i1 | i2);
- }
-
- public final long read_ulonglong() {
- return read_longlong();
- }
-
- public final float read_float() {
- return Float.intBitsToFloat(read_long());
- }
-
- public final double read_double() {
- return Double.longBitsToDouble(read_longlong());
- }
-
- protected final void checkForNegativeLength(int length) {
- if (length < 0)
- throw wrapper.negativeStringLength( CompletionStatus.COMPLETED_MAYBE,
- new Integer(length) ) ;
- }
-
- protected final String readStringOrIndirection(boolean allowIndirection) {
-
- int len = read_long();
-
- //
- // Check for indirection
- //
- if (allowIndirection) {
- if (len == 0xffffffff)
- return null;
- else
- stringIndirection = get_offset() - 4;
- }
-
- checkForNegativeLength(len);
-
- if (orb != null && ORBUtility.isLegacyORB((ORB)orb))
- return legacyReadString(len);
- else
- return internalReadString(len);
- }
-
- private final String internalReadString(int len) {
- // Workaround for ORBs which send string lengths of
- // zero to mean empty string.
- //
- // IMPORTANT: Do not replace 'new String("")' with "", it may result
- // in a Serialization bug (See serialization.zerolengthstring) and
- // bug id: 4728756 for details
- if (len == 0)
- return new String("");
-
- char[] result = getConvertedChars(len - 1, getCharConverter());
-
- // Skip over the 1 byte null
- read_octet();
-
- return new String(result, 0, getCharConverter().getNumChars());
- }
-
- private final String legacyReadString(int len) {
-
- //
- // Workaround for ORBs which send string lengths of
- // zero to mean empty string.
- //
- //
- // IMPORTANT: Do not replace 'new String("")' with "", it may result
- // in a Serialization bug (See serialization.zerolengthstring) and
- // bug id: 4728756 for details
- if (len == 0)
- return new String("");
-
- len--;
- char[] c = new char[len];
-
- int n = 0;
- while (n < len) {
- int avail;
- int bytes;
- int wanted;
-
- avail = bbwi.buflen - bbwi.position();
- if (avail <= 0) {
- grow(1, 1);
- avail = bbwi.buflen - bbwi.position();
- }
- wanted = len - n;
- bytes = (wanted < avail) ? wanted : avail;
- // Microbenchmarks are showing a loop of ByteBuffer.get(int) being
- // faster than ByteBuffer.get(byte[], int, int).
- for (int i=0; i<bytes; i++) {
- c[n+i] = (char) (bbwi.byteBuffer.get(bbwi.position()+i) & 0xFF);
- }
- bbwi.position(bbwi.position() + bytes);
- n += bytes;
- }
-
- //
- // Skip past terminating null byte
- //
- if (bbwi.position() + 1 > bbwi.buflen)
- alignAndCheck(1, 1);
- bbwi.position(bbwi.position() + 1);
-
- return new String(c);
- }
-
- public final String read_string() {
- return readStringOrIndirection(false);
- }
-
- public String read_wstring() {
- // Don't allow transmission of wchar/wstring data with
- // foreign ORBs since it's against the spec.
- if (ORBUtility.isForeignORB((ORB)orb)) {
- throw wrapper.wcharDataInGiop10( CompletionStatus.COMPLETED_MAYBE);
- }
-
- int len = read_long();
-
- //
- // Workaround for ORBs which send string lengths of
- // zero to mean empty string.
- //
- //
- // IMPORTANT: Do not replace 'new String("")' with "", it may result
- // in a Serialization bug (See serialization.zerolengthstring) and
- // bug id: 4728756 for details
- if (len == 0)
- return new String("");
-
- checkForNegativeLength(len);
-
- len--;
- char[] c = new char[len];
-
- for (int i = 0; i < len; i++)
- c[i] = read_wchar();
-
- // skip the two null terminator bytes
- read_wchar();
- // bbwi.position(bbwi.position() + 2);
-
- return new String(c);
- }
-
- public final void read_octet_array(byte[] b, int offset, int length) {
- if ( b == null )
- throw wrapper.nullParam() ;
-
- // Must call alignAndCheck at least once to ensure
- // we aren't at the end of a chunk. Of course, we
- // should only call it if we actually need to read
- // something, otherwise we might end up with an
- // exception at the end of the stream.
- if (length == 0)
- return;
-
- alignAndCheck(1, 1);
-
- int n = offset;
- while (n < length+offset) {
- int avail;
- int bytes;
- int wanted;
-
- avail = bbwi.buflen - bbwi.position();
- if (avail <= 0) {
- grow(1, 1);
- avail = bbwi.buflen - bbwi.position();
- }
- wanted = (length + offset) - n;
- bytes = (wanted < avail) ? wanted : avail;
- // Microbenchmarks are showing a loop of ByteBuffer.get(int) being
- // faster than ByteBuffer.get(byte[], int, int).
- for (int i = 0; i < bytes; i++) {
- b[n+i] = bbwi.byteBuffer.get(bbwi.position() + i);
- }
-
- bbwi.position(bbwi.position() + bytes);
-
- n += bytes;
- }
- }
-
- public Principal read_Principal() {
- int len = read_long();
- byte[] pvalue = new byte[len];
- read_octet_array(pvalue,0,len);
-
- Principal p = new PrincipalImpl();
- p.name(pvalue);
- return p;
- }
-
- public TypeCode read_TypeCode() {
- TypeCodeImpl tc = new TypeCodeImpl(orb);
- tc.read_value(parent);
- return tc;
- }
-
- public Any read_any() {
- Any any = orb.create_any();
- TypeCodeImpl tc = new TypeCodeImpl(orb);
-
- // read off the typecode
-
- // REVISIT We could avoid this try-catch if we could peek the typecode
- // kind off this stream and see if it is a tk_value. Looking at the
- // code we know that for tk_value the Any.read_value() below
- // ignores the tc argument anyway (except for the kind field).
- // But still we would need to make sure that the whole typecode,
- // including encapsulations, is read off.
- try {
- tc.read_value(parent);
- } catch (MARSHAL ex) {
- if (tc.kind().value() != TCKind._tk_value)
- throw ex;
- // We can be sure that the whole typecode encapsulation has been
- // read off.
- dprintThrowable(ex);
- }
- // read off the value of the any
- any.read_value(parent, tc);
-
- return any;
- }
-
- public org.omg.CORBA.Object read_Object() {
- return read_Object(null);
- }
-
- // ------------ RMI related methods --------------------------
-
- // IDL to Java ptc-00-01-08 1.21.4.1
- //
- // The clz argument to read_Object can be either a stub
- // Class or the "Class object for the RMI/IDL interface type
- // that is statically expected."
- // This functions as follows:
- // 1. If clz==null, just use the repository ID from the stub
- // 2. If clz is a stub class, just use it as a static factory.
- // clz is a stub class iff StubAdapter.isStubClass( clz ).
- // In addition, clz is a IDL stub class iff
- // IDLEntity.class.isAssignableFrom( clz ).
- // 3. If clz is an interface, use it to create the appropriate
- // stub factory.
- public org.omg.CORBA.Object read_Object(Class clz)
- {
- // In any case, we must first read the IOR.
- IOR ior = IORFactories.makeIOR(parent) ;
- if (ior.isNil())
- return null ;
-
- PresentationManager.StubFactoryFactory sff = ORB.getStubFactoryFactory() ;
- String codeBase = ior.getProfile().getCodebase() ;
- PresentationManager.StubFactory stubFactory = null ;
-
- if (clz == null) {
- RepositoryId rid = RepositoryId.cache.getId( ior.getTypeId() ) ;
- String className = rid.getClassName() ;
- boolean isIDLInterface = rid.isIDLType() ;
-
- if (className == null || className.equals( "" ))
- stubFactory = null ;
- else
- try {
- stubFactory = sff.createStubFactory( className,
- isIDLInterface, codeBase, (Class)null,
- (ClassLoader)null );
- } catch (Exception exc) {
- // Could not create stubFactory, so use null.
- // XXX stubFactory handling is still too complex:
- // Can we resolve the stubFactory question once in
- // a single place?
- stubFactory = null ;
- }
- } else if (StubAdapter.isStubClass( clz )) {
- stubFactory = PresentationDefaults.makeStaticStubFactory(
- clz ) ;
- } else {
- // clz is an interface class
- boolean isIDL = IDLEntity.class.isAssignableFrom( clz ) ;
-
- stubFactory = sff.createStubFactory( clz.getName(),
- isIDL, codeBase, clz, clz.getClassLoader() ) ;
- }
-
- return internalIORToObject( ior, stubFactory, orb ) ;
- }
-
- /*
- * This is used as a general utility (e.g., the PortableInterceptor
- * implementation uses it. If stubFactory is null, the ior's
- * IIOPProfile must support getServant.
- */
- public static org.omg.CORBA.Object internalIORToObject(
- IOR ior, PresentationManager.StubFactory stubFactory, ORB orb)
- {
- ORBUtilSystemException wrapper = ORBUtilSystemException.get(
- (ORB)orb, CORBALogDomains.RPC_ENCODING ) ;
-
- java.lang.Object servant = ior.getProfile().getServant() ;
- if (servant != null ) {
- if (servant instanceof Tie) {
- String codebase = ior.getProfile().getCodebase();
- org.omg.CORBA.Object objref = (org.omg.CORBA.Object)
- Utility.loadStub( (Tie)servant, stubFactory, codebase,
- false);
-
- // If we managed to load a stub, return it, otherwise we
- // must fail...
- if (objref != null) {
- return objref;
- } else {
- throw wrapper.readObjectException() ;
- }
- } else if (servant instanceof org.omg.CORBA.Object) {
- if (!(servant instanceof
- org.omg.CORBA.portable.InvokeHandler)) {
- return (org.omg.CORBA.Object) servant;
- }
- } else
- throw wrapper.badServantReadObject() ;
- }
-
- CorbaClientDelegate del = ORBUtility.makeClientDelegate( ior ) ;
- org.omg.CORBA.Object objref = null ;
- try {
- objref = stubFactory.makeStub() ;
- } catch (Throwable e) {
- wrapper.stubCreateError( e ) ;
-
- if (e instanceof ThreadDeath) {
- throw (ThreadDeath) e;
- }
-
- // Return the "default" stub...
- objref = new CORBAObjectImpl() ;
- }
-
- StubAdapter.setDelegate( objref, del ) ;
- return objref;
- }
-
- public java.lang.Object read_abstract_interface()
- {
- return read_abstract_interface(null);
- }
-
- public java.lang.Object read_abstract_interface(java.lang.Class clz)
- {
- boolean object = read_boolean();
-
- if (object) {
- return read_Object(clz);
- } else {
- return read_value();
- }
- }
-
- public Serializable read_value()
- {
- return read_value((Class)null);
- }
-
- private Serializable handleIndirection() {
- int indirection = read_long() + get_offset() - 4;
- if (valueCache != null && valueCache.containsVal(indirection)) {
-
- java.io.Serializable cachedValue
- = (java.io.Serializable)valueCache.getKey(indirection);
- return cachedValue;
- } else {
- // In RMI-IIOP the ValueHandler will recognize this
- // exception and use the provided indirection value
- // to lookup a possible indirection to an object
- // currently on the deserialization stack.
- throw new IndirectionException(indirection);
- }
- }
-
- /**
- * Examines the valuetag to see how many (if any) repository IDs
- * are present on the wire. If no repository ID information
- * is on the wire but the expectedType or expectedTypeRepId
- * is known, it will return one of those (favoring the
- * expectedType's repId).
- */
- private String readRepositoryIds(int valueTag,
- Class expectedType,
- String expectedTypeRepId)
- {
- switch(repIdUtil.getTypeInfo(valueTag)) {
- case RepositoryIdUtility.NO_TYPE_INFO :
- // Throw an exception if we have no repository ID info and
- // no expectedType to work with. Otherwise, how would we
- // know what to unmarshal?
- if (expectedType == null) {
- if (expectedTypeRepId != null)
- return expectedTypeRepId;
- else
- throw wrapper.expectedTypeNullAndNoRepId(
- CompletionStatus.COMPLETED_MAYBE);
- }
-
- return repIdStrs.createForAnyType(expectedType);
- case RepositoryIdUtility.SINGLE_REP_TYPE_INFO :
- return read_repositoryId();
- case RepositoryIdUtility.PARTIAL_LIST_TYPE_INFO :
- return read_repositoryIds();
- default:
- throw wrapper.badValueTag( CompletionStatus.COMPLETED_MAYBE,
- Integer.toHexString(valueTag) ) ;
- }
- }
-
- public Serializable read_value(Class expectedType) {
-
- // Read value tag
- int vType = readValueTag();
-
- // Is value null?
- if (vType == 0)
- return null;
-
- // Is this an indirection to a previously
- // read valuetype?
- if (vType == 0xffffffff)
- return handleIndirection();
-
- // Save where this valuetype started so we
- // can put it in the indirection valueCache
- // later
- int indirection = get_offset() - 4;
-
- // Need to save this special marker variable
- // to restore its value during recursion
- boolean saveIsChunked = isChunked;
-
- isChunked = repIdUtil.isChunkedEncoding(vType);
-
- java.lang.Object value = null;
-
- String codebase_URL = null;
- if (repIdUtil.isCodeBasePresent(vType)) {
- codebase_URL = read_codebase_URL();
- }
-
- // Read repository id(s)
- String repositoryIDString
- = readRepositoryIds(vType, expectedType, null);
-
- // If isChunked was determined to be true based
- // on the valuetag, this will read a chunk length
- start_block();
-
- // Remember that end_flag keeps track of all nested
- // valuetypes and is used for older ORBs
- end_flag--;
- if (isChunked)
- chunkedValueNestingLevel--;
-
- if (repositoryIDString.equals(repIdStrs.getWStringValueRepId())) {
- value = read_wstring();
- } else
- if (repositoryIDString.equals(repIdStrs.getClassDescValueRepId())) {
- // read in the class whether with the old ClassDesc or the
- // new one
- value = readClass();
- } else {
-
- Class valueClass = expectedType;
-
- // By this point, either the expectedType or repositoryIDString
- // is guaranteed to be non-null.
- if (expectedType == null ||
- !repositoryIDString.equals(repIdStrs.createForAnyType(expectedType))) {
-
- valueClass = getClassFromString(repositoryIDString,
- codebase_URL,
- expectedType);
- }
-
- if (valueClass == null) {
- // No point attempting to use value handler below, since the
- // class information is not available.
- throw wrapper.couldNotFindClass(
- CompletionStatus.COMPLETED_MAYBE,
- new ClassNotFoundException());
- }
-
- if (valueClass != null &&
- org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(valueClass)) {
-
- value = readIDLValue(indirection,
- repositoryIDString,
- valueClass,
- codebase_URL);
-
- } else {
-
- // Must be some form of RMI-IIOP valuetype
-
- try {
- if (valueHandler == null)
- valueHandler = ORBUtility.createValueHandler(orb);
-
- value = valueHandler.readValue(parent,
- indirection,
- valueClass,
- repositoryIDString,
- getCodeBase());
-
- } catch(SystemException sysEx) {
- // Just rethrow any CORBA system exceptions
- // that come out of the ValueHandler
- throw sysEx;
- } catch(Exception ex) {
- throw wrapper.valuehandlerReadException(
- CompletionStatus.COMPLETED_MAYBE, ex ) ;
- } catch(Error e) {
- throw wrapper.valuehandlerReadError(
- CompletionStatus.COMPLETED_MAYBE, e ) ;
- }
- }
- }
-
- // Skip any remaining chunks until we get to
- // an end tag or a valuetag. If we see a valuetag,
- // that means there was another valuetype in the sender's
- // version of this class that we need to skip over.
- handleEndOfValue();
-
- // Read and process the end tag if we're chunking.
- // Assumes that we're at the position of the end tag
- // (handleEndOfValue should assure this)
- readEndTag();
-
- // Cache the valuetype that we read
- if (valueCache == null)
- valueCache = new CacheTable(orb,false);
- valueCache.put(value, indirection);
-
- // Allow for possible continuation chunk.
- // If we're a nested valuetype inside of a chunked
- // valuetype, and that enclosing valuetype has
- // more data to write, it will need to have this
- // new chunk begin after we wrote our end tag.
- isChunked = saveIsChunked;
- start_block();
-
- return (java.io.Serializable)value;
- }
-
- public Serializable read_value(BoxedValueHelper factory) {
-
- // Read value tag
- int vType = readValueTag();
-
- if (vType == 0)
- return null; // value is null
- else if (vType == 0xffffffff) { // Indirection tag
- int indirection = read_long() + get_offset() - 4;
- if (valueCache != null && valueCache.containsVal(indirection))
- {
- java.io.Serializable cachedValue =
- (java.io.Serializable)valueCache.getKey(indirection);
- return cachedValue;
- }
- else {
- throw new IndirectionException(indirection);
- }
- }
- else {
- int indirection = get_offset() - 4;
-
- // end_block();
-
- boolean saveIsChunked = isChunked;
- isChunked = repIdUtil.isChunkedEncoding(vType);
-
- java.lang.Object value = null;
-
- String codebase_URL = null;
- if (repIdUtil.isCodeBasePresent(vType)){
- codebase_URL = read_codebase_URL();
- }
-
- // Read repository id
- String repositoryIDString
- = readRepositoryIds(vType, null, null);
-
- // Compare rep. ids to see if we should use passed helper
- if (!repositoryIDString.equals(factory.get_id()))
- factory = Utility.getHelper(null, codebase_URL, repositoryIDString);
-
- start_block();
- end_flag--;
- if (isChunked)
- chunkedValueNestingLevel--;
-
- if (factory instanceof ValueHelper) {
- value = readIDLValueWithHelper((ValueHelper)factory, indirection);
- } else {
- valueIndirection = indirection; // for callback
- value = factory.read_value(parent);
- }
-
- handleEndOfValue();
- readEndTag();
-
- // Put into valueCache
- if (valueCache == null)
- valueCache = new CacheTable(orb,false);
- valueCache.put(value, indirection);
-
- // allow for possible continuation chunk
- isChunked = saveIsChunked;
- start_block();
-
- return (java.io.Serializable)value;
- }
- }
-
- private boolean isCustomType(ValueHelper helper) {
- try{
- TypeCode tc = helper.get_type();
- int kind = tc.kind().value();
- if (kind == TCKind._tk_value) {
- return (tc.type_modifier() == org.omg.CORBA.VM_CUSTOM.value);
- }
- } catch(BadKind ex) {
- throw wrapper.badKind(ex) ;
- }
-
- return false;
- }
-
- // This method is actually called indirectly by
- // read_value(String repositoryId).
- // Therefore, it is not a truly independent read call that handles
- // header information itself.
- public java.io.Serializable read_value(java.io.Serializable value) {
-
- // Put into valueCache using valueIndirection
- if (valueCache == null)
- valueCache = new CacheTable(orb,false);
- valueCache.put(value, valueIndirection);
-
- if (value instanceof StreamableValue)
- ((StreamableValue)value)._read(parent);
- else if (value instanceof CustomValue)
- ((CustomValue)value).unmarshal(parent);
-
- return value;
- }
-
- public java.io.Serializable read_value(java.lang.String repositoryId) {
-
- // if (inBlock)
- // end_block();
-
- // Read value tag
- int vType = readValueTag();
-
- if (vType == 0)
- return null; // value is null
- else if (vType == 0xffffffff) { // Indirection tag
- int indirection = read_long() + get_offset() - 4;
- if (valueCache != null && valueCache.containsVal(indirection))
- {
- java.io.Serializable cachedValue =
- (java.io.Serializable)valueCache.getKey(indirection);
- return cachedValue;
- }
- else {
- throw new IndirectionException(indirection);
- }
- }
- else {
- int indirection = get_offset() - 4;
-
- // end_block();
-
- boolean saveIsChunked = isChunked;
- isChunked = repIdUtil.isChunkedEncoding(vType);
-
- java.lang.Object value = null;
-
- String codebase_URL = null;
- if (repIdUtil.isCodeBasePresent(vType)){
- codebase_URL = read_codebase_URL();
- }
-
- // Read repository id
- String repositoryIDString
- = readRepositoryIds(vType, null, repositoryId);
-
- ValueFactory factory =
- Utility.getFactory(null, codebase_URL, orb, repositoryIDString);
-
- start_block();
- end_flag--;
- if (isChunked)
- chunkedValueNestingLevel--;
-
- valueIndirection = indirection; // for callback
- value = factory.read_value(parent);
-
- handleEndOfValue();
- readEndTag();
-
- // Put into valueCache
- if (valueCache == null)
- valueCache = new CacheTable(orb,false);
- valueCache.put(value, indirection);
-
- // allow for possible continuation chunk
- isChunked = saveIsChunked;
- start_block();
-
- return (java.io.Serializable)value;
- }
- }
-
- private Class readClass() {
-
- String codebases = null, classRepId = null;
-
- if (orb == null ||
- ORBVersionFactory.getFOREIGN().equals(orb.getORBVersion()) ||
- ORBVersionFactory.getNEWER().compareTo(orb.getORBVersion()) <= 0) {
-
- codebases = (String)read_value(java.lang.String.class);
- classRepId = (String)read_value(java.lang.String.class);
- } else {
- // Pre-Merlin/J2EE 1.3 ORBs wrote the repository ID
- // and codebase strings in the wrong order.
- classRepId = (String)read_value(java.lang.String.class);
- codebases = (String)read_value(java.lang.String.class);
- }
-
- if (debug) {
- dprint("readClass codebases: "
- + codebases
- + " rep Id: "
- + classRepId);
- }
-
- Class cl = null;
-
- RepositoryIdInterface repositoryID
- = repIdStrs.getFromString(classRepId);
-
- try {
- cl = repositoryID.getClassFromType(codebases);
- } catch(ClassNotFoundException cnfe) {
- throw wrapper.cnfeReadClass( CompletionStatus.COMPLETED_MAYBE,
- cnfe, repositoryID.getClassName() ) ;
- } catch(MalformedURLException me) {
- throw wrapper.malformedUrl( CompletionStatus.COMPLETED_MAYBE,
- me, repositoryID.getClassName(), codebases ) ;
- }
-
- return cl;
- }
-
- private java.lang.Object readIDLValueWithHelper(ValueHelper helper, int indirection)
- {
- // look for two-argument static read method
- Method readMethod;
- try {
- Class argTypes[] = {org.omg.CORBA.portable.InputStream.class, helper.get_class()};
- readMethod = helper.getClass().getDeclaredMethod(kReadMethod, argTypes);
- }
- catch(NoSuchMethodException nsme) { // must be boxed value helper
- java.lang.Object result = helper.read_value(parent);
- return result;
- }
-
- // found two-argument read method, so must be non-boxed value...
- // ...create a blank instance
- java.lang.Object val = null;
- try {
- val = helper.get_class().newInstance();
- } catch(java.lang.InstantiationException ie) {
- throw wrapper.couldNotInstantiateHelper( ie,
- helper.get_class() ) ;
- } catch(IllegalAccessException iae){
- // Value's constructor is protected or private
- //
- // So, use the helper to read the value.
- //
- // NOTE : This means that in this particular case a recursive ref.
- // would fail.
- return helper.read_value(parent);
- }
-
- // add blank instance to cache table
- if (valueCache == null)
- valueCache = new CacheTable(orb,false);
- valueCache.put(val, indirection);
-
- // if custom type, call unmarshal method
- if (val instanceof CustomMarshal && isCustomType(helper)) {
- ((CustomMarshal)val).unmarshal(parent);
- return val;
- }
-
- // call two-argument read method using reflection
- try {
- java.lang.Object args[] = {parent, val};
- readMethod.invoke(helper, args);
- return val;
- } catch(IllegalAccessException iae2) {
- throw wrapper.couldNotInvokeHelperReadMethod( iae2, helper.get_class() ) ;
- } catch(InvocationTargetException ite){
- throw wrapper.couldNotInvokeHelperReadMethod( ite, helper.get_class() ) ;
- }
- }
-
- private java.lang.Object readBoxedIDLEntity(Class clazz, String codebase)
- {
- Class cls = null ;
-
- try {
- ClassLoader clazzLoader = (clazz == null ? null : clazz.getClassLoader());
-
- cls = Utility.loadClassForClass(clazz.getName()+"Helper", codebase,
- clazzLoader, clazz, clazzLoader);
- final Class helperClass = cls ;
-
- final Class argTypes[] = {org.omg.CORBA.portable.InputStream.class};
-
- // getDeclaredMethod requires RuntimePermission accessDeclaredMembers
- // if a different class loader is used (even though the javadoc says otherwise)
- Method readMethod = null;
- try {
- readMethod = (Method)AccessController.doPrivileged(
- new PrivilegedExceptionAction() {
- public java.lang.Object run() throws NoSuchMethodException {
- return helperClass.getDeclaredMethod(kReadMethod, argTypes);
- }
- }
- );
- } catch (PrivilegedActionException pae) {
- // this gets caught below
- throw (NoSuchMethodException)pae.getException();
- }
-
- java.lang.Object args[] = {parent};
- return readMethod.invoke(null, args);
-
- } catch (ClassNotFoundException cnfe) {
- throw wrapper.couldNotInvokeHelperReadMethod( cnfe, cls ) ;
- } catch(NoSuchMethodException nsme) {
- throw wrapper.couldNotInvokeHelperReadMethod( nsme, cls ) ;
- } catch(IllegalAccessException iae) {
- throw wrapper.couldNotInvokeHelperReadMethod( iae, cls ) ;
- } catch(InvocationTargetException ite) {
- throw wrapper.couldNotInvokeHelperReadMethod( ite, cls ) ;
- }
- }
-
- private java.lang.Object readIDLValue(int indirection, String repId,
- Class clazz, String codebase)
- {
- ValueFactory factory ;
-
- // Always try to find a ValueFactory first, as required by the spec.
- // There are some complications here in the IDL 3.0 mapping (see 1.13.8),
- // but basically we must always be able to override the DefaultFactory
- // or Helper mappings that are also used. This appears to be the case
- // even in the boxed value cases. The original code only did the lookup
- // in the case of class implementing either StreamableValue or CustomValue,
- // but abstract valuetypes only implement ValueBase, and really require
- // the use of the repId to find a factory (including the DefaultFactory).
- try {
- // use new-style OBV support (factory object)
- factory = Utility.getFactory(clazz, codebase, orb, repId);
- } catch (MARSHAL marshal) {
- // XXX log marshal at one of the INFO levels
-
- // Could not get a factory, so try alternatives
- if (!StreamableValue.class.isAssignableFrom(clazz) &&
- !CustomValue.class.isAssignableFrom(clazz) &&
- ValueBase.class.isAssignableFrom(clazz)) {
- // use old-style OBV support (helper object)
- BoxedValueHelper helper = Utility.getHelper(clazz, codebase, repId);
- if (helper instanceof ValueHelper)
- return readIDLValueWithHelper((ValueHelper)helper, indirection);
- else
- return helper.read_value(parent);
- } else {
- // must be a boxed IDLEntity, so make a reflective call to the
- // helper's static read method...
- return readBoxedIDLEntity(clazz, codebase);
- }
- }
-
- // If there was no error in getting the factory, use it.
- valueIndirection = indirection; // for callback
- return factory.read_value(parent);
- }
-
- /**
- * End tags are only written for chunked valuetypes.
- *
- * Before Merlin, our ORBs wrote end tags which took into account
- * all enclosing valuetypes. This was changed by an interop resolution
- * (see details around chunkedValueNestingLevel) to only include
- * enclosing chunked types.
- *
- * ORB versioning and end tag compaction are handled here.
- */
- private void readEndTag() {
- if (isChunked) {
-
- // Read the end tag
- int anEndTag = read_long();
-
- // End tags should always be negative, and the outermost
- // enclosing chunked valuetype should have a -1 end tag.
- //
- // handleEndOfValue should have assured that we were
- // at the end tag position!
- if (anEndTag >= 0) {
- throw wrapper.positiveEndTag( CompletionStatus.COMPLETED_MAYBE,
- new Integer(anEndTag), new Integer( get_offset() - 4 ) ) ;
- }
-
- // If the ORB is null, or if we're sure we're talking to
- // a foreign ORB, Merlin, or something more recent, we
- // use the updated end tag computation, and are more strenuous
- // about the values.
- if (orb == null ||
- ORBVersionFactory.getFOREIGN().equals(orb.getORBVersion()) ||
- ORBVersionFactory.getNEWER().compareTo(orb.getORBVersion()) <= 0) {
-
- // If the end tag we read was less than what we were expecting,
- // then the sender must think it's sent more enclosing
- // chunked valuetypes than we have. Throw an exception.
- if (anEndTag < chunkedValueNestingLevel)
- throw wrapper.unexpectedEnclosingValuetype(
- CompletionStatus.COMPLETED_MAYBE, new Integer( anEndTag ),
- new Integer( chunkedValueNestingLevel ) ) ;
-
- // If the end tag is bigger than what we expected, but
- // still negative, then the sender has done some end tag
- // compaction. We back up the stream 4 bytes so that the
- // next time readEndTag is called, it will get down here
- // again. Even with fragmentation, we'll always be able
- // to do this.
- if (anEndTag != chunkedValueNestingLevel) {
- bbwi.position(bbwi.position() - 4);
- }
-
- } else {
-
- // When talking to Kestrel or Ladybird, we use our old
- // end tag rules and are less strict. If the end tag
- // isn't what we expected, we back up, assuming
- // compaction.
- if (anEndTag != end_flag) {
- bbwi.position(bbwi.position() - 4);
- }
- }
-
- // This only keeps track of the enclosing chunked
- // valuetypes
- chunkedValueNestingLevel++;
- }
-
- // This keeps track of all enclosing valuetypes
- end_flag++;
- }
-
- protected int get_offset() {
- return bbwi.position();
- }
-
- private void start_block() {
-
- // if (outerValueDone)
- if (!isChunked)
- return;
-
- // if called from alignAndCheck, need to reset blockLength
- // to avoid an infinite recursion loop on read_long() call
- blockLength = maxBlockLength;
-
- blockLength = read_long();
-
- // Must remember where we began the chunk to calculate how far
- // along we are. See notes above about chunkBeginPos.
-
- if (blockLength > 0 && blockLength < maxBlockLength) {
- blockLength += get_offset(); // _REVISIT_ unsafe, should use a Java long
-
- // inBlock = true;
- } else {
-
- // System.out.println("start_block snooped a " + Integer.toHexString(blockLength));
-
- // not a chunk length field
- blockLength = maxBlockLength;
-
- bbwi.position(bbwi.position() - 4);
- }
- }
-
- // Makes sure that if we were reading a chunked value, we end up
- // at the right place in the stream, no matter how little the
- // unmarshalling code read.
- //
- // After calling this method, if we are chunking, we should be
- // in position to read the end tag.
- private void handleEndOfValue() {
-
- // If we're not chunking, we don't have to worry about
- // skipping remaining chunks or finding end tags
- if (!isChunked)
- return;
-
- // Skip any remaining chunks
- while (blockLength != maxBlockLength) {
- end_block();
- start_block();
- }
-
- // Now look for the end tag
-
- // This is a little wasteful since we're reading
- // this long up to 3 times in the worst cases (once
- // in start_block, once here, and once in readEndTag
- //
- // Peek next long
- int nextLong = read_long();
- bbwi.position(bbwi.position() - 4);
-
- // We did find an end tag, so we're done. readEndTag
- // should take care of making sure it's the correct
- // end tag, etc. Remember that since end tags,
- // chunk lengths, and valuetags have non overlapping
- // ranges, we can tell by the value what the longs are.
- if (nextLong < 0)
- return;
-
- if (nextLong == 0 || nextLong >= maxBlockLength) {
-
- // A custom marshaled valuetype left extra data
- // on the wire, and that data had another
- // nested value inside of it. We've just
- // read the value tag or null of that nested value.
- //
- // In an attempt to get by it, we'll try to call
- // read_value() to get the nested value off of
- // the wire. Afterwards, we must call handleEndOfValue
- // recursively to read any further chunks that the containing
- // valuetype might still have after the nested
- // value.
- read_value();
- handleEndOfValue();
- } else {
- // This probably means that the code to skip chunks has
- // an error, and ended up setting blockLength to something
- // other than maxBlockLength even though we weren't
- // starting a new chunk.
- throw wrapper.couldNotSkipBytes( CompletionStatus.COMPLETED_MAYBE,
- new Integer( nextLong ), new Integer( get_offset() ) ) ;
- }
- }
-
- private void end_block() {
-
- // if in a chunk, check for underflow or overflow
- if (blockLength != maxBlockLength) {
- if (blockLength == get_offset()) {
- // Chunk ended correctly
- blockLength = maxBlockLength;
- } else {
- // Skip over anything left by bad unmarshaling code (ex:
- // a buggy custom unmarshaler). See handleEndOfValue.
- if (blockLength > get_offset()) {
- skipToOffset(blockLength);
- } else {
- throw wrapper.badChunkLength( new Integer( blockLength ),
- new Integer( get_offset() ) ) ;
- }
- }
- }
- }
-
- private int readValueTag(){
- // outerValueDone = false;
- return read_long();
- }
-
- public org.omg.CORBA.ORB orb() {
- return orb;
- }
-
- // ------------ End RMI related methods --------------------------
-
- public final void read_boolean_array(boolean[] value, int offset, int length) {
- for(int i=0; i < length; i++) {
- value[i+offset] = read_boolean();
- }
- }
-
- public final void read_char_array(char[] value, int offset, int length) {
- for(int i=0; i < length; i++) {
- value[i+offset] = read_char();
- }
- }
-
- public final void read_wchar_array(char[] value, int offset, int length) {
- for(int i=0; i < length; i++) {
- value[i+offset] = read_wchar();
- }
- }
-
- public final void read_short_array(short[] value, int offset, int length) {
- for(int i=0; i < length; i++) {
- value[i+offset] = read_short();
- }
- }
-
- public final void read_ushort_array(short[] value, int offset, int length) {
- read_short_array(value, offset, length);
- }
-
- public final void read_long_array(int[] value, int offset, int length) {
- for(int i=0; i < length; i++) {
- value[i+offset] = read_long();
- }
- }
-
- public final void read_ulong_array(int[] value, int offset, int length) {
- read_long_array(value, offset, length);
- }
-
- public final void read_longlong_array(long[] value, int offset, int length) {
- for(int i=0; i < length; i++) {
- value[i+offset] = read_longlong();
- }
- }
-
- public final void read_ulonglong_array(long[] value, int offset, int length) {
- read_longlong_array(value, offset, length);
- }
-
- public final void read_float_array(float[] value, int offset, int length) {
- for(int i=0; i < length; i++) {
- value[i+offset] = read_float();
- }
- }
-
- public final void read_double_array(double[] value, int offset, int length) {
- for(int i=0; i < length; i++) {
- value[i+offset] = read_double();
- }
- }
-
- public final void read_any_array(org.omg.CORBA.Any[] value, int offset, int length) {
- for(int i=0; i < length; i++) {
- value[i+offset] = read_any();
- }
- }
-
- //--------------------------------------------------------------------//
- // CDRInputStream state management.
- //
-
- /**
- * Are we at the end of the input stream?
- */
- // public final boolean isAtEnd() {
- // return bbwi.position() == bbwi.buflen;
- // }
-
- // public int available() throws IOException {
- // return bbwi.buflen - bbwi.position();
- // }
-
- private String read_repositoryIds() {
-
- // Read # of repository ids
- int numRepIds = read_long();
- if (numRepIds == 0xffffffff) {
- int indirection = read_long() + get_offset() - 4;
- if (repositoryIdCache != null && repositoryIdCache.containsOrderedVal(indirection))
- return (String)repositoryIdCache.getKey(indirection);
- else
- throw wrapper.unableToLocateRepIdArray( new Integer( indirection ) ) ;
- } else {
-
- // read first array element and store it as an indirection to the whole array
- int indirection = get_offset();
- String repID = read_repositoryId();
- if (repositoryIdCache == null)
- repositoryIdCache = new CacheTable(orb,false);
- repositoryIdCache.put(repID, indirection);
-
- // read and ignore the subsequent array elements, but put them in the
- // indirection table in case there are later indirections back to them
- for (int i = 1; i < numRepIds; i++) {
- read_repositoryId();
- }
-
- return repID;
- }
- }
-
- private final String read_repositoryId()
- {
- String result = readStringOrIndirection(true);
-
- if (result == null) { // Indirection
- int indirection = read_long() + get_offset() - 4;
-
- if (repositoryIdCache != null && repositoryIdCache.containsOrderedVal(indirection))
- return (String)repositoryIdCache.getKey(indirection);
- else
- throw wrapper.badRepIdIndirection( CompletionStatus.COMPLETED_MAYBE,
- new Integer(bbwi.position()) ) ;
- } else {
- if (repositoryIdCache == null)
- repositoryIdCache = new CacheTable(orb,false);
- repositoryIdCache.put(result, stringIndirection);
- }
-
- return result ;
- }
-
- private final String read_codebase_URL()
- {
- String result = readStringOrIndirection(true);
-
- if (result == null) { // Indirection
- int indirection = read_long() + get_offset() - 4;
-
- if (codebaseCache != null && codebaseCache.containsVal(indirection))
- return (String)codebaseCache.getKey(indirection);
- else
- throw wrapper.badCodebaseIndirection(
- CompletionStatus.COMPLETED_MAYBE,
- new Integer(bbwi.position()) ) ;
- } else {
- if (codebaseCache == null)
- codebaseCache = new CacheTable(orb,false);
- codebaseCache.put(result, stringIndirection);
- }
-
- return result;
- }
-
- /* DataInputStream methods */
-
- public java.lang.Object read_Abstract () {
- return read_abstract_interface();
- }
-
- public java.io.Serializable read_Value () {
- return read_value();
- }
-
- public void read_any_array (org.omg.CORBA.AnySeqHolder seq, int offset, int length) {
- read_any_array(seq.value, offset, length);
- }
-
- public void read_boolean_array (org.omg.CORBA.BooleanSeqHolder seq, int offset, int length) {
- read_boolean_array(seq.value, offset, length);
- }
-
- public void read_char_array (org.omg.CORBA.CharSeqHolder seq, int offset, int length) {
- read_char_array(seq.value, offset, length);
- }
-
- public void read_wchar_array (org.omg.CORBA.WCharSeqHolder seq, int offset, int length) {
- read_wchar_array(seq.value, offset, length);
- }
-
- public void read_octet_array (org.omg.CORBA.OctetSeqHolder seq, int offset, int length) {
- read_octet_array(seq.value, offset, length);
- }
-
- public void read_short_array (org.omg.CORBA.ShortSeqHolder seq, int offset, int length) {
- read_short_array(seq.value, offset, length);
- }
-
- public void read_ushort_array (org.omg.CORBA.UShortSeqHolder seq, int offset, int length) {
- read_ushort_array(seq.value, offset, length);
- }
-
- public void read_long_array (org.omg.CORBA.LongSeqHolder seq, int offset, int length) {
- read_long_array(seq.value, offset, length);
- }
-
- public void read_ulong_array (org.omg.CORBA.ULongSeqHolder seq, int offset, int length) {
- read_ulong_array(seq.value, offset, length);
- }
-
- public void read_ulonglong_array (org.omg.CORBA.ULongLongSeqHolder seq, int offset, int length) {
- read_ulonglong_array(seq.value, offset, length);
- }
-
- public void read_longlong_array (org.omg.CORBA.LongLongSeqHolder seq, int offset, int length) {
- read_longlong_array(seq.value, offset, length);
- }
-
- public void read_float_array (org.omg.CORBA.FloatSeqHolder seq, int offset, int length) {
- read_float_array(seq.value, offset, length);
- }
-
- public void read_double_array (org.omg.CORBA.DoubleSeqHolder seq, int offset, int length) {
- read_double_array(seq.value, offset, length);
- }
-
- public java.math.BigDecimal read_fixed(short digits, short scale) {
- // digits isn't really needed here
- StringBuffer buffer = read_fixed_buffer();
- if (digits != buffer.length())
- throw wrapper.badFixed( new Integer(digits),
- new Integer(buffer.length()) ) ;
- buffer.insert(digits - scale, '.');
- return new BigDecimal(buffer.toString());
- }
-
- // This method is unable to yield the correct scale.
- public java.math.BigDecimal read_fixed() {
- return new BigDecimal(read_fixed_buffer().toString());
- }
-
- // Each octet contains (up to) two decimal digits.
- // If the fixed type has an odd number of decimal digits, then the representation
- // begins with the first (most significant) digit.
- // Otherwise, this first half-octet is all zero, and the first digit
- // is in the second half-octet.
- // The sign configuration, in the last half-octet of the representation,
- // is 0xD for negative numbers and 0xC for positive and zero values.
- private StringBuffer read_fixed_buffer() {
- StringBuffer buffer = new StringBuffer(64);
- byte doubleDigit;
- int firstDigit;
- int secondDigit;
- boolean wroteFirstDigit = false;
- boolean more = true;
- while (more) {
- doubleDigit = this.read_octet();
- firstDigit = (int)((doubleDigit & 0xf0) >> 4);
- secondDigit = (int)(doubleDigit & 0x0f);
- if (wroteFirstDigit || firstDigit != 0) {
- buffer.append(Character.forDigit(firstDigit, 10));
- wroteFirstDigit = true;
- }
- if (secondDigit == 12) {
- // positive number or zero
- if ( ! wroteFirstDigit) {
- // zero
- return new StringBuffer("0.0");
- } else {
- // positive number
- // done
- }
- more = false;
- } else if (secondDigit == 13) {
- // negative number
- buffer.insert(0, '-');
- more = false;
- } else {
- buffer.append(Character.forDigit(secondDigit, 10));
- wroteFirstDigit = true;
- }
- }
- return buffer;
- }
-
- private final static String _id = "IDL:omg.org/CORBA/DataInputStream:1.0";
- private final static String[] _ids = { _id };
-
- public String[] _truncatable_ids() {
- if (_ids == null)
- return null;
-
- return (String[])_ids.clone();
- }
-
- /* for debugging */
-
- public void printBuffer() {
- CDRInputStream_1_0.printBuffer(this.bbwi);
- }
-
- public static void printBuffer(ByteBufferWithInfo bbwi) {
-
- System.out.println("----- Input Buffer -----");
- System.out.println();
- System.out.println("Current position: " + bbwi.position());
- System.out.println("Total length : " + bbwi.buflen);
- System.out.println();
-
- try {
-
- char[] charBuf = new char[16];
-
- for (int i = 0; i < bbwi.buflen; i += 16) {
-
- int j = 0;
-
- // For every 16 bytes, there is one line
- // of output. First, the hex output of
- // the 16 bytes with each byte separated
- // by a space.
- while (j < 16 && j + i < bbwi.buflen) {
- int k = bbwi.byteBuffer.get(i + j);
- if (k < 0)
- k = 256 + k;
- String hex = Integer.toHexString(k);
- if (hex.length() == 1)
- hex = "0" + hex;
- System.out.print(hex + " ");
- j++;
- }
-
- // Add any extra spaces to align the
- // text column in case we didn't end
- // at 16
- while (j < 16) {
- System.out.print(" ");
- j++;
- }
-
- // Now output the ASCII equivalents. Non-ASCII
- // characters are shown as periods.
- int x = 0;
- while (x < 16 && x + i < bbwi.buflen) {
- if (ORBUtility.isPrintable((char)bbwi.byteBuffer.get(i + x)))
- charBuf[x] = (char)bbwi.byteBuffer.get(i + x);
- else
- charBuf[x] = '.';
- x++;
- }
- System.out.println(new String(charBuf, 0, x));
- }
-
- } catch (Throwable t) {
- t.printStackTrace();
- }
-
- System.out.println("------------------------");
- }
-
- public ByteBuffer getByteBuffer() {
- ByteBuffer result = null;
- if (bbwi != null) {
- result = bbwi.byteBuffer;
- }
- return result;
- }
-
- public int getBufferLength() {
- return bbwi.buflen;
- }
-
- public void setBufferLength(int value) {
- bbwi.buflen = value;
- bbwi.byteBuffer.limit(bbwi.buflen);
- }
-
- public void setByteBufferWithInfo(ByteBufferWithInfo bbwi) {
- this.bbwi = bbwi;
- }
-
- public void setByteBuffer(ByteBuffer byteBuffer) {
- bbwi.byteBuffer = byteBuffer;
- }
-
- public int getIndex() {
- return bbwi.position();
- }
-
- public void setIndex(int value) {
- bbwi.position(value);
- }
-
- public boolean isLittleEndian() {
- return littleEndian;
- }
-
- public void orb(org.omg.CORBA.ORB orb) {
- this.orb = (ORB)orb;
- }
-
- public BufferManagerRead getBufferManager() {
- return bufferManagerRead;
- }
-
- private void skipToOffset(int offset) {
-
- // Number of bytes to skip
- int len = offset - get_offset();
-
- int n = 0;
-
- while (n < len) {
- int avail;
- int bytes;
- int wanted;
-
- avail = bbwi.buflen - bbwi.position();
- if (avail <= 0) {
- grow(1, 1);
- avail = bbwi.buflen - bbwi.position();
- }
-
- wanted = len - n;
- bytes = (wanted < avail) ? wanted : avail;
- bbwi.position(bbwi.position() + bytes);
- n += bytes;
- }
- }
-
-
- // Mark and reset -------------------------------------------------
-
- protected MarkAndResetHandler markAndResetHandler = null;
-
- protected class StreamMemento
- {
- // These are the fields that may change after marking
- // the stream position, so we need to save them.
- private int blockLength_;
- private int end_flag_;
- private int chunkedValueNestingLevel_;
- private int valueIndirection_;
- private int stringIndirection_;
- private boolean isChunked_;
- private javax.rmi.CORBA.ValueHandler valueHandler_;
- private ByteBufferWithInfo bbwi_;
- private boolean specialNoOptionalDataState_;
-
- public StreamMemento()
- {
- blockLength_ = blockLength;
- end_flag_ = end_flag;
- chunkedValueNestingLevel_ = chunkedValueNestingLevel;
- valueIndirection_ = valueIndirection;
- stringIndirection_ = stringIndirection;
- isChunked_ = isChunked;
- valueHandler_ = valueHandler;
- specialNoOptionalDataState_ = specialNoOptionalDataState;
- bbwi_ = new ByteBufferWithInfo(bbwi);
- }
- }
-
- public java.lang.Object createStreamMemento() {
- return new StreamMemento();
- }
-
- public void restoreInternalState(java.lang.Object streamMemento) {
-
- StreamMemento mem = (StreamMemento)streamMemento;
-
- blockLength = mem.blockLength_;
- end_flag = mem.end_flag_;
- chunkedValueNestingLevel = mem.chunkedValueNestingLevel_;
- valueIndirection = mem.valueIndirection_;
- stringIndirection = mem.stringIndirection_;
- isChunked = mem.isChunked_;
- valueHandler = mem.valueHandler_;
- specialNoOptionalDataState = mem.specialNoOptionalDataState_;
- bbwi = mem.bbwi_;
- }
-
- public int getPosition() {
- return get_offset();
- }
-
- public void mark(int readlimit) {
- markAndResetHandler.mark(this);
- }
-
- public void reset() {
- markAndResetHandler.reset();
- }
-
- // ---------------------------------- end Mark and Reset
-
- // Provides a hook so subclasses of CDRInputStream can provide
- // a CodeBase. This ultimately allows us to grab a Connection
- // instance in IIOPInputStream, the only subclass where this
- // is actually used.
- CodeBase getCodeBase() {
- return parent.getCodeBase();
- }
-
- /**
- * Attempts to find the class described by the given
- * repository ID string and expected type. The first
- * attempt is to find the class locally, falling back
- * on the URL that came with the value. The second
- * attempt is to use a URL from the remote CodeBase.
- */
- private Class getClassFromString(String repositoryIDString,
- String codebaseURL,
- Class expectedType)
- {
- RepositoryIdInterface repositoryID
- = repIdStrs.getFromString(repositoryIDString);
-
- try {
- try {
- // First try to load the class locally, then use
- // the provided URL (if it isn't null)
- return repositoryID.getClassFromType(expectedType,
- codebaseURL);
- } catch (ClassNotFoundException cnfeOuter) {
-
- try {
-
- if (getCodeBase() == null) {
- return null; // class cannot be loaded remotely.
- }
-
- // Get a URL from the remote CodeBase and retry
- codebaseURL = getCodeBase().implementation(repositoryIDString);
-
- // Don't bother trying to find it locally again if
- // we got a null URL
- if (codebaseURL == null)
- return null;
-
- return repositoryID.getClassFromType(expectedType,
- codebaseURL);
- } catch (ClassNotFoundException cnfeInner) {
- dprintThrowable(cnfeInner);
- // Failed to load the class
- return null;
- }
- }
- } catch (MalformedURLException mue) {
- // Always report a bad URL
- throw wrapper.malformedUrl( CompletionStatus.COMPLETED_MAYBE,
- mue, repositoryIDString, codebaseURL ) ;
- }
- }
-
- /**
- * Attempts to find the class described by the given
- * repository ID string. At most, three attempts are made:
- * Try to find it locally, through the provided URL, and
- * finally, via a URL from the remote CodeBase.
- */
- private Class getClassFromString(String repositoryIDString,
- String codebaseURL)
- {
- RepositoryIdInterface repositoryID
- = repIdStrs.getFromString(repositoryIDString);
-
- for (int i = 0; i < 3; i++) {
-
- try {
-
- switch (i)
- {
- case 0:
- // First try to load the class locally
- return repositoryID.getClassFromType();
- case 1:
- // Try to load the class using the provided
- // codebase URL (falls out below)
- break;
- case 2:
- // Try to load the class using a URL from the
- // remote CodeBase
- codebaseURL = getCodeBase().implementation(repositoryIDString);
- break;
- }
-
- // Don't bother if the codebaseURL is null
- if (codebaseURL == null)
- continue;
-
- return repositoryID.getClassFromType(codebaseURL);
-
- } catch(ClassNotFoundException cnfe) {
- // Will ultimately return null if all three
- // attempts fail, but don't do anything here.
- } catch (MalformedURLException mue) {
- throw wrapper.malformedUrl( CompletionStatus.COMPLETED_MAYBE,
- mue, repositoryIDString, codebaseURL ) ;
- }
- }
-
- // If we get here, we have failed to load the class
- dprint("getClassFromString failed with rep id "
- + repositoryIDString
- + " and codebase "
- + codebaseURL);
-
- return null;
- }
-
- // Utility method used to get chars from bytes
- char[] getConvertedChars(int numBytes,
- CodeSetConversion.BTCConverter converter) {
-
- // REVISIT - Look at CodeSetConversion.BTCConverter to see
- // if it can work with an NIO ByteBuffer. We should
- // avoid getting the bytes into an array if possible.
-
- // To be honest, I doubt this saves much real time
- if (bbwi.buflen - bbwi.position() >= numBytes) {
- // If the entire string is in this buffer,
- // just convert directly from the bbwi rather than
- // allocating and copying.
- byte[] tmpBuf;
- if (bbwi.byteBuffer.hasArray())
- {
- tmpBuf = bbwi.byteBuffer.array();
- }
- else
- {
- tmpBuf = new byte[bbwi.buflen];
- // Microbenchmarks are showing a loop of ByteBuffer.get(int)
- // being faster than ByteBuffer.get(byte[], int, int).
- for (int i = 0; i < bbwi.buflen; i++)
- tmpBuf[i] = bbwi.byteBuffer.get(i);
- }
- char[] result = converter.getChars(tmpBuf,bbwi.position(),numBytes);
-
- bbwi.position(bbwi.position() + numBytes);
- return result;
- } else {
- // Stretches across buffers. Unless we provide an
- // incremental conversion interface, allocate and
- // copy the bytes.
- byte[] bytes = new byte[numBytes];
- read_octet_array(bytes, 0, bytes.length);
-
- return converter.getChars(bytes, 0, numBytes);
- }
- }
-
- protected CodeSetConversion.BTCConverter getCharConverter() {
- if (charConverter == null)
- charConverter = parent.createCharBTCConverter();
-
- return charConverter;
- }
-
- protected CodeSetConversion.BTCConverter getWCharConverter() {
- if (wcharConverter == null)
- wcharConverter = parent.createWCharBTCConverter();
-
- return wcharConverter;
- }
-
- protected void dprintThrowable(Throwable t) {
- if (debug && t != null)
- t.printStackTrace();
- }
-
- protected void dprint(String msg) {
- if (debug) {
- ORBUtility.dprint(this, msg);
- }
- }
-
- /**
- * Aligns the current position on the given octet boundary
- * if there are enough bytes available to do so. Otherwise,
- * it just returns. This is used for some (but not all)
- * GIOP 1.2 message headers.
- */
-
- void alignOnBoundary(int octetBoundary) {
- int needed = computeAlignment(bbwi.position(), octetBoundary);
-
- if (bbwi.position() + needed <= bbwi.buflen)
- {
- bbwi.position(bbwi.position() + needed);
- }
- }
-
- public void resetCodeSetConverters() {
- charConverter = null;
- wcharConverter = null;
- }
-
- public void start_value() {
- // Read value tag
- int vType = readValueTag();
-
- if (vType == 0) {
- // Stream needs to go into a state where it
- // throws standard exception until end_value
- // is called. This means the sender didn't
- // send any custom data. If the reader here
- // tries to read more, we need to throw an
- // exception before reading beyond where
- // we're supposed to
- specialNoOptionalDataState = true;
-
- return;
- }
-
- if (vType == 0xffffffff) {
- // One should never indirect to a custom wrapper
- throw wrapper.customWrapperIndirection(
- CompletionStatus.COMPLETED_MAYBE);
- }
-
- if (repIdUtil.isCodeBasePresent(vType)) {
- throw wrapper.customWrapperWithCodebase(
- CompletionStatus.COMPLETED_MAYBE);
- }
-
- if (repIdUtil.getTypeInfo(vType)
- != RepositoryIdUtility.SINGLE_REP_TYPE_INFO) {
- throw wrapper.customWrapperNotSingleRepid(
- CompletionStatus.COMPLETED_MAYBE);
- }
-
-
- // REVISIT - Could verify repository ID even though
- // it isn't used elsewhere
- read_repositoryId();
-
- // Note: isChunked should be true here. Should have
- // been set to true in the containing value's read_value
- // method.
-
- start_block();
- end_flag--;
- chunkedValueNestingLevel--;
- }
-
- public void end_value() {
-
- if (specialNoOptionalDataState) {
- specialNoOptionalDataState = false;
- return;
- }
-
- handleEndOfValue();
- readEndTag();
-
- // Note that isChunked should still be true here.
- // If the containing valuetype is the highest
- // chunked value, it will get set to false
- // at the end of read_value.
-
- // allow for possible continuation chunk
- start_block();
- }
-
- public void close() throws IOException
- {
-
- // tell BufferManagerRead to release any ByteBuffers
- getBufferManager().close(bbwi);
-
- // It's possible bbwi.byteBuffer is shared between
- // this InputStream and an OutputStream. Thus, we check
- // if the Input/Output streams are using the same ByteBuffer.
- // If they sharing the same ByteBuffer we need to ensure only
- // one of those ByteBuffers are released to the ByteBufferPool.
-
- if (bbwi != null && getByteBuffer() != null)
- {
- int bbHash = System.identityHashCode(bbwi.byteBuffer);
- MessageMediator messageMediator = parent.getMessageMediator();
- if (messageMediator != null)
- {
- CDROutputObject outputObj =
- (CDROutputObject)messageMediator.getOutputObject();
- if (outputObj != null)
- {
- ByteBuffer outputBb = outputObj.getByteBuffer();
-
- int oBbHash = 0;
- if (outputBb != null)
- {
- oBbHash = System.identityHashCode(outputBb);
- if (bbHash == oBbHash) // shared?
- {
- // Set OutputStream's ByteBuffer and bbwi to null
- // so its ByteBuffer cannot be released to the pool
- outputObj.setByteBuffer(null);
- outputObj.setByteBufferWithInfo(null);
- }
- }
- }
- }
-
- // release this stream's ByteBuffer to the pool
- ByteBufferPool byteBufferPool = orb.getByteBufferPool();
- if (debug)
- {
- // print address of ByteBuffer being released
- int bbAddress = System.identityHashCode(bbwi.byteBuffer);
- StringBuffer sb = new StringBuffer(80);
- sb.append(".close - releasing ByteBuffer id (");
- sb.append(bbAddress).append(") to ByteBufferPool.");
- String msg = sb.toString();
- dprint(msg);
- }
- byteBufferPool.releaseByteBuffer(bbwi.byteBuffer);
- bbwi.byteBuffer = null;
- bbwi = null;
- }
- }
- }