FileDocCategorySizeDatePackage
IIOPInputStream.javaAPI DocJava SE 5 API97784Fri Aug 26 14:54:22 BST 2005com.sun.corba.se.impl.io

IIOPInputStream

public class IIOPInputStream extends com.sun.corba.se.impl.io.InputStreamHook
IIOPInputStream is used by the ValueHandlerImpl to handle Java serialization input semantics.
author
Stephen Lewallen
since
JDK1.1.6

Fields Summary
private static sun.corba.Bridge
bridge
private static com.sun.corba.se.impl.logging.OMGSystemException
omgWrapper
private static com.sun.corba.se.impl.logging.UtilSystemException
utilWrapper
private org.omg.CORBA.ValueMember[]
defaultReadObjectFVDMembers
private org.omg.CORBA_2_3.portable.InputStream
orbStream
private com.sun.org.omg.SendingContext.CodeBase
cbSender
private ValueHandlerImpl
vhandler
private Object
currentObject
private com.sun.corba.se.impl.io.ObjectStreamClass
currentClassDesc
private Class
currentClass
private int
recursionDepth
private int
simpleReadDepth
ActiveRecursionManager
activeRecursionMgr
private IOException
abortIOException
private ClassNotFoundException
abortClassNotFoundException
private Vector
callbacks
com.sun.corba.se.impl.io.ObjectStreamClass[]
classdesc
Class[]
classes
int
spClass
private static final String
kEmptyStr
public static final org.omg.CORBA.TypeCode
kRemoteTypeCode
public static final org.omg.CORBA.TypeCode
kValueTypeCode
private static final boolean
useFVDOnly
private byte
streamFormatVersion
private static final Constructor
OPT_DATA_EXCEPTION_CTOR
private Object[]
readObjectArgList
Constructors Summary
public IIOPInputStream()
Dummy constructor; passes upper stream a dummy stream;

    	super();
	resetStream();
    
Methods Summary
public final intavailable()

        return 0; // unreliable
    
public final voidclose()

        // no op
    
private java.io.OptionalDataExceptioncreateOptionalDataException()

        try {
            OptionalDataException result
                = (OptionalDataException)
                   OPT_DATA_EXCEPTION_CTOR.newInstance(new Object[] { 
                       Boolean.TRUE });

            if (result == null)
		// XXX I18N, logging needed.
                throw new Error("Created null OptionalDataException");

            return result;

        } catch (Exception ex) {
	    // XXX I18N, logging needed.
            throw new Error("Couldn't create OptionalDataException", ex);
        }
    
public final intdecreaseRecursionDepth()

	return --recursionDepth;
    
public final voiddefaultReadObjectDelegate()
Override the actions of the final method "defaultReadObject()" in ObjectInputStream.

since
JDK1.1.6 Read the non-static and non-transient fields of the current class from this stream. This may only be called from the readObject method of the class being deserialized. It will throw the NotActiveException if it is called otherwise.
exception
java.lang.ClassNotFoundException if the class of a serialized object could not be found.
exception
IOException if an I/O error occurs.
exception
NotActiveException if the stream is not currently reading objects.
since
JDK1.1

        try {
	    if (currentObject == null || currentClassDesc == null)
		// XXX I18N, logging needed.
		throw new NotActiveException("defaultReadObjectDelegate");

            // The array will be null unless fields were retrieved
            // remotely because of a serializable version difference.
            // Bug fix for 4365188.  See the definition of
            // defaultReadObjectFVDMembers for more information.
            if (defaultReadObjectFVDMembers != null &&
                defaultReadObjectFVDMembers.length > 0) {

                // WARNING:  Be very careful!  What if some of
                // these fields actually have to do this, too?
                // This works because the defaultReadObjectFVDMembers
                // reference is passed to inputClassFields, but
                // there is no guarantee that
                // defaultReadObjectFVDMembers will point to the
                // same array after calling inputClassFields.

                // Use the remote fields to unmarshal.
                inputClassFields(currentObject, 
                                 currentClass, 
                                 currentClassDesc,
                                 defaultReadObjectFVDMembers,
                                 cbSender);

            } else {

                // Use the local fields to unmarshal.
                ObjectStreamField[] fields =
                    currentClassDesc.getFieldsNoCopy();
                if (fields.length > 0) {
                    inputClassFields(currentObject, currentClass, fields, cbSender); 
                }
            }
        }
        catch(NotActiveException nae)
	    {
		bridge.throwException( nae ) ;
	    }
        catch(IOException ioe)
	    {
		bridge.throwException( ioe ) ;
	    }
        catch(ClassNotFoundException cnfe)
	    {
		bridge.throwException( cnfe ) ;
	    }

    
public final booleanenableResolveObjectDelegate(boolean enable)
Override the actions of the final method "enableResolveObject()" in ObjectInputStream.

since
JDK1.1.6 Enable the stream to allow objects read from the stream to be replaced. If the stream is a trusted class it is allowed to enable replacment. Trusted classes are those classes with a classLoader equals null.

When enabled the resolveObject method is called for every object being deserialized.

exception
SecurityException The classloader of this stream object is non-null.
since
JDK1.1

	return false;
    
private intfindNextClass(java.lang.String classname, java.lang.Class[] classes, int _spClass, int _spBase)


	for (int i = _spClass; i > _spBase; i--){
	    if (classname.equals(classes[i].getName())) {
		return i;
	    }
	}

	return -1;
    
private static java.lang.reflect.ConstructorgetOptDataExceptionCtor()


     
        OPT_DATA_EXCEPTION_CTOR = getOptDataExceptionCtor();
    

        try {

            Constructor result =
                
                (Constructor) AccessController.doPrivileged(
                                    new PrivilegedExceptionAction() {
                    public java.lang.Object run() 
                        throws NoSuchMethodException,
                        SecurityException {
                        
                        Constructor boolCtor 
                            = OptionalDataException.class.getDeclaredConstructor(
                                                               new Class[] {
                                Boolean.TYPE });
                        
                        boolCtor.setAccessible(true);
                        
                        return boolCtor;
                    }});
            
            if (result == null)
		// XXX I18N, logging needed.
                throw new Error("Unable to find OptionalDataException constructor");
        
            return result;

        } catch (Exception ex) {
	    // XXX I18N, logging needed.
            throw new ExceptionInInitializerError(ex);
        }
    
public final org.omg.CORBA_2_3.portable.InputStreamgetOrbStream()

    	return orbStream;
    
private java.util.VectorgetOrderedDescriptions(java.lang.String repositoryID, com.sun.org.omg.SendingContext.CodeBase sender)

	Vector descs = new Vector();

        if (sender == null) {
            return descs;
        }
        
	FullValueDescription aFVD = sender.meta(repositoryID);
	while (aFVD != null) {
	    descs.insertElementAt(aFVD, 0);
	    if ((aFVD.base_value != null) && !kEmptyStr.equals(aFVD.base_value)) {
		aFVD = sender.meta(aFVD.base_value);
	    }
	    else return descs;
	}

	return descs;
    
public final com.sun.org.omg.SendingContext.CodeBasegetSender()

        return cbSender;
    
protected bytegetStreamFormatVersion()

        return streamFormatVersion;
    
public final javax.rmi.CORBA.ValueHandlergetValueHandler()

	return (javax.rmi.CORBA.ValueHandler) vhandler;
    
private voidhandleOptionalDataMarshalException(org.omg.CORBA.MARSHAL marshalException, boolean objectRead)


        // Java Object Serialization spec 3.4: "If the readObject method
        // of the class attempts to read more data than is present in the
        // optional part of the stream for this class, the stream will
        // return -1 for bytewise reads, throw an EOFException for
        // primitive data reads, or throw an OptionalDataException
        // with the eof field set to true for object reads."
        if (marshalException.minor 
            == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) {

            IOException result;

            if (!objectRead)
                result = new EOFException("No more optional data");
            else
                result = createOptionalDataException();

            result.initCause(marshalException);

            setState(IN_READ_OBJECT_NO_MORE_OPT_DATA);

            throw result;
        }
    
public final voidincreaseRecursionDepth()

	recursionDepth++;
    
private voidinputClassFields(java.lang.Object o, java.lang.Class cl, ObjectStreamField[] fields, com.sun.org.omg.SendingContext.CodeBase sender)

		
	int primFields = fields.length - currentClassDesc.objFields;

	if (o != null) {
	    for (int i = 0; i < primFields; ++i) {
		if (fields[i].getField() == null)
		    continue;

                inputPrimitiveField(o, cl, fields[i]);
	    }
	}

	/* Read and set object fields from the input stream. */
	if (currentClassDesc.objFields > 0) {
	    for (int i = primFields; i < fields.length; i++) {
		Object objectValue = null;

                try {
                    objectValue = inputObjectField(fields[i]);
                } catch(IndirectionException cdrie) {
                    // The CDR stream had never seen the given offset before,
                    // so check the recursion manager (it will throw an
                    // IOException if it doesn't have a reference, either).
                    objectValue = activeRecursionMgr.getObject(cdrie.offset);
                }

		if ((o == null) || (fields[i].getField() == null)) {
		    continue;
		}

		try {
		    bridge.putObject( o, fields[i].getFieldID(), objectValue ) ;
		    // reflective code: fields[i].getField().set( o, objectValue ) ;
		} catch (IllegalArgumentException e) {
		    ClassCastException exc = new ClassCastException("Assigning instance of class " +
						 objectValue.getClass().getName() +
						 " to field " +
						 currentClassDesc.getName() +
						 '#" +
						 fields[i].getField().getName());
		    exc.initCause( e ) ;
		    throw exc ;
		}
	    } // end : for loop
	    }
	
private voidinputClassFields(java.lang.Object o, java.lang.Class cl, com.sun.corba.se.impl.io.ObjectStreamClass osc, org.omg.CORBA.ValueMember[] fields, com.sun.org.omg.SendingContext.CodeBase sender)

	try{
	    for (int i = 0; i < fields.length; ++i) {
		try {
		    switch (fields[i].type.kind().value()) {
		    case TCKind._tk_octet:
			byte byteValue = orbStream.read_octet();
			if ((o != null) && osc.hasField(fields[i]))
			setByteField(o, cl, fields[i].name, byteValue);
			break;
		    case TCKind._tk_boolean:
			boolean booleanValue = orbStream.read_boolean();
			if ((o != null) && osc.hasField(fields[i]))
			setBooleanField(o, cl, fields[i].name, booleanValue);
			break;
		    case TCKind._tk_char:
                        // Backwards compatibility.  Older Sun ORBs sent
                        // _tk_char even though they read and wrote wchars
                        // correctly.
                        //
                        // Fall through to the _tk_wchar case.
                    case TCKind._tk_wchar:
			char charValue = orbStream.read_wchar();
			if ((o != null) && osc.hasField(fields[i]))
			setCharField(o, cl, fields[i].name, charValue);
			break;
		    case TCKind._tk_short:
			short shortValue = orbStream.read_short();
			if ((o != null) && osc.hasField(fields[i]))
			setShortField(o, cl, fields[i].name, shortValue);
			break;
		    case TCKind._tk_long:
			int intValue = orbStream.read_long();
			if ((o != null) && osc.hasField(fields[i]))
			setIntField(o, cl, fields[i].name, intValue);
			break;
		    case TCKind._tk_longlong:
			long longValue = orbStream.read_longlong();
			if ((o != null) && osc.hasField(fields[i]))
			setLongField(o, cl, fields[i].name, longValue);
			break;
		    case TCKind._tk_float:
			float floatValue = orbStream.read_float();
			if ((o != null) && osc.hasField(fields[i]))
			setFloatField(o, cl, fields[i].name, floatValue);
			break;
		    case TCKind._tk_double:
			double doubleValue = orbStream.read_double();
			if ((o != null) && osc.hasField(fields[i]))
			setDoubleField(o, cl, fields[i].name, doubleValue);
			break;
                    case TCKind._tk_value:
		    case TCKind._tk_objref:
		    case TCKind._tk_value_box:
                        Object objectValue = null;
                        try {
                            objectValue = inputObjectField(fields[i], sender);
                        } catch (IndirectionException cdrie) {
                            // The CDR stream had never seen the given offset before,
                            // so check the recursion manager (it will throw an
                            // IOException if it doesn't have a reference, either).
                            objectValue = activeRecursionMgr.getObject(cdrie.offset);
                        }
								
			if (o == null)
			    continue;
			try {
			    if (osc.hasField(fields[i])){
                                setObjectField(o, 
                                               cl, 
                                               fields[i].name, 
                                               objectValue);
			    } else {
                                // REVISIT.  Convert to a log message.
                                // This is a normal case when fields have
                                // been added as part of evolution, but
                                // silently skipping can make it hard to
                                // debug if there's an error
//                                 System.out.println("**** warning, not setting field: "
//                                                    + fields[i].name
//                                                    + " since not on class "
//                                                    + osc.getName());

                            }
			} catch (IllegalArgumentException e) {
			    // XXX I18N, logging needed.
			    ClassCastException cce = new ClassCastException("Assigning instance of class " + 
				objectValue.getClass().getName() + " to field " + fields[i].name);
			    cce.initCause(e) ;
			    throw cce ;
			}		
			break;
                    default:
			// XXX I18N, logging needed.
                        throw new StreamCorruptedException("Unknown kind: "
                                                           + fields[i].type.kind().value());
		    }
		} catch (IllegalArgumentException e) {
		    /* This case should never happen. If the field types
		       are not the same, InvalidClassException is raised when
		       matching the local class to the serialized ObjectStreamClass. */
		    // XXX I18N, logging needed.
		    ClassCastException cce = new ClassCastException("Assigning instance of class " + fields[i].id + 
			" to field " + currentClassDesc.getName() + '#" + fields[i].name);
		    cce.initCause( e ) ;
		    throw cce ;
		}
	    }
	} catch(Throwable t){
	    // XXX I18N, logging needed.
	    StreamCorruptedException sce = new StreamCorruptedException(t.getMessage());
	    sce.initCause(t) ;
	    throw sce ;
	}
    
private final voidinputCurrentClassFieldsForReadFields(java.util.Map fieldToValueMap)
Called from InputStreamHook. Reads the fields of the current class (could be the ones queried from the remote FVD) and puts them in the given Map, name to value. Wraps primitives in the corresponding java.lang Objects.


        ObjectStreamField[] fields = currentClassDesc.getFieldsNoCopy();

	int primFields = fields.length - currentClassDesc.objFields;

        // Handle the primitives first
        for (int i = 0; i < primFields; ++i) {

            switch (fields[i].getTypeCode()) {
                case 'B":
                    byte byteValue = orbStream.read_octet();
                    fieldToValueMap.put(fields[i].getName(),
                                        new Byte(byteValue));
                    break;
                case 'Z":
                   boolean booleanValue = orbStream.read_boolean();
                   fieldToValueMap.put(fields[i].getName(),
                                       new Boolean(booleanValue));
                   break;
		case 'C":
                    char charValue = orbStream.read_wchar();
                    fieldToValueMap.put(fields[i].getName(),
                                        new Character(charValue));
                    break;
		case 'S":
                    short shortValue = orbStream.read_short();
                    fieldToValueMap.put(fields[i].getName(),
                                        new Short(shortValue));
                    break;
		case 'I":
                    int intValue = orbStream.read_long();
                    fieldToValueMap.put(fields[i].getName(),
                                        new Integer(intValue));
                    break;
		case 'J":
                    long longValue = orbStream.read_longlong();
                    fieldToValueMap.put(fields[i].getName(),
                                        new Long(longValue));
                    break;
		case 'F" :
                    float floatValue = orbStream.read_float();
                    fieldToValueMap.put(fields[i].getName(),
                                        new Float(floatValue));
                    break;
		case 'D" :
                    double doubleValue = orbStream.read_double();
                    fieldToValueMap.put(fields[i].getName(),
                                        new Double(doubleValue));
                    break;
		default:
		    // XXX I18N, logging needed.
                    throw new InvalidClassException(currentClassDesc.getName());
	    }
	}

	/* Read and set object fields from the input stream. */
	if (currentClassDesc.objFields > 0) {
	    for (int i = primFields; i < fields.length; i++) {
                Object objectValue = null;
                try {
                    objectValue = inputObjectField(fields[i]);
                } catch(IndirectionException cdrie) {
                    // The CDR stream had never seen the given offset before,
                    // so check the recursion manager (it will throw an
                    // IOException if it doesn't have a reference, either).
                    objectValue = activeRecursionMgr.getObject(cdrie.offset);
                }

                fieldToValueMap.put(fields[i].getName(), objectValue);
            }
        }
    
private java.lang.ObjectinputObject(java.lang.Class clz, java.lang.String repositoryID, com.sun.org.omg.SendingContext.CodeBase sender, int offset)


    	/*
    	 * Get the descriptor and then class of the incoming object.
    	 */

    	currentClassDesc = ObjectStreamClass.lookup(clz);
    	currentClass = currentClassDesc.forClass();
    	//currentClassDesc.setClass(currentClass);
    	if (currentClass == null)
	    // XXX I18N, logging needed.
    	    throw new ClassNotFoundException(currentClassDesc.getName());

        try {
            /* If Externalizable,
             *  Create an instance and tell it to read its data.
             * else,
             *  Handle it as a serializable class.
             */
            if (currentClassDesc.isExternalizable()) {
                try {
                    currentObject = (currentClass == null) ?
                        null : currentClassDesc.newInstance();
                    if (currentObject != null) {

                        // Store this object and its beginning position
                        // since there might be indirections to it while
                        // it's been unmarshalled.
                        activeRecursionMgr.addObject(offset, currentObject);

                        // Read format version
                        readFormatVersion();

                        Externalizable ext = (Externalizable)currentObject;
                        ext.readExternal(this);
		}
	    } catch (InvocationTargetException e) {
		InvalidClassException exc = new InvalidClassException(
		    currentClass.getName(), 
		    "InvocationTargetException accessing no-arg constructor");
		exc.initCause( e ) ;
		throw exc ;
	    } catch (UnsupportedOperationException e) {
		InvalidClassException exc = new InvalidClassException(
		    currentClass.getName(), 
		    "UnsupportedOperationException accessing no-arg constructor");
		exc.initCause( e ) ;
		throw exc ;
    	    } catch (InstantiationException e) {
		InvalidClassException exc = new InvalidClassException(
		    currentClass.getName(), 
		    "InstantiationException accessing no-arg constructor");
		exc.initCause( e ) ;
		throw exc ;
    	    }
    	} // end : if (currentClassDesc.isExternalizable())
	else {
    	    /* Count number of classes and descriptors we might have
    	     * to work on.
    	     */

    	    ObjectStreamClass currdesc = currentClassDesc;
    	    Class currclass = currentClass;

    	    int spBase = spClass;	// current top of stack

    	    /* The object's classes should be processed from supertype to subtype
    	     * Push all the clases of the current object onto a stack.
    	     * Note that only the serializable classes are represented
    	     * in the descriptor list.
    	     *
    	     * Handle versioning where one or more supertypes of
    	     * have been inserted or removed.  The stack will
    	     * contain pairs of descriptors and the corresponding
    	     * class.  If the object has a class that did not occur in
    	     * the original the descriptor will be null.  If the
    	     * original object had a descriptor for a class not
    	     * present in the local hierarchy of the object the class will be
    	     * null.
    	     *
    	     */

    	    /*
    	     * This is your basic diff pattern, made simpler
    	     * because reordering is not allowed.
    	     */
            // sun.4296963 ibm.11861 
            // d11861 we should stop when we find the highest serializable class
            // We need this so that when we allocate the new object below, we
            // can call the constructor of the non-serializable superclass.
            // Note that in the JRMP variant of this code the
            // ObjectStreamClass.lookup() method handles this, but we've put
            // this fix here rather than change lookup because the new behaviour
            // is needed in other cases.

    	    for (currdesc = currentClassDesc, currclass = currentClass;
    		 currdesc != null && currdesc.isSerializable();   /*sun.4296963 ibm.11861*/
    		 currdesc = currdesc.getSuperclass()) {

    		/*
    		 * Search the classes to see if the class of this
    		 * descriptor appears further up the hierarchy. Until
    		 * it's found assume its an inserted class.  If it's
    		 * not found, its the descriptor's class that has been
    		 * removed.
    		 */
    		Class cc = currdesc.forClass();
    		Class cl;
    		for (cl = currclass; cl != null; cl = cl.getSuperclass()) {
    		    if (cc == cl) {
    			// found a superclass that matches this descriptor
    			break;
    		    } else {
    			/* Ignore a class that doesn't match.  No
    			 * action is needed since it is already
    			 * initialized.
    			 */
    		    }
		} // end : for (cl = currclass; cl != null; cl = cl.getSuperclass()) 
    		/* Test if there is room for this new entry.
    		 * If not, double the size of the arrays and copy the contents.
    		 */
    		spClass++;
    		if (spClass >= classes.length) {
    		    int newlen = classes.length * 2;
    		    Class[] newclasses = new Class[newlen];
    		    ObjectStreamClass[] newclassdesc = new ObjectStreamClass[newlen];

    		    System.arraycopy(classes, 0,
				     newclasses, 0,
				     classes.length);
    		    System.arraycopy(classdesc, 0,
    				     newclassdesc, 0,
    				     classes.length);

    		    classes = newclasses;
    		    classdesc = newclassdesc;
    		}

    		if (cl == null) {
    		    /* Class not found corresponding to this descriptor.
    		     * Pop off all the extra classes pushed.
    		     * Push the descriptor and a null class.
    		     */
    		    classdesc[spClass] = currdesc;
    		    classes[spClass] = null;
    		} else {
		    /* Current class descriptor matches current class.
    		     * Some classes may have been inserted.
    		     * Record the match and advance the class, continue
    		     * with the next descriptor.
    		     */
    		    classdesc[spClass] = currdesc;
    		    classes[spClass] = cl;
    		    currclass = cl.getSuperclass();
    		}
    	    } // end : for (currdesc = currentClassDesc, currclass = currentClass;

    	    /* Allocate a new object.  The object is only constructed
    	     * above the highest serializable class and is set to
    	     * default values for all more specialized classes.
    	     */
    	    try {
    		currentObject = (currentClass == null) ?
		    null : currentClassDesc.newInstance() ;

                // Store this object and its beginning position
                // since there might be indirections to it while
                // it's been unmarshalled.
                activeRecursionMgr.addObject(offset, currentObject);
	    } catch (InvocationTargetException e) {
		InvalidClassException exc = new InvalidClassException(
		    currentClass.getName(), 
		    "InvocationTargetException accessing no-arg constructor");
		exc.initCause( e ) ;
		throw exc ;
	    } catch (UnsupportedOperationException e) {
		InvalidClassException exc = new InvalidClassException(
		    currentClass.getName(), 
		    "UnsupportedOperationException accessing no-arg constructor");
		exc.initCause( e ) ;
		throw exc ;
    	    } catch (InstantiationException e) {
		InvalidClassException exc = new InvalidClassException(
		    currentClass.getName(), 
		    "InstantiationException accessing no-arg constructor");
		exc.initCause( e ) ;
		throw exc ;
    	    }

    	    /*
    	     * For all the pushed descriptors and classes.
    	     * 	if the class has its own writeObject and readObject methods
    	     *	    call the readObject method
    	     *	else
    	     *	    invoke the defaultReadObject method
    	     */
    	    try {
    		for (spClass = spClass; spClass > spBase; spClass--) {
    		    /*
    		     * Set current descriptor and corresponding class
    		     */
    		    currentClassDesc = classdesc[spClass];
    		    currentClass = classes[spClass];
    		    if (classes[spClass] != null) {
    			/* Read the data from the stream described by the
    			 * descriptor and store into the matching class.
    			 */

                        ReadObjectState oldState = readObjectState;
                        setState(DEFAULT_STATE);

                        try {

                            // Changed since invokeObjectReader no longer does this.
                            if (currentClassDesc.hasWriteObject()) {

                                // Read format version
                                readFormatVersion();

                                // Read defaultWriteObject indicator
                                boolean calledDefaultWriteObject = readBoolean();

                                readObjectState.beginUnmarshalCustomValue(this,
                                                                          calledDefaultWriteObject,
                                                                          (currentClassDesc.readObjectMethod
                                                                           != null));
                            } else {
                                if (currentClassDesc.hasReadObject())
                                    setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED);
                            }

                            if (!invokeObjectReader(currentClassDesc, currentObject, currentClass) ||
                                readObjectState == IN_READ_OBJECT_DEFAULTS_SENT) {

                                // Error case of no readObject and didn't call
                                // defaultWriteObject handled in default state

				ObjectStreamField[] fields =
				    currentClassDesc.getFieldsNoCopy();
				if (fields.length > 0) {
				    inputClassFields(currentObject, currentClass, fields, sender);
				}
                            }

                            if (currentClassDesc.hasWriteObject())
                                readObjectState.endUnmarshalCustomValue(this);

                        } finally {
                            setState(oldState);
                        }

    		    } else {

			// _REVISIT_ : Can we ever get here?
			/* No local class for this descriptor,
			 * Skip over the data for this class.
			 * like defaultReadObject with a null currentObject.
			 * The code will read the values but discard them.
			 */
			    ObjectStreamField[] fields =
				currentClassDesc.getFieldsNoCopy();
			    if (fields.length > 0) {
				inputClassFields(null, currentClass, fields, sender);
			    }
						
			}
					
		}
    	    } finally {
				// Make sure we exit at the same stack level as when we started.
		spClass = spBase;
    	    }
    	}
        } finally {
            // We've completed deserializing this object.  Any
            // future indirections will be handled correctly at the
            // CDR level.  The ActiveRecursionManager only deals with
            // objects currently being deserialized.
            activeRecursionMgr.removeObject(offset);
        }
		
    	return currentObject;
    
private java.lang.ObjectinputObjectField(org.omg.CORBA.ValueMember field, com.sun.org.omg.SendingContext.CodeBase sender)


        Object objectValue = null;
        Class type = null;
        String id = field.id;
							
        try {
            type = vhandler.getClassFromType(id);
        } catch(ClassNotFoundException cnfe) {
            // Make sure type = null
            type = null;
        }

        String signature = null;
        if (type != null)
            signature = ValueUtility.getSignature(field);
								
        if (signature != null && (signature.equals("Ljava/lang/Object;") ||
                                  signature.equals("Ljava/io/Serializable;") ||
                                  signature.equals("Ljava/io/Externalizable;"))) {
            objectValue = javax.rmi.CORBA.Util.readAny(orbStream);
        } else {
            // Decide what method call to make based on the type. If
            // it is a type for which we need to load a stub, convert
            // the type to the correct stub type.
            //
            // NOTE : Since FullValueDescription does not allow us
            // to ask whether something is an interface we do not
            // have the ability to optimize this check.
            
            int callType = ValueHandlerImpl.kValueType;
            
            if (!vhandler.isSequence(id)) {

                if (field.type.kind().value() == kRemoteTypeCode.kind().value()) {

                    // RMI Object reference...
                    callType = ValueHandlerImpl.kRemoteType;
                    
                } else {

                    // REVISIT.  If we don't have the local class,
                    // we should probably verify that it's an RMI type, 
                    // query the remote FVD, and use is_abstract.
                    // Our FVD seems to get NullPointerExceptions for any
                    // non-RMI types.

                    // This uses the local class in the same way as
                    // inputObjectField(ObjectStreamField) does.  REVISIT
                    // inputObjectField(ObjectStreamField)'s loadStubClass
                    // logic.  Assumption is that the given type cannot
                    // evolve to become a CORBA abstract interface or
                    // a RMI abstract interface.

                    if (type != null && type.isInterface() &&
                        (vhandler.isAbstractBase(type) ||
                         ObjectStreamClassCorbaExt.isAbstractInterface(type))) {
                
                        callType = ValueHandlerImpl.kAbstractType;
                    }
                }
            }
                
            // Now that we have used the FVD of the field to determine the proper course
            // of action, it is ok to use the type (Class) from this point forward since 
            // the rep. id for this read will also follow on the wire.

            switch (callType) {
                case ValueHandlerImpl.kRemoteType: 
                    if (type != null)
                        objectValue = Utility.readObjectAndNarrow(orbStream, type);
                    else
                        objectValue = orbStream.read_Object();
                    break;
                case ValueHandlerImpl.kAbstractType: 
                    if (type != null)
                        objectValue = Utility.readAbstractAndNarrow(orbStream, type);
                    else
                        objectValue = orbStream.read_abstract_interface();
                    break;
                case ValueHandlerImpl.kValueType:
                    if (type != null)
                        objectValue = orbStream.read_value(type);
                    else
                                            objectValue = orbStream.read_value();
                    break;
                default:
		    // XXX I18N, logging needed.
                    throw new StreamCorruptedException("Unknown callType: " + callType);
            }
        }

        return objectValue;
    
private java.lang.ObjectinputObjectField(ObjectStreamField field)
Factored out of inputClassFields and reused in inputCurrentClassFieldsForReadFields. Reads the field (which of an Object type as opposed to a primitive) described by ObjectStreamField field and returns it.


        if (ObjectStreamClassCorbaExt.isAny(field.getTypeString())) {
            return javax.rmi.CORBA.Util.readAny(orbStream);
        }

        Object objectValue = null;

        // fields have an API to provide the actual class
        // corresponding to the data type
        // Class type = osc.forClass();
        Class fieldType = field.getType();
	Class actualType = fieldType; // This may change if stub loaded.
				
        // Decide what method call to make based on the fieldType. If
        // it is a type for which we need to load a stub, convert
        // the type to the correct stub type.
        
        int callType = ValueHandlerImpl.kValueType;
        boolean narrow = false;
        
        if (fieldType.isInterface()) { 
            boolean loadStubClass = false;
            
            if (java.rmi.Remote.class.isAssignableFrom(fieldType)) {
                
                // RMI Object reference...
                callType = ValueHandlerImpl.kRemoteType;
                
            } else if (org.omg.CORBA.Object.class.isAssignableFrom(fieldType)){
                
                // IDL Object reference...
                callType = ValueHandlerImpl.kRemoteType;
                loadStubClass = true;
                
            } else if (vhandler.isAbstractBase(fieldType)) {
                // IDL Abstract Object reference...
                
                callType = ValueHandlerImpl.kAbstractType;
                loadStubClass = true;
            } else if (ObjectStreamClassCorbaExt.isAbstractInterface(fieldType)) {
                // RMI Abstract Object reference...
                
                callType = ValueHandlerImpl.kAbstractType;
            }
            
            if (loadStubClass) {
                try {
                    String codebase = Util.getCodebase(fieldType);
                    String repID = vhandler.createForAnyType(fieldType);
                    Class stubType =
			Utility.loadStubClass(repID, codebase, fieldType); 
		    actualType = stubType;
                } catch (ClassNotFoundException e) {
                    narrow = true;
                }
            } else {
                narrow = true;
            }
        }			

        switch (callType) {
            case ValueHandlerImpl.kRemoteType: 
                if (!narrow) 
                    objectValue = (Object)orbStream.read_Object(actualType);
                else
                    objectValue = Utility.readObjectAndNarrow(orbStream, actualType);
                break;
            case ValueHandlerImpl.kAbstractType: 
                if (!narrow)
                    objectValue = (Object)orbStream.read_abstract_interface(actualType); 
                else
                    objectValue = Utility.readAbstractAndNarrow(orbStream, actualType);
                break;
            case ValueHandlerImpl.kValueType:
                objectValue = (Object)orbStream.read_value(actualType);
                break;
            default:
		// XXX I18N, logging needed.
                throw new StreamCorruptedException("Unknown callType: " + callType);
        }

        return objectValue;
    
private java.lang.ObjectinputObjectUsingFVD(java.lang.Class clz, java.lang.String repositoryID, com.sun.org.omg.SendingContext.CodeBase sender, int offset)
This input method uses FullValueDescriptions retrieved from the sender's runtime to read in the data. This method is capable of throwing out data not applicable to client's fields. This method handles instances where the reader has a class not sent by the sender, the sender sent a class not present on the reader, and/or the reader's class does not match the sender's class. NOTE : If the local description indicates custom marshaling and the remote type's FVD also indicates custom marsahling than the local type is used to read the data off the wire. However, if either says custom while the other does not, a MARSHAL error is thrown. Externalizable is a form of custom marshaling.

	int spBase = spClass;	// current top of stack
	try{
			
	    /*
	     * Get the descriptor and then class of the incoming object.
	     */
			
	    ObjectStreamClass currdesc = currentClassDesc = ObjectStreamClass.lookup(clz);
	    Class currclass = currentClass = clz;
			
	    /* If Externalizable,
	     *  Create an instance and tell it to read its data.
	     * else,
	     *  Handle it as a serializable class.
	     */
	    if (currentClassDesc.isExternalizable()) {
		try {
		    currentObject = (currentClass == null) ?
			null : currentClassDesc.newInstance();
		    if (currentObject != null) {
                        // Store this object and its beginning position
                        // since there might be indirections to it while
                        // it's been unmarshalled.
                        activeRecursionMgr.addObject(offset, currentObject);

			// Read format version
			readFormatVersion();
						
			Externalizable ext = (Externalizable)currentObject;
			ext.readExternal(this);
		    }
		} catch (InvocationTargetException e) {
		    InvalidClassException exc = new InvalidClassException(
			currentClass.getName(), 
			"InvocationTargetException accessing no-arg constructor");
		    exc.initCause( e ) ;
		    throw exc ;
		} catch (UnsupportedOperationException e) {
		    InvalidClassException exc = new InvalidClassException(
			currentClass.getName(), 
			"UnsupportedOperationException accessing no-arg constructor");
		    exc.initCause( e ) ;
		    throw exc ;
		} catch (InstantiationException e) {
		    InvalidClassException exc = new InvalidClassException(
			currentClass.getName(), 
			"InstantiationException accessing no-arg constructor");
		    exc.initCause( e ) ;
		    throw exc ;
		}
	    } else {
		/*
		 * This is your basic diff pattern, made simpler
		 * because reordering is not allowed.
		 */
		for (currdesc = currentClassDesc, currclass = currentClass;
		     currdesc != null && currdesc.isSerializable();   /*sun.4296963 ibm.11861*/

		     currdesc = currdesc.getSuperclass()) {
					
		    /*
		     * Search the classes to see if the class of this
		     * descriptor appears further up the hierarchy. Until
		     * it's found assume its an inserted class.  If it's
		     * not found, its the descriptor's class that has been
		     * removed.
		     */
		    Class cc = currdesc.forClass();
		    Class cl;
		    for (cl = currclass; cl != null; cl = cl.getSuperclass()) {
			if (cc == cl) {
			    // found a superclass that matches this descriptor
			    break;
			} else {
			    /* Ignore a class that doesn't match.  No
			     * action is needed since it is already
			     * initialized.
			     */
			}
		    } // end : for (cl = currclass; cl != null; cl = cl.getSuperclass()) 
		    /* Test if there is room for this new entry.
		     * If not, double the size of the arrays and copy the contents.
		     */
		    spClass++;
		    if (spClass >= classes.length) {
			int newlen = classes.length * 2;
			Class[] newclasses = new Class[newlen];
			ObjectStreamClass[] newclassdesc = new ObjectStreamClass[newlen];
				
			System.arraycopy(classes, 0,
					 newclasses, 0,
					 classes.length);
			System.arraycopy(classdesc, 0,
					 newclassdesc, 0,
					 classes.length);
						
			classes = newclasses;
			classdesc = newclassdesc;
    		    }

		    if (cl == null) {
			/* Class not found corresponding to this descriptor.
			 * Pop off all the extra classes pushed.
			 * Push the descriptor and a null class.
			 */
			classdesc[spClass] = currdesc;
			classes[spClass] = null;
		    } else {
			/* Current class descriptor matches current class.
			 * Some classes may have been inserted.
			 * Record the match and advance the class, continue
			 * with the next descriptor.
			 */
			classdesc[spClass] = currdesc;
			classes[spClass] = cl;
			currclass = cl.getSuperclass();
		    }
		} // end : for (currdesc = currentClassDesc, currclass = currentClass;
				
		/* Allocate a new object.  
		 */
		try {
		    currentObject = (currentClass == null) ?
			null : currentClassDesc.newInstance();

                    // Store this object and its beginning position
                    // since there might be indirections to it while
                    // it's been unmarshalled.
                    activeRecursionMgr.addObject(offset, currentObject);
		} catch (InvocationTargetException e) {
		    InvalidClassException exc = new InvalidClassException(
			currentClass.getName(), 
			"InvocationTargetException accessing no-arg constructor");
		    exc.initCause( e ) ;
		    throw exc ;
		} catch (UnsupportedOperationException e) {
		    InvalidClassException exc = new InvalidClassException(
			currentClass.getName(), 
			"UnsupportedOperationException accessing no-arg constructor");
		    exc.initCause( e ) ;
		    throw exc ;
		} catch (InstantiationException e) {
		    InvalidClassException exc = new InvalidClassException(
			currentClass.getName(), 
			"InstantiationException accessing no-arg constructor");
		    exc.initCause( e ) ;
		    throw exc ;
		}
				
		Enumeration fvdsList = getOrderedDescriptions(repositoryID, sender).elements();
				
		while((fvdsList.hasMoreElements()) && (spClass > spBase)) {
		    FullValueDescription fvd = (FullValueDescription)fvdsList.nextElement();
	            // d4365188: backward compatability
		    String repIDForFVD = vhandler.getClassName(fvd.id);
		    String repIDForClass = vhandler.getClassName(vhandler.getRMIRepositoryID(currentClass));
					
		    while ((spClass > spBase) &&
			   (!repIDForFVD.equals(repIDForClass))) {
			int pos = findNextClass(repIDForFVD, classes, spClass, spBase);
			if (pos != -1) {
			    spClass = pos;
			    currclass = currentClass = classes[spClass];
			    repIDForClass = vhandler.getClassName(vhandler.getRMIRepositoryID(currentClass));
			}
			else { // Read and throw away one level of the fvdslist

                            // This seems to mean that the sender had a superclass that
                            // we don't have

			    if (fvd.is_custom) {

                                readFormatVersion();
                                boolean calledDefaultWriteObject = readBoolean();

                                if (calledDefaultWriteObject)
                                    inputClassFields(null, null, null, fvd.members, sender);

                                if (getStreamFormatVersion() == 2) {

                                    ((ValueInputStream)getOrbStream()).start_value();
                                    ((ValueInputStream)getOrbStream()).end_value();
                                }

                                // WARNING: If stream format version is 1 and there's
                                // optional data, we'll get some form of exception down
                                // the line or data corruption.

			    } else {

				inputClassFields(null, currentClass, null, fvd.members, sender);
			    }

			    if (fvdsList.hasMoreElements()){
				fvd = (FullValueDescription)fvdsList.nextElement();
				repIDForFVD = vhandler.getClassName(fvd.id);
			    }
			    else return currentObject;
			}
		    }

		    currdesc = currentClassDesc = ObjectStreamClass.lookup(currentClass);

		    if (!repIDForClass.equals("java.lang.Object")) {

                        // If the sender used custom marshaling, then it should have put
                        // the two bytes on the wire indicating stream format version
                        // and whether or not the writeObject method called 
                        // defaultWriteObject/writeFields.

                        ReadObjectState oldState = readObjectState;
                        setState(DEFAULT_STATE);

                        try {

                            if (fvd.is_custom) {

                                // Read format version
                                readFormatVersion();

                                // Read defaultWriteObject indicator
                                boolean calledDefaultWriteObject = readBoolean();

                                readObjectState.beginUnmarshalCustomValue(this,
                                                                          calledDefaultWriteObject,
                                                                          (currentClassDesc.readObjectMethod
                                                                           != null));
                            }

                            boolean usedReadObject = false;

                            // Always use readObject if it exists, and fall back to default
                            // unmarshaling if it doesn't.
                            try {

                                if (!fvd.is_custom && currentClassDesc.hasReadObject())
                                    setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED);

                                // See the definition of defaultReadObjectFVDMembers
                                // for more information.  This concerns making sure
                                // we use the remote FVD's members in defaultReadObject.
                                defaultReadObjectFVDMembers = fvd.members;
                                usedReadObject = invokeObjectReader(currentClassDesc,
                                                                    currentObject,
                                                                    currentClass);

                            } finally {
                                defaultReadObjectFVDMembers = null;
                            }

                            // Note that the !usedReadObject !calledDefaultWriteObject
                            // case is handled by the beginUnmarshalCustomValue method
                            // of the default state
                            if (!usedReadObject || readObjectState == IN_READ_OBJECT_DEFAULTS_SENT)
                                inputClassFields(currentObject, currentClass, currdesc, fvd.members, sender);

                            if (fvd.is_custom)
                                readObjectState.endUnmarshalCustomValue(this);

                        } finally {
                            setState(oldState);
                        }
                           
                        currclass = currentClass = classes[--spClass];

		    } else { 

			// The remaining hierarchy of the local class does not match the sender's FVD.
			// So, use remaining FVDs to read data off wire.  If any remaining FVDs indicate
			// custom marshaling, throw MARSHAL error.
			inputClassFields(null, currentClass, null, fvd.members, sender);
						
			while (fvdsList.hasMoreElements()){
			    fvd = (FullValueDescription)fvdsList.nextElement();

                            if (fvd.is_custom)
                                skipCustomUsingFVD(fvd.members, sender);
			    else
                                inputClassFields(null, currentClass, null, fvd.members, sender);
			}
						
		    }
					
		} // end : while(fvdsList.hasMoreElements()) 
		while (fvdsList.hasMoreElements()){

		    FullValueDescription fvd = (FullValueDescription)fvdsList.nextElement();
		    if (fvd.is_custom)
                        skipCustomUsingFVD(fvd.members, sender);
		    else 
                        throwAwayData(fvd.members, sender);			
		}
	    }
			
	    return currentObject;
	}
	finally {
    		// Make sure we exit at the same stack level as when we started.
    		spClass = spBase;

                // We've completed deserializing this object.  Any
                // future indirections will be handled correctly at the
                // CDR level.  The ActiveRecursionManager only deals with
                // objects currently being deserialized.
                activeRecursionMgr.removeObject(offset);
    	    }
		
    	
private voidinputPrimitiveField(java.lang.Object o, java.lang.Class cl, ObjectStreamField field)
Factored out of inputClassFields This reads a primitive value and sets it in the field of o described by the ObjectStreamField field. Note that reflection cannot be used here, because reflection cannot be used to set final fields.


        try {
            switch (field.getTypeCode()) {
                case 'B":
                    byte byteValue = orbStream.read_octet();
		    bridge.putByte( o, field.getFieldID(), byteValue ) ;
		    //reflective code: field.getField().setByte( o, byteValue ) ;
                    break;
                case 'Z":
                    boolean booleanValue = orbStream.read_boolean();
		    bridge.putBoolean( o, field.getFieldID(), booleanValue ) ;
		    //reflective code: field.getField().setBoolean( o, booleanValue ) ;
                    break;
		case 'C":
                    char charValue = orbStream.read_wchar();
		    bridge.putChar( o, field.getFieldID(), charValue ) ;
		    //reflective code: field.getField().setChar( o, charValue ) ;
                    break;
		case 'S":
                    short shortValue = orbStream.read_short();
		    bridge.putShort( o, field.getFieldID(), shortValue ) ;
		    //reflective code: field.getField().setShort( o, shortValue ) ;
                    break;
		case 'I":
                    int intValue = orbStream.read_long();
		    bridge.putInt( o, field.getFieldID(), intValue ) ;
		    //reflective code: field.getField().setInt( o, intValue ) ;
                    break;
		case 'J":
                    long longValue = orbStream.read_longlong();
		    bridge.putLong( o, field.getFieldID(), longValue ) ;
		    //reflective code: field.getField().setLong( o, longValue ) ;
                    break;
		case 'F" :
                    float floatValue = orbStream.read_float();
		    bridge.putFloat( o, field.getFieldID(), floatValue ) ;
		    //reflective code: field.getField().setFloat( o, floatValue ) ;
                    break;
		case 'D" :
                    double doubleValue = orbStream.read_double();
		    bridge.putDouble( o, field.getFieldID(), doubleValue ) ;
		    //reflective code: field.getField().setDouble( o, doubleValue ) ;
                    break;
		default:
		    // XXX I18N, logging needed.
                    throw new InvalidClassException(cl.getName());
            }
        } catch (IllegalArgumentException e) {
            /* This case should never happen. If the field types
               are not the same, InvalidClassException is raised when
               matching the local class to the serialized ObjectStreamClass. */
            ClassCastException cce = new ClassCastException("Assigning instance of class " +
                                         field.getType().getName() +
                                         " to field " +
                                         currentClassDesc.getName() + '#" +
                                         field.getField().getName());
	    cce.initCause( e ) ;
	    throw cce ;
	}
     
private final voidinputRemoteMembersForReadFields(java.util.Map fieldToValueMap)


        // Must have this local variable since defaultReadObjectFVDMembers
        // may get mangled by recursion.
        ValueMember fields[] = defaultReadObjectFVDMembers;

	try {

	    for (int i = 0; i < fields.length; i++) {

                switch (fields[i].type.kind().value()) {

                case TCKind._tk_octet:
                    byte byteValue = orbStream.read_octet();
                    fieldToValueMap.put(fields[i].name, new Byte(byteValue));
                    break;
                case TCKind._tk_boolean:
                    boolean booleanValue = orbStream.read_boolean();
                    fieldToValueMap.put(fields[i].name, new Boolean(booleanValue));
                    break;
                case TCKind._tk_char:
                    // Backwards compatibility.  Older Sun ORBs sent
                    // _tk_char even though they read and wrote wchars
                    // correctly.
                    //
                    // Fall through to the _tk_wchar case.
                case TCKind._tk_wchar:
                    char charValue = orbStream.read_wchar();
                    fieldToValueMap.put(fields[i].name, new Character(charValue));
                    break;
                case TCKind._tk_short:
                    short shortValue = orbStream.read_short();
                    fieldToValueMap.put(fields[i].name, new Short(shortValue));
                    break;
                case TCKind._tk_long:
                    int intValue = orbStream.read_long();
                    fieldToValueMap.put(fields[i].name, new Integer(intValue));
                    break;
                case TCKind._tk_longlong:
                    long longValue = orbStream.read_longlong();
                    fieldToValueMap.put(fields[i].name, new Long(longValue));
                    break;
                case TCKind._tk_float:
                    float floatValue = orbStream.read_float();
                    fieldToValueMap.put(fields[i].name, new Float(floatValue));
                    break;
                case TCKind._tk_double:
                    double doubleValue = orbStream.read_double();
                    fieldToValueMap.put(fields[i].name, new Double(doubleValue));
                    break;
                case TCKind._tk_value:
                case TCKind._tk_objref:
                case TCKind._tk_value_box:
                    Object objectValue = null;
                    try {
                        objectValue = inputObjectField(fields[i],
                                                       cbSender);

                    } catch (IndirectionException cdrie) {
                        // The CDR stream had never seen the given offset before,
                        // so check the recursion manager (it will throw an
                        // IOException if it doesn't have a reference, either).
                        objectValue = activeRecursionMgr.getObject(cdrie.offset);
                    }

                    fieldToValueMap.put(fields[i].name, objectValue);
                    break;
                default:
		    // XXX I18N, logging needed.
                    throw new StreamCorruptedException("Unknown kind: "
                                                       + fields[i].type.kind().value());
                }
            }
        } catch (Throwable t) {
            StreamCorruptedException result = new StreamCorruptedException(t.getMessage());
            result.initCause(t);
            throw result;
	}
    
protected java.lang.StringinternalReadUTF(org.omg.CORBA.portable.InputStream stream)
Helper method for correcting the Kestrel bug 4367783 (dealing with larger than 8-bit chars). The old behavior is preserved in orbutil.IIOPInputStream_1_3 in order to interoperate with our legacy ORBs.

        return stream.read_wstring();
    
private booleaninvokeObjectReader(com.sun.corba.se.impl.io.ObjectStreamClass osc, java.lang.Object obj, java.lang.Class aclass)

	if (osc.readObjectMethod == null) {
	    return false;
	}

	try {
	    osc.readObjectMethod.invoke( obj, readObjectArgList ) ;
	    return true;
	} catch (InvocationTargetException e) {
	    Throwable t = e.getTargetException();
	    if (t instanceof ClassNotFoundException)
		throw (ClassNotFoundException)t;
	    else if (t instanceof IOException)
		throw (IOException)t;
	    else if (t instanceof RuntimeException)
		throw (RuntimeException) t;
	    else if (t instanceof Error)
		throw (Error) t;
	    else
		// XXX I18N, logging needed.
		throw new Error("internal error");
	} catch (IllegalAccessException e) {
	    return false;
	}
    
public final voidmark(int readAheadLimit)

        orbStream.mark(readAheadLimit);
    
public final booleanmarkSupported()

        return orbStream.markSupported();
    
private final booleanmustUseRemoteValueMembers()

        return defaultReadObjectFVDMembers != null;
    
public final intread()

        try{
            readObjectState.readData(this);

            return (orbStream.read_octet() << 0) & 0x000000FF;
        } catch (MARSHAL marshalException) {
            if (marshalException.minor 
                == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) {
                setState(IN_READ_OBJECT_NO_MORE_OPT_DATA);
                return -1;
            }

            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e) ;
	    throw exc ;
	}
    
public final intread(byte[] data, int offset, int length)

        try{
            readObjectState.readData(this);

            orbStream.read_octet_array(data, offset, length);
            return length;
        } catch (MARSHAL marshalException) {
            if (marshalException.minor 
                == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) {
                setState(IN_READ_OBJECT_NO_MORE_OPT_DATA);
                return -1;
            }

            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e) ;
	    throw exc ;
	}

    
public final booleanreadBoolean()

        try{
            readObjectState.readData(this);

            return orbStream.read_boolean();
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;

        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
public final bytereadByte()

        try{
            readObjectState.readData(this);

            return orbStream.read_octet();
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;

        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
public final charreadChar()

        try{
            readObjectState.readData(this);

            return orbStream.read_wchar();
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;

        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
public final doublereadDouble()

        try{
            readObjectState.readData(this);

            return orbStream.read_double();
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
voidreadFields(java.util.Map fieldToValueMap)


        if (mustUseRemoteValueMembers()) {
            inputRemoteMembersForReadFields(fieldToValueMap);
        } else
            inputCurrentClassFieldsForReadFields(fieldToValueMap);
    
public final floatreadFloat()

        try{
            readObjectState.readData(this);

            return orbStream.read_float();
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
private voidreadFormatVersion()


        streamFormatVersion = orbStream.read_octet();

        if (streamFormatVersion < 1 || 
            streamFormatVersion > vhandler.getMaximumStreamFormatVersion()) {
	    SystemException sysex = omgWrapper.unsupportedFormatVersion(
		    CompletionStatus.COMPLETED_MAYBE);
	    // XXX I18N?  Logging for IOException?
	    IOException result = new IOException("Unsupported format version: "
                                                 + streamFormatVersion);
	    result.initCause( sysex ) ;
	    throw result ;
        }

        if (streamFormatVersion == 2) {
            if (!(orbStream instanceof ValueInputStream)) {
		SystemException sysex = omgWrapper.notAValueinputstream( 
		    CompletionStatus.COMPLETED_MAYBE);
		// XXX I18N?  Logging for IOException?
		IOException result = new IOException("Not a ValueInputStream");
		result.initCause( sysex ) ;
		throw result;
            }
        }
    
public final voidreadFully(byte[] data)

// d11623 : implement readFully, required for serializing some core classes

        readFully(data, 0, data.length);
    
public final voidreadFully(byte[] data, int offset, int size)

// d11623 : implement readFully, required for serializing some core classes
        try{
            readObjectState.readData(this);

            orbStream.read_octet_array(data, offset, size);
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            
            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
public final intreadInt()

        try{
            readObjectState.readData(this);

            return orbStream.read_long();
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
public final java.lang.StringreadLine()

	// XXX I18N, logging needed.
        throw new IOException("Method readLine not supported");
    
public final longreadLong()

        try{
            readObjectState.readData(this);

            return orbStream.read_longlong();
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
public final java.lang.ObjectreadObjectDelegate()
Override the actions of the final method "readObject()" in ObjectInputStream.

since
JDK1.1.6 Read an object from the ObjectInputStream. The class of the object, the signature of the class, and the values of the non-transient and non-static fields of the class and all of its supertypes are read. Default deserializing for a class can be overriden using the writeObject and readObject methods. Objects referenced by this object are read transitively so that a complete equivalent graph of objects is reconstructed by readObject.

The root object is completly restored when all of its fields and the objects it references are completely restored. At this point the object validation callbacks are executed in order based on their registered priorities. The callbacks are registered by objects (in the readObject special methods) as they are individually restored. Exceptions are thrown for problems with the InputStream and for classes that should not be deserialized. All exceptions are fatal to the InputStream and leave it in an indeterminate state; it is up to the caller to ignore or recover the stream state.

exception
java.lang.ClassNotFoundException Class of a serialized object cannot be found.
exception
InvalidClassException Something is wrong with a class used by serialization.
exception
StreamCorruptedException Control information in the stream is inconsistent.
exception
OptionalDataException Primitive data was found in the stream instead of objects.
exception
IOException Any of the usual Input/Output related exceptions.
since
JDK1.1

	try {

            readObjectState.readData(this);

            return orbStream.read_abstract_interface();
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, true);
            throw marshalException;
	} catch(IndirectionException cdrie)
	    {
                // The CDR stream had never seen the given offset before,
                // so check the recursion manager (it will throw an
                // IOException if it doesn't have a reference, either).
                return activeRecursionMgr.getObject(cdrie.offset);
	    }
    
protected final java.lang.ObjectreadObjectOverride()
This method is called by trusted subclasses of ObjectOutputStream that constructed ObjectOutputStream using the protected no-arg constructor. The subclass is expected to provide an override method with the modifier "final".

return
the Object read from the stream.
see
#ObjectInputStream()
see
#readObject
since
JDK 1.2

        return readObjectDelegate();
    
public final shortreadShort()

        try{
            readObjectState.readData(this);

            return orbStream.read_short();
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
protected final voidreadStreamHeader()

        // no op
    
public final java.lang.StringreadUTF()

        try{
            readObjectState.readData(this);

            return internalReadUTF(orbStream);
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
public final intreadUnsignedByte()

        try{
            readObjectState.readData(this);

    	    return (orbStream.read_octet() << 0) & 0x000000FF;
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;
	} catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
public final intreadUnsignedShort()

        try{
            readObjectState.readData(this);

    	    return (orbStream.read_ushort() << 0) & 0x0000FFFF;
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            throw marshalException;
        } catch(Error e) {
	    IOException exc = new IOException(e.getMessage());
	    exc.initCause(e);
	    throw exc ;
	}
    
public final synchronized voidregisterValidation(java.io.ObjectInputValidation obj, int prio)

	// XXX I18N, logging needed.
        throw new Error("Method registerValidation not supported");
    
public final voidreset()

        try {
            orbStream.reset();
        } catch (Error e) {
            IOException err = new IOException(e.getMessage());
	    err.initCause(e) ;
	    throw err ;
        }
    
private voidresetStream()


	if (classes == null)
	    classes = new Class[20];
	else {
	    for (int i = 0; i < classes.length; i++)
		classes[i] = null;
	}
	if (classdesc == null)
	    classdesc = new ObjectStreamClass[20];
	else {
	    for (int i = 0; i < classdesc.length; i++)
		classdesc[i] = null;
	}
	spClass = 0;

	if (callbacks != null)
	    callbacks.setSize(0);	// discard any pending callbacks
    
protected final java.lang.ClassresolveClass(com.sun.corba.se.impl.io.ObjectStreamClass v)

	// XXX I18N, logging needed.
        throw new IOException("Method resolveClass not supported");
    
protected final java.lang.ObjectresolveObject(java.lang.Object obj)

	// XXX I18N, logging needed.
        throw new IOException("Method resolveObject not supported");
    
private static voidsetBooleanField(java.lang.Object o, java.lang.Class c, java.lang.String fieldName, boolean v)

	try {
	    Field fld = c.getDeclaredField( fieldName ) ;
	    long key = bridge.objectFieldOffset( fld ) ;
	    bridge.putBoolean( o, key, v ) ;
	} catch (Exception e) {
	    throw utilWrapper.errorSetBooleanField( e, fieldName, 
		ObjectUtility.compactObjectToString( o ),
		new Boolean(v) ) ;
	}
    
private static voidsetByteField(java.lang.Object o, java.lang.Class c, java.lang.String fieldName, byte v)

	try {
	    Field fld = c.getDeclaredField( fieldName ) ;
	    long key = bridge.objectFieldOffset( fld ) ;
	    bridge.putByte( o, key, v ) ;
	} catch (Exception e) {
	    throw utilWrapper.errorSetByteField( e, fieldName, 
		ObjectUtility.compactObjectToString( o ),
		new Byte(v) ) ;
	}
    
private static voidsetCharField(java.lang.Object o, java.lang.Class c, java.lang.String fieldName, char v)

	try {
	    Field fld = c.getDeclaredField( fieldName ) ;
	    long key = bridge.objectFieldOffset( fld ) ;
	    bridge.putChar( o, key, v ) ;
	} catch (Exception e) {
	    throw utilWrapper.errorSetCharField( e, fieldName, 
		ObjectUtility.compactObjectToString( o ),
		new Character(v) ) ;
	}
    
private static voidsetDoubleField(java.lang.Object o, java.lang.Class c, java.lang.String fieldName, double v)

	try {
	    Field fld = c.getDeclaredField( fieldName ) ;
	    long key = bridge.objectFieldOffset( fld ) ;
	    bridge.putDouble( o, key, v ) ;
	} catch (Exception e) {
	    throw utilWrapper.errorSetDoubleField( e, fieldName, 
		ObjectUtility.compactObjectToString( o ),
		new Double(v) ) ;
	}
    
private static voidsetFloatField(java.lang.Object o, java.lang.Class c, java.lang.String fieldName, float v)

	try {
	    Field fld = c.getDeclaredField( fieldName ) ;
	    long key = bridge.objectFieldOffset( fld ) ;
	    bridge.putFloat( o, key, v ) ;
	} catch (Exception e) {
	    throw utilWrapper.errorSetFloatField( e, fieldName, 
		ObjectUtility.compactObjectToString( o ),
		new Float(v) ) ;
	}
    
private static voidsetIntField(java.lang.Object o, java.lang.Class c, java.lang.String fieldName, int v)

	try {
	    Field fld = c.getDeclaredField( fieldName ) ;
	    long key = bridge.objectFieldOffset( fld ) ;
	    bridge.putInt( o, key, v ) ;
	} catch (Exception e) {
	    throw utilWrapper.errorSetIntField( e, fieldName, 
		ObjectUtility.compactObjectToString( o ),
		new Integer(v) ) ;
	}
    
private static voidsetLongField(java.lang.Object o, java.lang.Class c, java.lang.String fieldName, long v)

	try {
	    Field fld = c.getDeclaredField( fieldName ) ;
	    long key = bridge.objectFieldOffset( fld ) ;
	    bridge.putLong( o, key, v ) ;
	} catch (Exception e) {
	    throw utilWrapper.errorSetLongField( e, fieldName, 
		ObjectUtility.compactObjectToString( o ),
		new Long(v) ) ;
	}
    
private static voidsetObjectField(java.lang.Object o, java.lang.Class c, java.lang.String fieldName, java.lang.Object v)

	try {
	    Field fld = c.getDeclaredField( fieldName ) ;
	    long key = bridge.objectFieldOffset( fld ) ;
	    bridge.putObject( o, key, v ) ;
	} catch (Exception e) {
	    throw utilWrapper.errorSetObjectField( e, fieldName, 
		ObjectUtility.compactObjectToString( o ),
		ObjectUtility.compactObjectToString( v )) ;
	}
    
public final voidsetOrbStream(org.omg.CORBA_2_3.portable.InputStream os)

    	orbStream = os;
    
public final voidsetSender(com.sun.org.omg.SendingContext.CodeBase cb)

        cbSender = cb;
    
private static voidsetShortField(java.lang.Object o, java.lang.Class c, java.lang.String fieldName, short v)

	try {
	    Field fld = c.getDeclaredField( fieldName ) ;
	    long key = bridge.objectFieldOffset( fld ) ;
	    bridge.putShort( o, key, v ) ;
	} catch (Exception e) {
	    throw utilWrapper.errorSetShortField( e, fieldName, 
		ObjectUtility.compactObjectToString( o ),
		new Short(v) ) ;
	}
    
public static voidsetTestFVDFlag(boolean val)

	//  useFVDOnly = val;
    
public final voidsetValueHandler(javax.rmi.CORBA.ValueHandler vh)

        vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh;
    
final java.lang.ObjectsimpleReadObject(java.lang.Class clz, java.lang.String repositoryID, com.sun.org.omg.SendingContext.CodeBase sender, int offset)


    	/* Save the current state and get ready to read an object. */
    	Object prevObject = currentObject;
    	ObjectStreamClass prevClassDesc = currentClassDesc;
        Class prevClass = currentClass;
        byte oldStreamFormatVersion = streamFormatVersion;

    	simpleReadDepth++;	// Entering
    	Object obj = null;

    	/*
    	 * Check for reset, handle it before reading an object.
    	 */
    	try {
	    // d4365188: backward compatability
	    if (vhandler.useFullValueDescription(clz, repositoryID)) {
		obj = inputObjectUsingFVD(clz, repositoryID, sender, offset);
	    } else {
                obj = inputObject(clz, repositoryID, sender, offset);
	    }

	    obj = currentClassDesc.readResolve(obj);
    	}
    	catch(ClassNotFoundException cnfe)
	    {
		bridge.throwException( cnfe ) ;
		return null;
	    }
    	catch(IOException ioe)
	    {
		// System.out.println("CLZ = " + clz + "; " + ioe.toString());
		bridge.throwException(ioe) ;
		return null;
	    }
    	finally {
    	    simpleReadDepth --;
    	    currentObject = prevObject;
    	    currentClassDesc = prevClassDesc;
            currentClass = prevClass;
            streamFormatVersion = oldStreamFormatVersion;
    	}


    	/* Check for thrown exceptions and re-throw them, clearing them if
    	 * this is the last recursive call .
    	 */
    	IOException exIOE = abortIOException;
    	if (simpleReadDepth == 0)
    	    abortIOException = null;
    	if (exIOE != null){
	    bridge.throwException( exIOE ) ;
            return null;
    	}


    	ClassNotFoundException exCNF = abortClassNotFoundException;
    	if (simpleReadDepth == 0)
    	    abortClassNotFoundException = null;
    	if (exCNF != null) {
	    bridge.throwException( exCNF ) ;
            return null;
    	}

    	return obj;
    
public final voidsimpleSkipObject(java.lang.String repositoryID, com.sun.org.omg.SendingContext.CodeBase sender)

				
    	/* Save the current state and get ready to read an object. */
    	Object prevObject = currentObject;
    	ObjectStreamClass prevClassDesc = currentClassDesc;
        Class prevClass = currentClass;
        byte oldStreamFormatVersion = streamFormatVersion;

    	simpleReadDepth++;	// Entering
    	Object obj = null;

    	/*
    	 * Check for reset, handle it before reading an object.
    	 */
    	try {
	    skipObjectUsingFVD(repositoryID, sender);
    	}
    	catch(ClassNotFoundException cnfe)
	    {
		bridge.throwException( cnfe ) ;
		return;
	    }
    	catch(IOException ioe)
	    {
		bridge.throwException( ioe ) ;
		return;
	    }
    	finally {
    	    simpleReadDepth --;
            streamFormatVersion = oldStreamFormatVersion;
    	    currentObject = prevObject;
    	    currentClassDesc = prevClassDesc;
            currentClass = prevClass;
    	}


    	/* Check for thrown exceptions and re-throw them, clearing them if
    	 * this is the last recursive call .
    	 */
    	IOException exIOE = abortIOException;
    	if (simpleReadDepth == 0)
    	    abortIOException = null;
    	if (exIOE != null){
	    bridge.throwException( exIOE ) ;
            return;
    	}


    	ClassNotFoundException exCNF = abortClassNotFoundException;
    	if (simpleReadDepth == 0)
    	    abortClassNotFoundException = null;
    	if (exCNF != null) {
	    bridge.throwException( exCNF ) ;
            return;
    	}

	return;
    
public final intskipBytes(int len)

        try{
            readObjectState.readData(this);

            byte buf[] = new byte[len];
            orbStream.read_octet_array(buf, 0, len);
            return len;
        } catch (MARSHAL marshalException) {
            handleOptionalDataMarshalException(marshalException, false);
            
            throw marshalException;
        } catch(Error e) {
            IOException exc = new IOException(e.getMessage());
	    exc.initCause(e) ;
	    throw exc ;
        }
    
private voidskipCustomUsingFVD(org.omg.CORBA.ValueMember[] fields, com.sun.org.omg.SendingContext.CodeBase sender)

        readFormatVersion();
        boolean calledDefaultWriteObject = readBoolean();

        if (calledDefaultWriteObject)
            throwAwayData(fields, sender);

        if (getStreamFormatVersion() == 2) {
            
            ((ValueInputStream)getOrbStream()).start_value();
            ((ValueInputStream)getOrbStream()).end_value();
        }
    
private java.lang.ObjectskipObjectUsingFVD(java.lang.String repositoryID, com.sun.org.omg.SendingContext.CodeBase sender)
This input method uses FullValueDescriptions retrieved from the sender's runtime to read in the data. This method is capable of throwing out data not applicable to client's fields. NOTE : If the local description indicates custom marshaling and the remote type's FVD also indicates custom marsahling than the local type is used to read the data off the wire. However, if either says custom while the other does not, a MARSHAL error is thrown. Externalizable is a form of custom marshaling.


	Enumeration fvdsList = getOrderedDescriptions(repositoryID, sender).elements();
		
	while(fvdsList.hasMoreElements()) {
	    FullValueDescription fvd = (FullValueDescription)fvdsList.nextElement();
	    String repIDForFVD = vhandler.getClassName(fvd.id);
			
	    if (!repIDForFVD.equals("java.lang.Object")) {
		if (fvd.is_custom) {

                    readFormatVersion();
                        
                    boolean calledDefaultWriteObject = readBoolean();
                        
                    if (calledDefaultWriteObject)
                        inputClassFields(null, null, null, fvd.members, sender);

                    if (getStreamFormatVersion() == 2) {

                        ((ValueInputStream)getOrbStream()).start_value();
                        ((ValueInputStream)getOrbStream()).end_value();
                    }

                    // WARNING: If stream format version is 1 and there's
                    // optional data, we'll get some form of exception down
                    // the line.

		} else { 
		    // Use default marshaling
		    inputClassFields(null, null, null, fvd.members, sender);
		}
	    }

	} // end : while(fvdsList.hasMoreElements()) 
	return null;
		
    
private voidthrowAwayData(org.omg.CORBA.ValueMember[] fields, com.sun.org.omg.SendingContext.CodeBase sender)

	for (int i = 0; i < fields.length; ++i) {
	
	    try {
					
		switch (fields[i].type.kind().value()) {
		case TCKind._tk_octet:
		    orbStream.read_octet();
		    break;
		case TCKind._tk_boolean:
		    orbStream.read_boolean();
		    break;
		case TCKind._tk_char:
                    // Backwards compatibility.  Older Sun ORBs sent
                    // _tk_char even though they read and wrote wchars
                    // correctly.
                    //
                    // Fall through to the _tk_wchar case.
                case TCKind._tk_wchar:
		    orbStream.read_wchar();
		    break;
		case TCKind._tk_short:
		    orbStream.read_short();
		    break;
		case TCKind._tk_long:
		    orbStream.read_long();
		    break;
		case TCKind._tk_longlong:
		    orbStream.read_longlong();
		    break;
		case TCKind._tk_float:
		    orbStream.read_float();
		    break;
		case TCKind._tk_double:
		    orbStream.read_double();
		    break;
                case TCKind._tk_value:
		case TCKind._tk_objref:
		case TCKind._tk_value_box:
		    Class type = null;
	            String id = fields[i].id;

		    try {
			type = vhandler.getClassFromType(id);
		    }
		    catch(ClassNotFoundException cnfe){
			// Make sure type = null
			type = null;
		    }
		    String signature = null;
		    if (type != null)
			signature = ValueUtility.getSignature(fields[i]);
								
		    // Read value
		    try {
			if ((signature != null) && ( signature.equals("Ljava/lang/Object;") ||
						     signature.equals("Ljava/io/Serializable;") ||
						     signature.equals("Ljava/io/Externalizable;")) ) {
			    javax.rmi.CORBA.Util.readAny(orbStream);
			}
			else {
			    // Decide what method call to make based on the type.
			    //
			    // NOTE : Since FullValueDescription does not allow us
			    // to ask whether something is an interface we do not
			    // have the ability to optimize this check.
										
			    int callType = ValueHandlerImpl.kValueType;

			    if (!vhandler.isSequence(id)) {
				FullValueDescription fieldFVD = sender.meta(fields[i].id);
				if (kRemoteTypeCode == fields[i].type) {

				    // RMI Object reference...
				    callType = ValueHandlerImpl.kRemoteType;
				} else if (fieldFVD.is_abstract) {
				    // RMI Abstract Object reference...

				    callType = ValueHandlerImpl.kAbstractType;
				}
			    }
										
			    // Now that we have used the FVD of the field to determine the proper course
			    // of action, it is ok to use the type (Class) from this point forward since 
			    // the rep. id for this read will also follow on the wire.

			    switch (callType) {
			    case ValueHandlerImpl.kRemoteType: 
				orbStream.read_Object();
				break;
			    case ValueHandlerImpl.kAbstractType: 
				orbStream.read_abstract_interface(); 
				break;
			    case ValueHandlerImpl.kValueType:
				if (type != null) {
				    orbStream.read_value(type);
				} else {
				    orbStream.read_value();
				}
				break;
                            default:
				// XXX I18N, logging needed.
                                throw new StreamCorruptedException("Unknown callType: "
                                                                   + callType);
			    }
			}
										
		    }
		    catch(IndirectionException cdrie) {
			// Since we are throwing this away, don't bother handling recursion.
			continue;
		    }
									
		    break;
                default:
		    // XXX I18N, logging needed.
                    throw new StreamCorruptedException("Unknown kind: "
                                                       + fields[i].type.kind().value());

		}
	    } catch (IllegalArgumentException e) {
		/* This case should never happen. If the field types
		   are not the same, InvalidClassException is raised when
		   matching the local class to the serialized ObjectStreamClass. */
		// XXX I18N, logging needed.
		ClassCastException cce = new ClassCastException("Assigning instance of class " + 
		    fields[i].id + " to field " + currentClassDesc.getName() + 
		    '#" + fields[i].name);
		cce.initCause(e) ;
		throw cce ;
	    }
	}