alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (CDRInputStream_1_0.java)

This example Java source code file (CDRInputStream_1_0.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

buffermanagerread, bytebufferwithinfo, cachetable, cdrinputstreambase, class, classnotfoundexception, corba, indirection, indirectionexception, integer, net, network, reflection, rmi, security, serializable, streammemento, string, stringbuffer, typecodeimpl

The CDRInputStream_1_0.java Java example source code

/*
 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * Licensed Materials - Property of IBM
 * RMI-IIOP v1.0
 * Copyright IBM Corp. 1998 1999  All Rights Reserved
 *
 */

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();
        repIdStrs = RepositoryIdFactory.getRepIdStringsFactory();
    }

    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);

        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());
    }

    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);
        }
    }

    private String readRepositoryIds(int valueTag,
                                     Class expectedType,
                                     String expectedTypeRepId) {
        return readRepositoryIds(valueTag, expectedType,
                                 expectedTypeRepId, null);
    }

    /**
     * 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). Failing that, it uses the supplied
     * BoxedValueHelper to obtain the repository ID, as a last resort.
     */
    private String readRepositoryIds(int valueTag,
                                     Class expectedType,
                                     String expectedTypeRepId,
                                     BoxedValueHelper factory) {
        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 if (factory != null) {
                        return factory.get_id();
                    } 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();

                    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, factory);

            // 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)
        {
            MessageMediator messageMediator = parent.getMessageMediator();
            if (messageMediator != null)
            {
                CDROutputObject outputObj =
                             (CDROutputObject)messageMediator.getOutputObject();
                if (outputObj != null)
                {
                    if (outputObj.isSharing(getByteBuffer()))
                    {
                        // 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;
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java CDRInputStream_1_0.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.