151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.io; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.ObjectStreamClass.WeakClassKey; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.ref.ReferenceQueue; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.reflect.Array; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.reflect.Modifier; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.reflect.Proxy; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessControlContext; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessController; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedAction; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedActionException; 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedExceptionAction; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Arrays; 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.HashMap; 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.concurrent.ConcurrentHashMap; 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.concurrent.ConcurrentMap; 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.concurrent.atomic.AtomicBoolean; 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport static java.io.ObjectStreamClass.processQueue; 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.reflect.misc.ReflectUtil; 468d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebskiimport dalvik.system.VMStack; 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * An ObjectInputStream deserializes primitive data and objects previously 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * written using an ObjectOutputStream. 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>ObjectOutputStream and ObjectInputStream can provide an application with 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * persistent storage for graphs of objects when used with a FileOutputStream 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and FileInputStream respectively. ObjectInputStream is used to recover 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * those objects previously serialized. Other uses include passing objects 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * between hosts using a socket stream or for marshaling and unmarshaling 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * arguments and parameters in a remote communication system. 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>ObjectInputStream ensures that the types of all objects in the graph 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * created from the stream match the classes present in the Java Virtual 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Machine. Classes are loaded as required using the standard mechanisms. 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Only objects that support the java.io.Serializable or 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.io.Externalizable interface can be read from streams. 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The method <code>readObject</code> is used to read an object from the 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream. Java's safe casting should be used to get the desired type. In 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Java, strings and arrays are objects and are treated as objects during 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * serialization. When read they need to be cast to the expected type. 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Primitive data types can be read from the stream using the appropriate 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method on DataInput. 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The default deserialization mechanism for objects restores the contents 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of each field to the value and type it had when it was written. Fields 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * declared as transient or static are ignored by the deserialization process. 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * References to other objects cause those objects to be read from the stream 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as necessary. Graphs of objects are restored correctly using a reference 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * sharing mechanism. New objects are always allocated when deserializing, 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * which prevents existing objects from being overwritten. 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Reading an object is analogous to running the constructors of a new 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object. Memory is allocated for the object and initialized to zero (NULL). 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * No-arg constructors are invoked for the non-serializable classes and then 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the fields of the serializable classes are restored from the stream starting 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with the serializable class closest to java.lang.object and finishing with 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the object's most specific class. 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>For example to read from a stream as written by the example in 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ObjectOutputStream: 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <br> 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FileInputStream fis = new FileInputStream("t.tmp"); 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ObjectInputStream ois = new ObjectInputStream(fis); 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * int i = ois.readInt(); 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * String today = (String) ois.readObject(); 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Date date = (Date) ois.readObject(); 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ois.close(); 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Classes control how they are serialized by implementing either the 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.io.Serializable or java.io.Externalizable interfaces. 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Implementing the Serializable interface allows object serialization to 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * save and restore the entire state of the object and it allows classes to 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * evolve between the time the stream is written and the time it is read. It 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * automatically traverses references between objects, saving and restoring 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * entire graphs. 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Serializable classes that require special handling during the 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * serialization and deserialization process should implement the following 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * methods:<p> 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * private void writeObject(java.io.ObjectOutputStream stream) 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * throws IOException; 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * private void readObject(java.io.ObjectInputStream stream) 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * throws IOException, ClassNotFoundException; 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * private void readObjectNoData() 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * throws ObjectStreamException; 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The readObject method is responsible for reading and restoring the state 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the object for its particular class using data written to the stream by 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the corresponding writeObject method. The method does not need to concern 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * itself with the state belonging to its superclasses or subclasses. State is 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * restored by reading data from the ObjectInputStream for the individual 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * fields and making assignments to the appropriate fields of the object. 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reading primitive data types is supported by DataInput. 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Any attempt to read object data which exceeds the boundaries of the 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * custom data written by the corresponding writeObject method will cause an 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * OptionalDataException to be thrown with an eof field value of true. 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Non-object reads which exceed the end of the allotted data will reflect the 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * end of data in the same way that they would indicate the end of the stream: 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * bytewise reads will return -1 as the byte read or number of bytes read, and 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * primitive reads will throw EOFExceptions. If there is no corresponding 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * writeObject method, then the end of default serialized data marks the end of 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the allotted data. 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Primitive and object read calls issued from within a readExternal method 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * behave in the same manner--if the stream is already positioned at the end of 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * data written by the corresponding writeExternal method, object reads will 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * throw OptionalDataExceptions with eof set to true, bytewise reads will 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * return -1, and primitive reads will throw EOFExceptions. Note that this 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * behavior does not hold for streams written with the old 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>ObjectStreamConstants.PROTOCOL_VERSION_1</code> protocol, in which the 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * end of data written by writeExternal methods is not demarcated, and hence 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * cannot be detected. 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The readObjectNoData method is responsible for initializing the state of 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the object for its particular class in the event that the serialization 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream does not list the given class as a superclass of the object being 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * deserialized. This may occur in cases where the receiving party uses a 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * different version of the deserialized instance's class than the sending 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * party, and the receiver's version extends classes that are not extended by 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the sender's version. This may also occur if the serialization stream has 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * been tampered; hence, readObjectNoData is useful for initializing 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * deserialized objects properly despite a "hostile" or incomplete source 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream. 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Serialization does not read or assign values to the fields of any object 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that does not implement the java.io.Serializable interface. Subclasses of 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Objects that are not serializable can be serializable. In this case the 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * non-serializable class must have a no-arg constructor to allow its fields to 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be initialized. In this case it is the responsibility of the subclass to 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * save and restore the state of the non-serializable class. It is frequently 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the case that the fields of that class are accessible (public, package, or 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * protected) or that there are get and set methods that can be used to restore 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the state. 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Any exception that occurs while deserializing an object will be caught by 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the ObjectInputStream and abort the reading process. 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Implementing the Externalizable interface allows the object to assume 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * complete control over the contents and format of the object's serialized 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * form. The methods of the Externalizable interface, writeExternal and 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * readExternal, are called to save and restore the objects state. When 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * implemented by a class they can write and read their own state using all of 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the methods of ObjectOutput and ObjectInput. It is the responsibility of 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the objects to handle any versioning that occurs. 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Enum constants are deserialized differently than ordinary serializable or 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * externalizable objects. The serialized form of an enum constant consists 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * solely of its name; field values of the constant are not transmitted. To 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * deserialize an enum constant, ObjectInputStream reads the constant name from 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the stream; the deserialized constant is then obtained by calling the static 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method <code>Enum.valueOf(Class, String)</code> with the enum constant's 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * base type and the received constant name as arguments. Like other 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * serializable or externalizable objects, enum constants can function as the 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * targets of back references appearing subsequently in the serialization 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream. The process by which enum constants are deserialized cannot be 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * customized: any class-specific readObject, readObjectNoData, and readResolve 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * methods defined by enum types are ignored during deserialization. 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Similarly, any serialPersistentFields or serialVersionUID field declarations 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are also ignored--all enum types have a fixed serialVersionUID of 0L. 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Mike Warres 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Roger Riggs 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.DataInput 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.ObjectOutputStream 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.Serializable 205d2449bb576ad1e3a3877364e5e1ae28625f69e35Yi Kong * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/input.html"> Object Serialization Specification, Section 3, Object Input Classes</a> 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.1 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class ObjectInputStream 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extends InputStream implements ObjectInput, ObjectStreamConstants 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 2118d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebski 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** handle value representing null */ 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int NULL_HANDLE = -1; 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** marker for unshared objects in internal handle table */ 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final Object unsharedMarker = new Object(); 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** table mapping primitive type names to corresponding class objects */ 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final HashMap<String, Class<?>> primClasses 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski = new HashMap<>(8, 1.0F); 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primClasses.put("boolean", boolean.class); 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primClasses.put("byte", byte.class); 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primClasses.put("char", char.class); 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primClasses.put("short", short.class); 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primClasses.put("int", int.class); 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primClasses.put("long", long.class); 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primClasses.put("float", float.class); 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primClasses.put("double", double.class); 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primClasses.put("void", void.class); 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class Caches { 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** cache of subclass security audit results */ 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits = 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new ConcurrentHashMap<>(); 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** queue for WeakReferences to audited subclasses */ 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final ReferenceQueue<Class<?>> subclassAuditsQueue = 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new ReferenceQueue<>(); 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** filter stream for handling block data conversion */ 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final BlockDataInputStream bin; 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** validation callback list */ 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final ValidationList vlist; 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** recursion depth */ 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int depth; 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** whether stream is closed */ 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean closed; 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** wire handle -> obj/exception map */ 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final HandleTable handles; 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** scratch field for passing handle values up/down call stack */ 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int passHandle = NULL_HANDLE; 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** flag set when at end of field value block with no TC_ENDBLOCKDATA */ 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean defaultDataEnd = false; 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** buffer for reading primitive field values */ 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] primVals; 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** if true, invoke readObjectOverride() instead of readObject() */ 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final boolean enableOverride; 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** if true, invoke resolveObject() */ 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean enableResolve; 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Context during upcalls to class-defined readObject methods; holds 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object currently being deserialized and descriptor for current class. 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Null when not during readObject upcall. 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private SerialCallbackContext curContext; 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates an ObjectInputStream that reads from the specified InputStream. 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A serialization stream header is read from the stream and verified. 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This constructor will block until the corresponding ObjectOutputStream 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * has written and flushed the header. 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If a security manager is installed, this constructor will check for 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the "enableSubclassImplementation" SerializablePermission when invoked 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * directly or indirectly by the constructor of a subclass which overrides 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the ObjectInputStream.readFields or ObjectInputStream.readUnshared 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * methods. 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in input stream to read from 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws StreamCorruptedException if the stream header is incorrect 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error occurs while reading stream header 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if untrusted subclass illegally overrides 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * security-sensitive methods 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if <code>in</code> is <code>null</code> 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see ObjectInputStream#ObjectInputStream() 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see ObjectInputStream#readFields() 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see ObjectOutputStream#ObjectOutputStream(OutputStream) 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ObjectInputStream(InputStream in) throws IOException { 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verifySubclass(); 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin = new BlockDataInputStream(in); 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles = new HandleTable(10); 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vlist = new ValidationList(); 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski enableOverride = false; 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readStreamHeader(); 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(true); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Provide a way for subclasses that are completely reimplementing 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ObjectInputStream to not have to allocate private data just used by this 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * implementation of ObjectInputStream. 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If there is a security manager installed, this method first calls the 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * security manager's <code>checkPermission</code> method with the 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SerializablePermission("enableSubclassImplementation")</code> 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * permission to ensure it's ok to enable subclassing. 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if a security manager exists and its 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkPermission</code> method denies enabling 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * subclassing. 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkPermission 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.SerializablePermission 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected ObjectInputStream() throws IOException, SecurityException { 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) { 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin = null; 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles = null; 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vlist = null; 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski enableOverride = true; 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Read an object from the ObjectInputStream. The class of the object, the 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * signature of the class, and the values of the non-transient and 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * non-static fields of the class and all of its supertypes are read. 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Default deserializing for a class can be overriden using the writeObject 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and readObject methods. Objects referenced by this object are read 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * transitively so that a complete equivalent graph of objects is 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * reconstructed by readObject. 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The root object is completely restored when all of its fields and the 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * objects it references are completely restored. At this point the object 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * validation callbacks are executed in order based on their registered 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * priorities. The callbacks are registered by objects (in the readObject 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * special methods) as they are individually restored. 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Exceptions are thrown for problems with the InputStream and for 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * classes that should not be deserialized. All exceptions are fatal to 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the InputStream and leave it in an indeterminate state; it is up to the 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * caller to ignore or recover the stream state. 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ClassNotFoundException Class of a serialized object cannot be 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * found. 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws InvalidClassException Something is wrong with a class used by 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * serialization. 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws StreamCorruptedException Control information in the 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream is inconsistent. 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws OptionalDataException Primitive data was found in the 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream instead of objects. 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException Any of the usual Input/Output related exceptions. 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final Object readObject() 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, ClassNotFoundException 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (enableOverride) { 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readObjectOverride(); 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if nested read, passHandle contains handle of enclosing object 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int outerHandle = passHandle; 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object obj = readObject0(false); 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markDependency(outerHandle, passHandle); 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException ex = handles.lookupException(passHandle); 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ex != null) { 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ex; 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (depth == 0) { 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vlist.doCallbacks(); 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return obj; 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = outerHandle; 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (closed && depth == 0) { 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski clear(); 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method is called by trusted subclasses of ObjectOutputStream that 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * constructed ObjectOutputStream using the protected no-arg constructor. 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The subclass is expected to provide an override method with the modifier 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "final". 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the Object read from the stream. 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ClassNotFoundException Class definition of a serialized object 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * cannot be found. 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws OptionalDataException Primitive data was found in the stream 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * instead of objects. 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if I/O errors occurred while reading from the 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying stream 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #ObjectInputStream() 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #readObject() 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.2 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected Object readObjectOverride() 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, ClassNotFoundException 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads an "unshared" object from the ObjectInputStream. This method is 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * identical to readObject, except that it prevents subsequent calls to 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * readObject and readUnshared from returning additional references to the 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * deserialized instance obtained via this call. Specifically: 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <ul> 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>If readUnshared is called to deserialize a back-reference (the 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream representation of an object which has been written 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * previously to the stream), an ObjectStreamException will be 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * thrown. 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>If readUnshared returns successfully, then any subsequent attempts 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to deserialize back-references to the stream handle deserialized 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by readUnshared will cause an ObjectStreamException to be thrown. 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </ul> 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Deserializing an object via readUnshared invalidates the stream handle 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * associated with the returned object. Note that this in itself does not 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * always guarantee that the reference returned by readUnshared is unique; 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the deserialized object may define a readResolve method which returns an 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object visible to other parties, or readUnshared may return a Class 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object or enum constant obtainable elsewhere in the stream or through 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * external means. If the deserialized object defines a readResolve method 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the invocation of that method returns an array, then readUnshared 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * returns a shallow clone of that array; this guarantees that the returned 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * array object is unique and cannot be obtained a second time from an 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * invocation of readObject or readUnshared on the ObjectInputStream, 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * even if the underlying data stream has been manipulated. 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>ObjectInputStream subclasses which override this method can only be 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * constructed in security contexts possessing the 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "enableSubclassImplementation" SerializablePermission; any attempt to 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * instantiate such a subclass without this permission will cause a 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * SecurityException to be thrown. 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return reference to deserialized object 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ClassNotFoundException if class of an object to deserialize 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * cannot be found 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws StreamCorruptedException if control information in the stream 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is inconsistent 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ObjectStreamException if object to deserialize has already 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * appeared in stream 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws OptionalDataException if primitive data is next in stream 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error occurs during deserialization 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Object readUnshared() throws IOException, ClassNotFoundException { 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if nested read, passHandle contains handle of enclosing object 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int outerHandle = passHandle; 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object obj = readObject0(true); 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markDependency(outerHandle, passHandle); 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException ex = handles.lookupException(passHandle); 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ex != null) { 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ex; 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (depth == 0) { 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vlist.doCallbacks(); 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return obj; 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = outerHandle; 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (closed && depth == 0) { 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski clear(); 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Read the non-static and non-transient fields of the current class from 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this stream. This may only be called from the readObject method of the 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class being deserialized. It will throw the NotActiveException if it is 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * called otherwise. 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ClassNotFoundException if the class of a serialized object 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * could not be found. 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error occurs. 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NotActiveException if the stream is not currently reading 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * objects. 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void defaultReadObject() 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, ClassNotFoundException 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (curContext == null) { 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotActiveException("not in call to readObject"); 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object curObj = curContext.getObj(); 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass curDesc = curContext.getDesc(); 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(false); 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski defaultReadFields(curObj, curDesc); 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(true); 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!curDesc.hasWriteObjectData()) { 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Fix for 4360508: since stream does not contain terminating 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * knows to simulate end-of-custom-data behavior. 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski defaultDataEnd = true; 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException ex = handles.lookupException(passHandle); 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ex != null) { 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ex; 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads the persistent fields from the stream and makes them available by 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * name. 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the <code>GetField</code> object representing the persistent 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * fields of the object being deserialized 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ClassNotFoundException if the class of a serialized object 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * could not be found. 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error occurs. 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NotActiveException if the stream is not currently reading 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * objects. 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.2 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ObjectInputStream.GetField readFields() 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, ClassNotFoundException 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (curContext == null) { 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotActiveException("not in call to readObject"); 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object curObj = curContext.getObj(); 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass curDesc = curContext.getDesc(); 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(false); 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski GetFieldImpl getField = new GetFieldImpl(curDesc); 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getField.readFields(); 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(true); 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!curDesc.hasWriteObjectData()) { 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Fix for 4360508: since stream does not contain terminating 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * knows to simulate end-of-custom-data behavior. 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski defaultDataEnd = true; 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getField; 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Register an object to be validated before the graph is returned. While 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * similar to resolveObject these validations are called after the entire 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * graph has been reconstituted. Typically, a readObject method will 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * register the object with the stream so that when all of the objects are 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * restored a final set of validations can be performed. 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param obj the object to receive the validation callback. 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param prio controls the order of callbacks;zero is a good default. 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Use higher numbers to be called back earlier, lower numbers for 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * later callbacks. Within a priority, callbacks are processed in 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * no particular order. 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NotActiveException The stream is not currently reading objects 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * so it is invalid to register a callback. 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws InvalidObjectException The validation object is null. 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void registerValidation(ObjectInputValidation obj, int prio) 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws NotActiveException, InvalidObjectException 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (depth == 0) { 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotActiveException("stream inactive"); 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vlist.register(obj, prio); 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Load the local class equivalent of the specified stream class 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * description. Subclasses may implement this method to allow classes to 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be fetched from an alternate source. 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The corresponding method in <code>ObjectOutputStream</code> is 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>annotateClass</code>. This method will be invoked only once for 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * each unique class in the stream. This method can be implemented by 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * subclasses to use an alternate loading mechanism but must return a 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>Class</code> object. Once returned, if the class is not an array 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class, its serialVersionUID is compared to the serialVersionUID of the 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * serialized class, and if there is a mismatch, the deserialization fails 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and an {@link InvalidClassException} is thrown. 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The default implementation of this method in 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>ObjectInputStream</code> returns the result of calling 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Class.forName(desc.getName(), false, loader) 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * where <code>loader</code> is determined as follows: if there is a 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method on the current thread's stack whose declaring class was 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * defined by a user-defined class loader (and was not a generated to 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * implement reflective invocations), then <code>loader</code> is class 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * loader corresponding to the closest such method to the currently 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * executing frame; otherwise, <code>loader</code> is 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>null</code>. If this call results in a 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>ClassNotFoundException</code> and the name of the passed 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>ObjectStreamClass</code> instance is the Java language keyword 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for a primitive type or void, then the <code>Class</code> object 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * representing that primitive type or void will be returned 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (e.g., an <code>ObjectStreamClass</code> with the name 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>). 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Otherwise, the <code>ClassNotFoundException</code> will be thrown to 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the caller of this method. 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param desc an instance of class <code>ObjectStreamClass</code> 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a <code>Class</code> object corresponding to <code>desc</code> 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException any of the usual Input/Output exceptions. 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ClassNotFoundException if class of a serialized object cannot 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be found. 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected Class<?> resolveClass(ObjectStreamClass desc) 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, ClassNotFoundException 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = desc.getName(); 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Class.forName(name, false, latestUserDefinedLoader()); 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ClassNotFoundException ex) { 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class<?> cl = primClasses.get(name); 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cl != null) { 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cl; 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ex; 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a proxy class that implements the interfaces named in a proxy 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class descriptor; subclasses may implement this method to read custom 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * data from the stream along with the descriptors for dynamic proxy 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * classes, allowing them to use an alternate loading mechanism for the 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * interfaces and the proxy class. 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>This method is called exactly once for each unique proxy class 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * descriptor in the stream. 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The corresponding method in <code>ObjectOutputStream</code> is 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>annotateProxyClass</code>. For a given subclass of 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>ObjectInputStream</code> that overrides this method, the 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>annotateProxyClass</code> method in the corresponding subclass of 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>ObjectOutputStream</code> must write any data or objects read by 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this method. 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The default implementation of this method in 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>ObjectInputStream</code> returns the result of calling 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>Proxy.getProxyClass</code> with the list of <code>Class</code> 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * objects for the interfaces that are named in the <code>interfaces</code> 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * parameter. The <code>Class</code> object for each interface name 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>i</code> is the value returned by calling 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Class.forName(i, false, loader) 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * where <code>loader</code> is that of the first non-<code>null</code> 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class loader up the execution stack, or <code>null</code> if no 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * non-<code>null</code> class loaders are on the stack (the same class 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * loader choice used by the <code>resolveClass</code> method). Unless any 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the resolved interfaces are non-public, this same value of 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>loader</code> is also the class loader passed to 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>Proxy.getProxyClass</code>; if non-public interfaces are present, 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * their class loader is passed instead (if more than one non-public 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * interface class loader is encountered, an 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>IllegalAccessError</code> is thrown). 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If <code>Proxy.getProxyClass</code> throws an 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code> 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * will throw a <code>ClassNotFoundException</code> containing the 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>IllegalArgumentException</code>. 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param interfaces the list of interface names that were 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * deserialized in the proxy class descriptor 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a proxy class for the specified interfaces 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException any exception thrown by the underlying 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>InputStream</code> 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ClassNotFoundException if the proxy class or any of the 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * named interfaces could not be found 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see ObjectOutputStream#annotateProxyClass(Class) 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected Class<?> resolveProxyClass(String[] interfaces) 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, ClassNotFoundException 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassLoader latestLoader = latestUserDefinedLoader(); 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassLoader nonPublicLoader = null; 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean hasNonPublicInterface = false; 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // define proxy in class loader of non-public interface(s), if any 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class[] classObjs = new Class[interfaces.length]; 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < interfaces.length; i++) { 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class cl = Class.forName(interfaces[i], false, latestLoader); 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((cl.getModifiers() & Modifier.PUBLIC) == 0) { 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hasNonPublicInterface) { 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nonPublicLoader != cl.getClassLoader()) { 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalAccessError( 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "conflicting non-public interface class loaders"); 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nonPublicLoader = cl.getClassLoader(); 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hasNonPublicInterface = true; 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski classObjs[i] = cl; 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Proxy.getProxyClass( 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hasNonPublicInterface ? nonPublicLoader : latestLoader, 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski classObjs); 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IllegalArgumentException e) { 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClassNotFoundException(null, e); 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method will allow trusted subclasses of ObjectInputStream to 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * substitute one object for another during deserialization. Replacing 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * objects is disabled until enableResolveObject is called. The 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * enableResolveObject method checks that the stream requesting to resolve 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object can be trusted. Every reference to serializable objects is passed 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to resolveObject. To insure that the private state of objects is not 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unintentionally exposed only trusted streams may use resolveObject. 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>This method is called after an object has been read but before it is 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * returned from readObject. The default resolveObject method just returns 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the same object. 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>When a subclass is replacing objects it must insure that the 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * substituted object is compatible with every field where the reference 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * will be stored. Objects whose type is not a subclass of the type of the 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * field or array element abort the serialization by raising an exception 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the object is not be stored. 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>This method is called only once when each object is first 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * encountered. All subsequent references to the object will be redirected 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the new object. 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param obj object to be substituted 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the substituted object 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException Any of the usual Input/Output exceptions. 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected Object resolveObject(Object obj) throws IOException { 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return obj; 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Enable the stream to allow objects read from the stream to be replaced. 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * When enabled, the resolveObject method is called for every object being 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * deserialized. 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If <i>enable</i> is true, and there is a security manager installed, 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this method first calls the security manager's 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkPermission</code> method with the 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SerializablePermission("enableSubstitution")</code> permission to 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ensure it's ok to enable the stream to allow objects read from the 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream to be replaced. 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param enable true for enabling use of <code>resolveObject</code> for 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * every object being deserialized 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the previous setting before this method was invoked 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if a security manager exists and its 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkPermission</code> method denies enabling the stream 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to allow objects read from the stream to be replaced. 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkPermission 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.SerializablePermission 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected boolean enableResolveObject(boolean enable) 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws SecurityException 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (enable == enableResolve) { 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return enable; 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (enable) { 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) { 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkPermission(SUBSTITUTION_PERMISSION); 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski enableResolve = enable; 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return !enableResolve; 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The readStreamHeader method is provided to allow subclasses to read and 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * verify their own stream headers. It reads and verifies the magic number 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and version number. 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws StreamCorruptedException if control information in the stream 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is inconsistent 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void readStreamHeader() 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, StreamCorruptedException 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski short s0 = bin.readShort(); 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski short s1 = bin.readShort(); 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) { 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String.format("invalid stream header: %04X%04X", s0, s1)); 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Read a class descriptor from the serialization stream. This method is 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * called when the ObjectInputStream expects a class descriptor as the next 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * item in the serialization stream. Subclasses of ObjectInputStream may 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * override this method to read in class descriptors that have been written 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in non-standard formats (by subclasses of ObjectOutputStream which have 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * overridden the <code>writeClassDescriptor</code> method). By default, 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this method reads class descriptors according to the format defined in 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the Object Serialization specification. 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the class descriptor read 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If an I/O error has occurred. 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ClassNotFoundException If the Class of a serialized object used 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in the class descriptor representation cannot be found 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.ObjectOutputStream#writeClassDescriptor(java.io.ObjectStreamClass) 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected ObjectStreamClass readClassDescriptor() 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, ClassNotFoundException 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass desc = new ObjectStreamClass(); 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski desc.readNonProxy(this); 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return desc; 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a byte of data. This method will block if no input is available. 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the byte read, or -1 if the end of the stream is reached. 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If an I/O error has occurred. 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read() throws IOException { 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.read(); 84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads into an array of bytes. This method will block until some input 84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is available. Consider using java.io.DataInputStream.readFully to read 84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * exactly 'length' bytes. 84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param buf the buffer into which the data is read 85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param off the start offset of the data 85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param len the maximum number of bytes read 85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the actual number of bytes read, -1 is returned when the end of 85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the stream is reached. 85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If an I/O error has occurred. 85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.DataInputStream#readFully(byte[],int,int) 85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(byte[] buf, int off, int len) throws IOException { 85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (buf == null) { 86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int endoff = off + len; 86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) { 86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.read(buf, off, len, false); 86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the number of bytes that can be read without blocking. 87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the number of available bytes. 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int available() throws IOException { 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.available(); 87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Closes the input stream. Must be called to release any resources 88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * associated with the stream. 88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If an I/O error has occurred. 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() throws IOException { 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Even if stream already closed, propagate redundant close to 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying stream to stay consistent with previous implementations. 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski closed = true; 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (depth == 0) { 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski clear(); 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.close(); 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in a boolean. 90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the boolean read. 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean readBoolean() throws IOException { 90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readBoolean(); 90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads an 8 bit byte. 91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the 8 bit byte read. 91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte readByte() throws IOException { 91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readByte(); 91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads an unsigned 8 bit byte. 92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the 8 bit byte read. 92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int readUnsignedByte() throws IOException { 92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readUnsignedByte(); 92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a 16 bit char. 93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the 16 bit char read. 93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public char readChar() throws IOException { 93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readChar(); 94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a 16 bit short. 94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the 16 bit short read. 94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public short readShort() throws IOException { 95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readShort(); 95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads an unsigned 16 bit short. 95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the 16 bit short read. 95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int readUnsignedShort() throws IOException { 96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readUnsignedShort(); 96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a 32 bit int. 96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the 32 bit integer read. 96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int readInt() throws IOException { 97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readInt(); 97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a 64 bit long. 97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the read 64 bit long. 97951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long readLong() throws IOException { 98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readLong(); 98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a 32 bit float. 98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the 32 bit float read. 99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public float readFloat() throws IOException { 99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readFloat(); 99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a 64 bit double. 99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the 64 bit double read. 100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 100351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 100451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public double readDouble() throws IOException { 100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readDouble(); 100651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads bytes, blocking until all bytes are read. 101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param buf the buffer into which the data is read 101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void readFully(byte[] buf) throws IOException { 101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readFully(buf, 0, buf.length, false); 101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads bytes, blocking until all bytes are read. 102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param buf the buffer into which the data is read 102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param off the start offset of the data 102451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param len the maximum number of bytes to read 102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws EOFException If end of file is reached. 102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If other I/O error has occurred. 102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void readFully(byte[] buf, int off, int len) throws IOException { 102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int endoff = off + len; 103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) { 103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readFully(buf, off, len, false); 103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Skips bytes. 103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param len the number of bytes to be skipped 104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the actual number of bytes skipped. 104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException If an I/O error has occurred. 104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int skipBytes(int len) throws IOException { 104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.skipBytes(len); 104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in a line that has been terminated by a \n, \r, \r\n or EOF. 104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a String copy of the line. 105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @deprecated This method does not properly convert bytes to characters. 105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * see DataInputStream for the details and alternatives. 105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Deprecated 105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String readLine() throws IOException { 105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readLine(); 105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a String in 106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <a href="DataInput.html#modified-utf-8">modified UTF-8</a> 106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * format. 106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the String. 106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws UTFDataFormatException if read bytes do not represent a valid 107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * modified UTF-8 encoding of a string 107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String readUTF() throws IOException { 107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bin.readUTF(); 107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Provide access to the persistent fields read from the input stream. 107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static abstract class GetField { 108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the ObjectStreamClass that describes the fields in the stream. 108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the descriptor class that describes the serializable fields 108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract ObjectStreamClass getObjectStreamClass(); 108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return true if the named field is defaulted and has no value in this 109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream. 109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true, if and only if the named field is defaulted 109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from 109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the underlying <code>InputStream</code> 109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if <code>name</code> does not 109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * correspond to a serializable field 109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract boolean defaulted(String name) throws IOException; 110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the value of the named boolean field from the persistent field. 110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param val the default value to use if <code>name</code> does not 110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a value 110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the value of the named <code>boolean</code> field 110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if type of <code>name</code> is 111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not serializable or if the field type is incorrect 111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract boolean get(String name, boolean val) 111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException; 111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the value of the named byte field from the persistent field. 111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param val the default value to use if <code>name</code> does not 112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a value 112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the value of the named <code>byte</code> field 112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if type of <code>name</code> is 112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not serializable or if the field type is incorrect 112751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract byte get(String name, byte val) throws IOException; 112951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the value of the named char field from the persistent field. 113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param val the default value to use if <code>name</code> does not 113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a value 113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the value of the named <code>char</code> field 113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if type of <code>name</code> is 114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not serializable or if the field type is incorrect 114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract char get(String name, char val) throws IOException; 114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the value of the named short field from the persistent field. 114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param val the default value to use if <code>name</code> does not 114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a value 115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the value of the named <code>short</code> field 115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if type of <code>name</code> is 115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not serializable or if the field type is incorrect 115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract short get(String name, short val) throws IOException; 115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the value of the named int field from the persistent field. 116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param val the default value to use if <code>name</code> does not 116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a value 116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the value of the named <code>int</code> field 116551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if type of <code>name</code> is 116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not serializable or if the field type is incorrect 116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract int get(String name, int val) throws IOException; 117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the value of the named long field from the persistent field. 117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param val the default value to use if <code>name</code> does not 117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a value 117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the value of the named <code>long</code> field 117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if type of <code>name</code> is 118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not serializable or if the field type is incorrect 118351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract long get(String name, long val) throws IOException; 118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the value of the named float field from the persistent field. 118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param val the default value to use if <code>name</code> does not 119151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a value 119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the value of the named <code>float</code> field 119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if type of <code>name</code> is 119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not serializable or if the field type is incorrect 119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract float get(String name, float val) throws IOException; 119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the value of the named double field from the persistent field. 120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param val the default value to use if <code>name</code> does not 120551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a value 120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the value of the named <code>double</code> field 120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 120851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if type of <code>name</code> is 121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not serializable or if the field type is incorrect 121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract double get(String name, double val) throws IOException; 121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the value of the named Object field from the persistent field. 121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the field 121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param val the default value to use if <code>name</code> does not 121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a value 122051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the value of the named <code>Object</code> field 122151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if there are I/O errors while reading from the 122251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying <code>InputStream</code> 122351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if type of <code>name</code> is 122451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not serializable or if the field type is incorrect 122551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 122651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract Object get(String name, Object val) throws IOException; 122751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Verifies that this (possibly subclass) instance can be constructed 123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * without violating security constraints: the subclass must not override 123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * security-sensitive non-final methods, or else the 123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "enableSubclassImplementation" SerializablePermission is checked. 123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void verifySubclass() { 123651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class cl = getClass(); 123751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cl == ObjectInputStream.class) { 123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm == null) { 124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); 124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); 124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Boolean result = Caches.subclassAudits.get(key); 124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (result == null) { 124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result = Boolean.valueOf(auditSubclass(cl)); 124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Caches.subclassAudits.putIfAbsent(key, result); 125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (result.booleanValue()) { 125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); 125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Performs reflective checks on given subclass to verify that it doesn't 125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * override security-sensitive non-final methods. Returns true if subclass 126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is "safe", false otherwise. 126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static boolean auditSubclass(final Class<?> subcl) { 126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Boolean result = AccessController.doPrivileged( 126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new PrivilegedAction<Boolean>() { 126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Boolean run() { 126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (Class<?> cl = subcl; 126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cl != ObjectInputStream.class; 126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cl = cl.getSuperclass()) 126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cl.getDeclaredMethod( 127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "readUnshared", (Class[]) null); 127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Boolean.FALSE; 127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (NoSuchMethodException ex) { 127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 127751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cl.getDeclaredMethod("readFields", (Class[]) null); 127851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Boolean.FALSE; 127951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (NoSuchMethodException ex) { 128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 128151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Boolean.TRUE; 128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 128451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ); 128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return result.booleanValue(); 128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Clears internal data structures. 129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void clear() { 129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.clear(); 129451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vlist.clear(); 129551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 129651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 129751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 129851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Underlying readObject implementation. 129951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 130051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object readObject0(boolean unshared) throws IOException { 130151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean oldMode = bin.getBlockDataMode(); 130251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (oldMode) { 130351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int remain = bin.currentBlockRemaining(); 130451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (remain > 0) { 130551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new OptionalDataException(remain); 130651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (defaultDataEnd) { 130751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 130851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Fix for 4360508: stream is currently at the end of a field 130951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * value block written via default serialization; since there 131051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is no terminating TC_ENDBLOCKDATA tag, simulate 131151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * end-of-custom-data behavior explicitly. 131251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 131351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new OptionalDataException(true); 131451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 131551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(false); 131651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 131751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 131851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte tc; 131951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ((tc = bin.peekByte()) == TC_RESET) { 132051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readByte(); 132151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handleReset(); 132251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski depth++; 132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (tc) { 132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_NULL: 132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readNull(); 132951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 133051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_REFERENCE: 133151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readHandle(unshared); 133251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_CLASS: 133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readClass(unshared); 133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_CLASSDESC: 133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_PROXYCLASSDESC: 133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readClassDesc(unshared); 133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_STRING: 134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_LONGSTRING: 134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return checkResolve(readString(unshared)); 134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_ARRAY: 134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return checkResolve(readArray(unshared)); 134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_ENUM: 134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return checkResolve(readEnum(unshared)); 134951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 135051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_OBJECT: 135151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return checkResolve(readOrdinaryObject(unshared)); 135251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 135351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_EXCEPTION: 135451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IOException ex = readFatalException(); 135551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new WriteAbortedException("writing aborted", ex); 135651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 135751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_BLOCKDATA: 135851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_BLOCKDATALONG: 135951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (oldMode) { 136051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(true); 136151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.peek(); // force header read 136251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new OptionalDataException( 136351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.currentBlockRemaining()); 136451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 136551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 136651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "unexpected block data"); 136751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 136851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 136951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_ENDBLOCKDATA: 137051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (oldMode) { 137151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new OptionalDataException(true); 137251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 137351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 137451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "unexpected end of block data"); 137551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 137651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 137751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 137851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String.format("invalid type code: %02X", tc)); 138051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 138151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 138251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski depth--; 138351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(oldMode); 138451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 138551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 138651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 138751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 138851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If resolveObject has been enabled and given object does not have an 138951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * exception associated with it, calls resolveObject to determine 139051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * replacement for object, and updates handle table accordingly. Returns 139151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * replacement object, or echoes provided object if no replacement 139251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * occurred. Expects that passHandle is set to given object's handle prior 139351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to calling this method. 139451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 139551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object checkResolve(Object obj) throws IOException { 139651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!enableResolve || handles.lookupException(passHandle) != null) { 139751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return obj; 139851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 139951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object rep = resolveObject(obj); 140051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (rep != obj) { 140151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.setObject(passHandle, rep); 140251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 140351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return rep; 140451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 140551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 140651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 140751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads string without allowing it to be replaced in stream. Called from 140851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * within ObjectStreamClass.read(). 140951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 141051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String readTypeString() throws IOException { 141151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int oldHandle = passHandle; 141251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 141351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte tc = bin.peekByte(); 141451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (tc) { 141551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_NULL: 141651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (String) readNull(); 141751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 141851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_REFERENCE: 141951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (String) readHandle(false); 142051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 142151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_STRING: 142251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_LONGSTRING: 142351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readString(false); 142451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 142551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 142651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 142751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String.format("invalid type code: %02X", tc)); 142851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 142951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 143051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = oldHandle; 143151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 143251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 143351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 143451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 143551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in null code, sets passHandle to NULL_HANDLE and returns null. 143651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 143751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object readNull() throws IOException { 143851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.readByte() != TC_NULL) { 143951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 144051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 144151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = NULL_HANDLE; 144251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 144351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 144451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 144551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 144651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in object handle, sets passHandle to the read handle, and returns 144751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object associated with the handle. 144851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 144951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object readHandle(boolean unshared) throws IOException { 145051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.readByte() != TC_REFERENCE) { 145151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 145251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 145351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = bin.readInt() - baseWireHandle; 145451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (passHandle < 0 || passHandle >= handles.size()) { 145551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 145651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String.format("invalid handle value: %08X", passHandle + 145751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski baseWireHandle)); 145851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 145951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (unshared) { 146051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // REMIND: what type of exception to throw here? 146151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InvalidObjectException( 146251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "cannot read back reference as unshared"); 146351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 146451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 146551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object obj = handles.lookupObject(passHandle); 146651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj == unsharedMarker) { 146751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // REMIND: what type of exception to throw here? 146851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InvalidObjectException( 146951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "cannot read back reference to unshared object"); 147051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 147151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return obj; 147251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 147351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 147451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 147551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in and returns class object. Sets passHandle to class object's 147651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * assigned handle. Returns null if class is unresolvable (in which case a 147751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ClassNotFoundException will be associated with the class' handle in the 147851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * handle table). 147951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 148051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Class readClass(boolean unshared) throws IOException { 148151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.readByte() != TC_CLASS) { 148251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 148351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 148451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass desc = readClassDesc(false); 148551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class cl = desc.forClass(); 148651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = handles.assign(unshared ? unsharedMarker : cl); 148751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 148851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException resolveEx = desc.getResolveException(); 148951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (resolveEx != null) { 149051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markException(passHandle, resolveEx); 149151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 149251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 149351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.finish(passHandle); 149451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cl; 149551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 149651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 149751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 149851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in and returns (possibly null) class descriptor. Sets passHandle 149951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to class descriptor's assigned handle. If class descriptor cannot be 150051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * resolved to a class in the local VM, a ClassNotFoundException is 150151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * associated with the class descriptor's handle. 150251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 150351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ObjectStreamClass readClassDesc(boolean unshared) 150451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 150551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 150651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte tc = bin.peekByte(); 150751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (tc) { 150851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_NULL: 150951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (ObjectStreamClass) readNull(); 151051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 151151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_REFERENCE: 151251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (ObjectStreamClass) readHandle(unshared); 151351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 151451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_PROXYCLASSDESC: 151551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readProxyDesc(unshared); 151651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 151751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_CLASSDESC: 151851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readNonProxyDesc(unshared); 151951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 152051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 152151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 152251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String.format("invalid type code: %02X", tc)); 152351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 152451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 152551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 152651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isCustomSubclass() { 152751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Return true if this class is a custom subclass of ObjectInputStream 152851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getClass().getClassLoader() 152951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski != ObjectInputStream.class.getClassLoader(); 153051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 153151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 153251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 153351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in and returns class descriptor for a dynamic proxy class. Sets 153451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * passHandle to proxy class descriptor's assigned handle. If proxy class 153551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * descriptor cannot be resolved to a class in the local VM, a 153651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ClassNotFoundException is associated with the descriptor's handle. 153751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 153851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ObjectStreamClass readProxyDesc(boolean unshared) 153951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 154051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 154151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.readByte() != TC_PROXYCLASSDESC) { 154251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 154351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 154451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 154551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass desc = new ObjectStreamClass(); 154651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int descHandle = handles.assign(unshared ? unsharedMarker : desc); 154751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = NULL_HANDLE; 154851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 154951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int numIfaces = bin.readInt(); 155051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] ifaces = new String[numIfaces]; 155151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < numIfaces; i++) { 155251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ifaces[i] = bin.readUTF(); 155351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 155451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 155551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class cl = null; 155651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException resolveEx = null; 155751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(true); 155851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 155951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((cl = resolveProxyClass(ifaces)) == null) { 156051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski resolveEx = new ClassNotFoundException("null class"); 156151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (!Proxy.isProxyClass(cl)) { 156251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InvalidClassException("Not a proxy"); 156351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 156451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ReflectUtil.checkProxyPackageAccess makes a test 156551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // equivalent to isCustomSubclass so there's no need 156651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // to condition this call to isCustomSubclass == true here. 156751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ReflectUtil.checkProxyPackageAccess( 156851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getClass().getClassLoader(), 156951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cl.getInterfaces()); 157051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 157151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ClassNotFoundException ex) { 157251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski resolveEx = ex; 157351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 157451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski skipCustomData(); 157551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 157651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski desc.initProxy(cl, resolveEx, readClassDesc(false)); 157751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 157851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.finish(descHandle); 157951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = descHandle; 158051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return desc; 158151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 158251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 158351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 158451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in and returns class descriptor for a class that is not a dynamic 158551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * proxy class. Sets passHandle to class descriptor's assigned handle. If 158651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class descriptor cannot be resolved to a class in the local VM, a 158751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ClassNotFoundException is associated with the descriptor's handle. 158851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 158951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ObjectStreamClass readNonProxyDesc(boolean unshared) 159051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 159151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 159251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.readByte() != TC_CLASSDESC) { 159351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 159451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 159551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 159651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass desc = new ObjectStreamClass(); 159751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int descHandle = handles.assign(unshared ? unsharedMarker : desc); 159851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = NULL_HANDLE; 159951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 160051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass readDesc = null; 160151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 160251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readDesc = readClassDescriptor(); 160351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ClassNotFoundException ex) { 160451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw (IOException) new InvalidClassException( 160551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "failed to read class descriptor").initCause(ex); 160651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 160751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 160851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class cl = null; 160951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException resolveEx = null; 161051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(true); 161151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final boolean checksRequired = isCustomSubclass(); 161251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 161351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((cl = resolveClass(readDesc)) == null) { 161451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski resolveEx = new ClassNotFoundException("null class"); 161551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (checksRequired) { 161651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ReflectUtil.checkPackageAccess(cl); 161751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 161851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ClassNotFoundException ex) { 161951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski resolveEx = ex; 162051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 162151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski skipCustomData(); 162251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 162351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); 162451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 162551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.finish(descHandle); 162651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = descHandle; 162751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return desc; 162851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 162951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 163051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 163151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in and returns new string. Sets passHandle to new string's 163251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * assigned handle. 163351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 163451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String readString(boolean unshared) throws IOException { 163551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String str; 163651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte tc = bin.readByte(); 163751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (tc) { 163851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_STRING: 163951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski str = bin.readUTF(); 164051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 164151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 164251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_LONGSTRING: 164351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski str = bin.readLongUTF(); 164451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 164551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 164651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 164751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 164851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String.format("invalid type code: %02X", tc)); 164951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 165051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = handles.assign(unshared ? unsharedMarker : str); 165151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.finish(passHandle); 165251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return str; 165351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 165451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 165551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 165651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in and returns array object, or null if array class is 165751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unresolvable. Sets passHandle to array's assigned handle. 165851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 165951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object readArray(boolean unshared) throws IOException { 166051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.readByte() != TC_ARRAY) { 166151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 166251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 166351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 166451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass desc = readClassDesc(false); 166551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = bin.readInt(); 166651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 166751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object array = null; 166851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class cl, ccl = null; 166951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((cl = desc.forClass()) != null) { 167051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ccl = cl.getComponentType(); 167151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski array = Array.newInstance(ccl, len); 167251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 167351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 167451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int arrayHandle = handles.assign(unshared ? unsharedMarker : array); 167551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException resolveEx = desc.getResolveException(); 167651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (resolveEx != null) { 167751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markException(arrayHandle, resolveEx); 167851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 167951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 168051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ccl == null) { 168151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < len; i++) { 168251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readObject0(false); 168351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 168451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (ccl.isPrimitive()) { 168551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ccl == Integer.TYPE) { 168651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readInts((int[]) array, 0, len); 168751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (ccl == Byte.TYPE) { 168851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readFully((byte[]) array, 0, len, true); 168951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (ccl == Long.TYPE) { 169051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readLongs((long[]) array, 0, len); 169151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (ccl == Float.TYPE) { 169251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readFloats((float[]) array, 0, len); 169351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (ccl == Double.TYPE) { 169451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readDoubles((double[]) array, 0, len); 169551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (ccl == Short.TYPE) { 169651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readShorts((short[]) array, 0, len); 169751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (ccl == Character.TYPE) { 169851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readChars((char[]) array, 0, len); 169951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (ccl == Boolean.TYPE) { 170051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readBooleans((boolean[]) array, 0, len); 170151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 170251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 170351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 170451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 170551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object[] oa = (Object[]) array; 170651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < len; i++) { 170751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski oa[i] = readObject0(false); 170851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markDependency(arrayHandle, passHandle); 170951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 171051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 171151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 171251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.finish(arrayHandle); 171351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = arrayHandle; 171451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return array; 171551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 171651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 171751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 171851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in and returns enum constant, or null if enum type is 171951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unresolvable. Sets passHandle to enum constant's assigned handle. 172051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 172151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Enum readEnum(boolean unshared) throws IOException { 172251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.readByte() != TC_ENUM) { 172351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 172451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 172551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 172651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass desc = readClassDesc(false); 172751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!desc.isEnum()) { 172851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InvalidClassException("non-enum class: " + desc); 172951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 173051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 173151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int enumHandle = handles.assign(unshared ? unsharedMarker : null); 173251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException resolveEx = desc.getResolveException(); 173351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (resolveEx != null) { 173451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markException(enumHandle, resolveEx); 173551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 173651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 173751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = readString(false); 173851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Enum en = null; 173951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class cl = desc.forClass(); 174051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cl != null) { 174151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 174251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski en = Enum.valueOf(cl, name); 174351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IllegalArgumentException ex) { 174451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw (IOException) new InvalidObjectException( 174551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "enum constant " + name + " does not exist in " + 174651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cl).initCause(ex); 174751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 174851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!unshared) { 174951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.setObject(enumHandle, en); 175051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 175151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 175251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 175351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.finish(enumHandle); 175451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = enumHandle; 175551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return en; 175651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 175751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 175851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 175951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads and returns "ordinary" (i.e., not a String, Class, 176051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ObjectStreamClass, array, or enum constant) object, or null if object's 176151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class is unresolvable (in which case a ClassNotFoundException will be 176251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * associated with object's handle). Sets passHandle to object's assigned 176351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * handle. 176451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 176551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object readOrdinaryObject(boolean unshared) 176651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 176751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 176851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.readByte() != TC_OBJECT) { 176951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 177051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 177151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 177251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass desc = readClassDesc(false); 177351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski desc.checkDeserialize(); 177451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 177551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class<?> cl = desc.forClass(); 177651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cl == String.class || cl == Class.class 177751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski || cl == ObjectStreamClass.class) { 177851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InvalidClassException("invalid class descriptor"); 177951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 178051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 178151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object obj; 178251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 178351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski obj = desc.isInstantiable() ? desc.newInstance() : null; 178451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception ex) { 178551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw (IOException) new InvalidClassException( 178651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski desc.forClass().getName(), 178751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "unable to create instance").initCause(ex); 178851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 178951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 179051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = handles.assign(unshared ? unsharedMarker : obj); 179151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException resolveEx = desc.getResolveException(); 179251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (resolveEx != null) { 179351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markException(passHandle, resolveEx); 179451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 179551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 179651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (desc.isExternalizable()) { 179751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readExternalData((Externalizable) obj, desc); 179851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 179951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readSerialData(obj, desc); 180051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 180151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 180251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.finish(passHandle); 180351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 180451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj != null && 180551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.lookupException(passHandle) == null && 180651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski desc.hasReadResolveMethod()) 180751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 180851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object rep = desc.invokeReadResolve(obj); 180951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (unshared && rep.getClass().isArray()) { 181051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rep = cloneArray(rep); 181151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 181251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (rep != obj) { 181351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.setObject(passHandle, obj = rep); 181451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 181551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 181651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 181751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return obj; 181851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 181951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 182051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 182151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If obj is non-null, reads externalizable data by invoking readExternal() 182251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method of obj; otherwise, attempts to skip over externalizable data. 182351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Expects that passHandle is set to obj's handle before this method is 182451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * called. 182551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 182651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void readExternalData(Externalizable obj, ObjectStreamClass desc) 182751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 182851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 182951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SerialCallbackContext oldContext = curContext; 183051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski curContext = null; 183151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 183251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean blocked = desc.hasBlockExternalData(); 183351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blocked) { 183451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(true); 183551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 183651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj != null) { 183751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 183851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski obj.readExternal(this); 183951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ClassNotFoundException ex) { 184051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 184151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In most cases, the handle table has already propagated 184251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a CNFException to passHandle at this point; this mark 184351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * call is included to address cases where the readExternal 184451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method has cons'ed and thrown a new CNFException of its 184551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * own. 184651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 184751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markException(passHandle, ex); 184851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 184951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 185051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blocked) { 185151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski skipCustomData(); 185251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 185351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 185451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski curContext = oldContext; 185551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 185651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 185751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * At this point, if the externalizable data was not written in 185851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * block-data form and either the externalizable class doesn't exist 185951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * locally (i.e., obj == null) or readExternal() just threw a 186051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * CNFException, then the stream is probably in an inconsistent state, 186151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * since some (or all) of the externalizable data may not have been 186251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * consumed. Since there's no "correct" action to take in this case, 186351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * we mimic the behavior of past serialization implementations and 186451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * blindly hope that the stream is in sync; if it isn't and additional 186551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * externalizable data remains in the stream, a subsequent read will 186651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * most likely throw a StreamCorruptedException. 186751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 186851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 186951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 187051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 187151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads (or attempts to skip, if obj is null or is tagged with a 187251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ClassNotFoundException) instance data for each serializable class of 187351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object in stream, from superclass to subclass. Expects that passHandle 187451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is set to obj's handle before this method is called. 187551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 187651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void readSerialData(Object obj, ObjectStreamClass desc) 187751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 187851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 187951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout(); 188051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < slots.length; i++) { 188151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamClass slotDesc = slots[i].desc; 188251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 188351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (slots[i].hasData) { 188451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj != null && 188551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski slotDesc.hasReadObjectMethod() && 188651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.lookupException(passHandle) == null) 188751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 188851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SerialCallbackContext oldContext = curContext; 188951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 189051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 189151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski curContext = new SerialCallbackContext(obj, slotDesc); 189251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 189351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(true); 189451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski slotDesc.invokeReadObject(obj, this); 189551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ClassNotFoundException ex) { 189651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 189751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In most cases, the handle table has already 189851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * propagated a CNFException to passHandle at this 189951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * point; this mark call is included to address cases 190051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * where the custom readObject method has cons'ed and 190151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * thrown a new CNFException of its own. 190251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 190351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markException(passHandle, ex); 190451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 190551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski curContext.setUsed(); 190651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski curContext = oldContext; 190751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 190851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 190951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 191051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * defaultDataEnd may have been set indirectly by custom 191151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * readObject() method when calling defaultReadObject() or 191251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * readFields(); clear it to restore normal read behavior. 191351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 191451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski defaultDataEnd = false; 191551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 191651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski defaultReadFields(obj, slotDesc); 191751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 191851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (slotDesc.hasWriteObjectData()) { 191951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski skipCustomData(); 192051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 192151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(false); 192251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 192351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 192451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj != null && 192551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski slotDesc.hasReadObjectNoDataMethod() && 192651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.lookupException(passHandle) == null) 192751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 192851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski slotDesc.invokeReadObjectNoData(obj); 192951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 193051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 193151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 193251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 193351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 193451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 193551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Skips over all block data and objects until TC_ENDBLOCKDATA is 193651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * encountered. 193751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 193851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void skipCustomData() throws IOException { 193951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int oldHandle = passHandle; 194051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 194151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.getBlockDataMode()) { 194251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.skipBlockData(); 194351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(false); 194451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 194551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (bin.peekByte()) { 194651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_BLOCKDATA: 194751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_BLOCKDATALONG: 194851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.setBlockDataMode(true); 194951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 195051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 195151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_ENDBLOCKDATA: 195251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readByte(); 195351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = oldHandle; 195451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 195551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 195651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 195751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readObject0(false); 195851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 195951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 196051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 196151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 196251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 196351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 196451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in values of serializable fields declared by given class 196551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * descriptor. If obj is non-null, sets field values in obj. Expects that 196651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * passHandle is set to obj's handle before this method is called. 196751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 196851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void defaultReadFields(Object obj, ObjectStreamClass desc) 196951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 197051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 197151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // REMIND: is isInstance check necessary? 197251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class cl = desc.forClass(); 197351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cl != null && obj != null && !cl.isInstance(obj)) { 197451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClassCastException(); 197551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 197651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 197751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int primDataSize = desc.getPrimDataSize(); 197851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (primVals == null || primVals.length < primDataSize) { 197951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primVals = new byte[primDataSize]; 198051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 198151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readFully(primVals, 0, primDataSize, false); 198251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj != null) { 198351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski desc.setPrimFieldValues(obj, primVals); 198451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 198551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 198651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int objHandle = passHandle; 198751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamField[] fields = desc.getFields(false); 198851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object[] objVals = new Object[desc.getNumObjFields()]; 198951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int numPrimFields = fields.length - objVals.length; 199051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < objVals.length; i++) { 199151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamField f = fields[numPrimFields + i]; 199251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski objVals[i] = readObject0(f.isUnshared()); 199351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (f.getField() != null) { 199451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markDependency(objHandle, passHandle); 199551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 199651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 199751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj != null) { 199851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski desc.setObjFieldValues(obj, objVals); 199951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 200051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = objHandle; 200151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 200251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 200351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 200451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in and returns IOException that caused serialization to abort. 200551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * All stream state is discarded prior to reading in fatal exception. Sets 200651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * passHandle to fatal exception's handle. 200751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 200851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private IOException readFatalException() throws IOException { 200951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bin.readByte() != TC_EXCEPTION) { 201051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 201151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 201251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski clear(); 2013c17398294ce7bc00e83cd236109edf95340d33e5Przemyslaw Szczepaniak IOException e = (IOException) readObject0(false); 2014c17398294ce7bc00e83cd236109edf95340d33e5Przemyslaw Szczepaniak // ----- BEGIN android ----- 2015c17398294ce7bc00e83cd236109edf95340d33e5Przemyslaw Szczepaniak clear(); 2016c17398294ce7bc00e83cd236109edf95340d33e5Przemyslaw Szczepaniak // ----- END android ----- 2017c17398294ce7bc00e83cd236109edf95340d33e5Przemyslaw Szczepaniak return e; 201851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 201951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 202051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 202151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If recursion depth is 0, clears internal data structures; otherwise, 202251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * throws a StreamCorruptedException. This method is called when a 202351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TC_RESET typecode is encountered. 202451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 202551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void handleReset() throws StreamCorruptedException { 202651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (depth > 0) { 202751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 202851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "unexpected reset; recursion depth: " + depth); 202951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 203051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski clear(); 203151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 203251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 203351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 203451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Converts specified span of bytes into float values. 203551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 203651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // REMIND: remove once hotspot inlines Float.intBitsToFloat 203751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static native void bytesToFloats(byte[] src, int srcpos, 203851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski float[] dst, int dstpos, 203951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nfloats); 204051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 204151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 204251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Converts specified span of bytes into double values. 204351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 204451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // REMIND: remove once hotspot inlines Double.longBitsToDouble 204551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static native void bytesToDoubles(byte[] src, int srcpos, 204651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski double[] dst, int dstpos, 204751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ndoubles); 204851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 204951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 205051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the first non-null class loader (not counting class loaders of 205151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * generated reflection implementation classes) up the execution stack, or 205251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * null if only code from the null class loader is on the stack. This 205351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method is also called via reflection by the following RMI-IIOP class: 205451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 205551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * com.sun.corba.se.internal.util.JDKClassLoader 205651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 205751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method should not be removed or its signature changed without 205851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * corresponding modifications to the above class. 205951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 206051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static ClassLoader latestUserDefinedLoader() { 2061419d15f19dcb247d6188bb6954cb55e8c5ddf20aPrzemyslaw Szczepaniak return VMStack.getClosestUserClassLoader(); 206251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 206351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 206451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 206551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Default GetField implementation. 206651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 206751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class GetFieldImpl extends GetField { 206851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 206951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** class descriptor describing serializable fields */ 207051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final ObjectStreamClass desc; 207151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** primitive field values */ 207251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final byte[] primVals; 207351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** object field values */ 207451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object[] objVals; 207551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** object field value handles */ 207651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final int[] objHandles; 207751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 207851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 207951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates GetFieldImpl object for reading fields defined in given 208051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class descriptor. 208151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 208251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski GetFieldImpl(ObjectStreamClass desc) { 208351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.desc = desc; 208451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski primVals = new byte[desc.getPrimDataSize()]; 208551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski objVals = new Object[desc.getNumObjFields()]; 208651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski objHandles = new int[objVals.length]; 208751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 208851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 208951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ObjectStreamClass getObjectStreamClass() { 209051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return desc; 209151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 209251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 209351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean defaulted(String name) throws IOException { 209451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (getFieldOffset(name, null) < 0); 209551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 209651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 209751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean get(String name, boolean val) throws IOException { 209851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int off = getFieldOffset(name, Boolean.TYPE); 209951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (off >= 0) ? Bits.getBoolean(primVals, off) : val; 210051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 210151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 210251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte get(String name, byte val) throws IOException { 210351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int off = getFieldOffset(name, Byte.TYPE); 210451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (off >= 0) ? primVals[off] : val; 210551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 210651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 210751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public char get(String name, char val) throws IOException { 210851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int off = getFieldOffset(name, Character.TYPE); 210951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (off >= 0) ? Bits.getChar(primVals, off) : val; 211051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 211151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 211251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public short get(String name, short val) throws IOException { 211351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int off = getFieldOffset(name, Short.TYPE); 211451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (off >= 0) ? Bits.getShort(primVals, off) : val; 211551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 211651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 211751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int get(String name, int val) throws IOException { 211851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int off = getFieldOffset(name, Integer.TYPE); 211951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (off >= 0) ? Bits.getInt(primVals, off) : val; 212051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 212151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 212251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public float get(String name, float val) throws IOException { 212351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int off = getFieldOffset(name, Float.TYPE); 212451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (off >= 0) ? Bits.getFloat(primVals, off) : val; 212551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 212651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 212751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long get(String name, long val) throws IOException { 212851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int off = getFieldOffset(name, Long.TYPE); 212951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (off >= 0) ? Bits.getLong(primVals, off) : val; 213051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 213151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 213251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public double get(String name, double val) throws IOException { 213351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int off = getFieldOffset(name, Double.TYPE); 213451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (off >= 0) ? Bits.getDouble(primVals, off) : val; 213551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 213651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 213751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Object get(String name, Object val) throws IOException { 213851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int off = getFieldOffset(name, Object.class); 213951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (off >= 0) { 214051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int objHandle = objHandles[off]; 214151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handles.markDependency(passHandle, objHandle); 214251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (handles.lookupException(objHandle) == null) ? 214351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski objVals[off] : null; 214451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 214551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return val; 214651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 214751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 214851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 214951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 215051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads primitive and object field values from stream. 215151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 215251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void readFields() throws IOException { 215351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bin.readFully(primVals, 0, primVals.length, false); 215451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 215551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int oldHandle = passHandle; 215651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamField[] fields = desc.getFields(false); 215751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int numPrimFields = fields.length - objVals.length; 215851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < objVals.length; i++) { 215951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski objVals[i] = 216051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readObject0(fields[numPrimFields + i].isUnshared()); 216151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski objHandles[i] = passHandle; 216251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 216351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passHandle = oldHandle; 216451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 216551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 216651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 216751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns offset of field with given name and type. A specified type 216851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of null matches all types, Object.class matches all non-primitive 216951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * types, and any other non-null type matches assignable types only. 217051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If no matching field is found in the (incoming) class 217151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * descriptor but a matching field is present in the associated local 217251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class descriptor, returns -1. Throws IllegalArgumentException if 217351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * neither incoming nor local class descriptor contains a match. 217451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 217551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int getFieldOffset(String name, Class type) { 217651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectStreamField field = desc.getField(name, type); 217751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (field != null) { 217851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return field.getOffset(); 217951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (desc.getLocalDesc().getField(name, type) != null) { 218051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 218151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 218251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("no such field " + name + 218351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski " with type " + type); 218451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 218551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 218651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 218751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 218851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 218951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Prioritized list of callbacks to be performed once object graph has been 219051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * completely deserialized. 219151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 219251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class ValidationList { 219351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 219451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class Callback { 219551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final ObjectInputValidation obj; 219651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final int priority; 219751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Callback next; 219851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final AccessControlContext acc; 219951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 220051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Callback(ObjectInputValidation obj, int priority, Callback next, 220151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski AccessControlContext acc) 220251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 220351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.obj = obj; 220451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.priority = priority; 220551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.next = next; 220651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.acc = acc; 220751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 220851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 220951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 221051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** linked list of callbacks */ 221151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Callback list; 221251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 221351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 221451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates new (empty) ValidationList. 221551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 221651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ValidationList() { 221751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 221851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 221951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 222051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Registers callback. Throws InvalidObjectException if callback 222151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object is null. 222251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 222351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void register(ObjectInputValidation obj, int priority) 222451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws InvalidObjectException 222551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 222651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj == null) { 222751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InvalidObjectException("null callback"); 222851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 222951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 223051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Callback prev = null, cur = list; 223151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (cur != null && priority < cur.priority) { 223251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski prev = cur; 223351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cur = cur.next; 223451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 223551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski AccessControlContext acc = AccessController.getContext(); 223651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (prev != null) { 223751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski prev.next = new Callback(obj, priority, cur, acc); 223851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 223951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list = new Callback(obj, priority, list, acc); 224051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 224151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 224251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 224351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 224451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Invokes all registered callbacks and clears the callback list. 224551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Callbacks with higher priorities are called first; those with equal 224651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * priorities may be called in any order. If any of the callbacks 224751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * throws an InvalidObjectException, the callback process is terminated 224851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the exception propagated upwards. 224951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 225051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void doCallbacks() throws InvalidObjectException { 225151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 225251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (list != null) { 225351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski AccessController.doPrivileged( 225451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new PrivilegedExceptionAction<Void>() 225551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 225651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Void run() throws InvalidObjectException { 225751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list.obj.validateObject(); 225851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 225951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 226051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }, list.acc); 226151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list = list.next; 226251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 226351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (PrivilegedActionException ex) { 226451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list = null; 226551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw (InvalidObjectException) ex.getException(); 226651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 226751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 226851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 226951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 227051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Resets the callback list to its initial (empty) state. 227151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 227251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void clear() { 227351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list = null; 227451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 227551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 227651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 227751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 227851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Input stream supporting single-byte peek operations. 227951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 228051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class PeekInputStream extends InputStream { 228151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 228251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** underlying stream */ 228351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final InputStream in; 228451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** peeked byte */ 228551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int peekb = -1; 228651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 228751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 228851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates new PeekInputStream on top of given underlying stream. 228951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 229051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PeekInputStream(InputStream in) { 229151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.in = in; 229251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 229351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 229451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 229551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Peeks at next byte value in stream. Similar to read(), except 229651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that it does not consume the read value. 229751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 229851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int peek() throws IOException { 229951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (peekb >= 0) ? peekb : (peekb = in.read()); 230051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 230151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 230251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read() throws IOException { 230351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (peekb >= 0) { 230451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int v = peekb; 230551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekb = -1; 230651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return v; 230751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 230851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return in.read(); 230951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 231051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 231151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 231251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(byte[] b, int off, int len) throws IOException { 231351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len == 0) { 231451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 231551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (peekb < 0) { 231651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return in.read(b, off, len); 231751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 231851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b[off++] = (byte) peekb; 231951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len--; 232051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekb = -1; 232151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = in.read(b, off, len); 232251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (n >= 0) ? (n + 1) : 1; 232351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 232451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 232551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 232651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void readFully(byte[] b, int off, int len) throws IOException { 232751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 232851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (n < len) { 232951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int count = read(b, off + n, len - n); 233051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count < 0) { 233151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new EOFException(); 233251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 233351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n += count; 233451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 233551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 233651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 233751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long skip(long n) throws IOException { 233851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n <= 0) { 233951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 234051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 234151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int skipped = 0; 234251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (peekb >= 0) { 234351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekb = -1; 234451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski skipped++; 234551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n--; 234651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 234751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return skipped + skip(n); 234851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 234951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 235051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int available() throws IOException { 235151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return in.available() + ((peekb >= 0) ? 1 : 0); 235251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 235351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 235451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() throws IOException { 235551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.close(); 235651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 235751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 235851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 235951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 236051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Input stream with two modes: in default mode, inputs data written in the 236151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * same format as DataOutputStream; in "block data" mode, inputs data 236251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * bracketed by block data markers (see object serialization specification 236351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for details). Buffering depends on block data mode: when in default 236451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * mode, no data is buffered in advance; when in block data mode, all data 236551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for the current data block is read in at once (and buffered). 236651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 236751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class BlockDataInputStream 236851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extends InputStream implements DataInput 236951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 237051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** maximum data block length */ 237151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int MAX_BLOCK_SIZE = 1024; 237251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** maximum data block header length */ 237351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int MAX_HEADER_SIZE = 5; 237451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** (tunable) length of char buffer (for reading strings) */ 237551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int CHAR_BUF_SIZE = 256; 237651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** readBlockHeader() return value indicating header read may block */ 237751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int HEADER_BLOCKED = -2; 237851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 237951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** buffer for reading general/block data */ 238051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final byte[] buf = new byte[MAX_BLOCK_SIZE]; 238151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** buffer for reading block data headers */ 238251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final byte[] hbuf = new byte[MAX_HEADER_SIZE]; 238351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** char buffer for fast string reads */ 238451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final char[] cbuf = new char[CHAR_BUF_SIZE]; 238551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 238651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** block data mode */ 238751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean blkmode = false; 238851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 238951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // block data state fields; values meaningful only when blkmode true 239051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** current offset into buf */ 239151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int pos = 0; 239251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** end offset of valid data in buf, or -1 if no more block data */ 239351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int end = -1; 239451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** number of bytes in current block yet to be read from stream */ 239551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int unread = 0; 239651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 239751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** underlying stream (wrapped in peekable filter stream) */ 239851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final PeekInputStream in; 239951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** loopback stream (for data reads that span data blocks) */ 240051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final DataInputStream din; 240151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 240251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 240351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates new BlockDataInputStream on top of given underlying stream. 240451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Block data mode is turned off by default. 240551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 240651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski BlockDataInputStream(InputStream in) { 240751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.in = new PeekInputStream(in); 240851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski din = new DataInputStream(this); 240951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 241051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 241151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 241251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets block data mode to the given mode (true == on, false == off) 241351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and returns the previous mode value. If the new mode is the same as 241451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the old mode, no action is taken. Throws IllegalStateException if 241551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * block data mode is being switched from on to off while unconsumed 241651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * block data is still present in the stream. 241751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 241851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean setBlockDataMode(boolean newmode) throws IOException { 241951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blkmode == newmode) { 242051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return blkmode; 242151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 242251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (newmode) { 242351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 242451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = 0; 242551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unread = 0; 242651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (pos < end) { 242751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalStateException("unread block data"); 242851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 242951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski blkmode = newmode; 243051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return !blkmode; 243151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 243251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 243351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 243451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true if the stream is currently in block data mode, false 243551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * otherwise. 243651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 243751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean getBlockDataMode() { 243851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return blkmode; 243951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 244051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 244151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 244251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If in block data mode, skips to the end of the current group of data 244351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * blocks (but does not unset block data mode). If not in block data 244451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * mode, throws an IllegalStateException. 244551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 244651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void skipBlockData() throws IOException { 244751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 244851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalStateException("not in block data mode"); 244951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 245051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (end >= 0) { 245151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski refill(); 245251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 245351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 245451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 245551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 245651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Attempts to read in the next block data header (if any). If 245751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * canBlock is false and a full header cannot be read without possibly 245851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * blocking, returns HEADER_BLOCKED, else if the next element in the 245951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream is a block data header, returns the block data length 246051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified by the header, else returns -1. 246151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 246251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int readBlockHeader(boolean canBlock) throws IOException { 246351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (defaultDataEnd) { 246451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 246551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Fix for 4360508: stream is currently at the end of a field 246651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * value block written via default serialization; since there 246751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is no terminating TC_ENDBLOCKDATA tag, simulate 246851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * end-of-custom-data behavior explicitly. 246951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 247051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 247151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 247251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 247351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 247451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int avail = canBlock ? Integer.MAX_VALUE : in.available(); 247551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (avail == 0) { 247651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return HEADER_BLOCKED; 247751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 247851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 247951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int tc = in.peek(); 248051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (tc) { 248151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_BLOCKDATA: 248251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (avail < 2) { 248351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return HEADER_BLOCKED; 248451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 248551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(hbuf, 0, 2); 248651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return hbuf[1] & 0xFF; 248751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 248851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_BLOCKDATALONG: 248951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (avail < 5) { 249051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return HEADER_BLOCKED; 249151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 249251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(hbuf, 0, 5); 249351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = Bits.getInt(hbuf, 1); 249451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len < 0) { 249551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 249651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "illegal block data header length: " + 249751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len); 249851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 249951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return len; 250051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 250151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 250251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TC_RESETs may occur in between data blocks. 250351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Unfortunately, this case must be parsed at a lower 250451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * level than other typecodes, since primitive data 250551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * reads may span data blocks separated by a TC_RESET. 250651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 250751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TC_RESET: 250851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.read(); 250951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handleReset(); 251051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 251151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 251251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 251351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tc >= 0 && (tc < TC_BASE || tc > TC_MAX)) { 251451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 251551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String.format("invalid type code: %02X", 251651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tc)); 251751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 251851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 251951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 252051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 252151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (EOFException ex) { 252251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 252351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "unexpected EOF while reading block data header"); 252451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 252551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 252651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 252751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 252851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Refills internal buffer buf with block data. Any data in buf at the 252951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * time of the call is considered consumed. Sets the pos, end, and 253051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unread fields to reflect the new amount of available block data; if 253151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the next element in the stream is not a data block, sets pos and 253251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unread to 0 and end to -1. 253351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 253451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void refill() throws IOException { 253551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 253651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 253751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 253851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (unread > 0) { 253951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 254051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.read(buf, 0, Math.min(unread, MAX_BLOCK_SIZE)); 254151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n >= 0) { 254251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = n; 254351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unread -= n; 254451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 254551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new StreamCorruptedException( 254651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "unexpected EOF in middle of data block"); 254751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 254851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 254951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = readBlockHeader(true); 255051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n >= 0) { 255151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = 0; 255251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unread = n; 255351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 255451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = -1; 255551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unread = 0; 255651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 255751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 255851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while (pos == end); 255951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ex) { 256051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 256151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = -1; 256251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unread = 0; 256351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ex; 256451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 256551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 256651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 256751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 256851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If in block data mode, returns the number of unconsumed bytes 256951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * remaining in the current data block. If not in block data mode, 257051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * throws an IllegalStateException. 257151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 257251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int currentBlockRemaining() { 257351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blkmode) { 257451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (end >= 0) ? (end - pos) + unread : 0; 257551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 257651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalStateException(); 257751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 257851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 257951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 258051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 258151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Peeks at (but does not consume) and returns the next byte value in 258251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the stream, or -1 if the end of the stream/block data (if in block 258351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * data mode) has been reached. 258451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 258551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int peek() throws IOException { 258651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blkmode) { 258751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (pos == end) { 258851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski refill(); 258951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 259051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (end >= 0) ? (buf[pos] & 0xFF) : -1; 259151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 259251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return in.peek(); 259351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 259451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 259551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 259651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 259751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Peeks at (but does not consume) and returns the next byte value in 259851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the stream, or throws EOFException if end of stream/block data has 259951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * been reached. 260051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 260151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte peekByte() throws IOException { 260251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int val = peek(); 260351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (val < 0) { 260451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new EOFException(); 260551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 260651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (byte) val; 260751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 260851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 260951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 261051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* ----------------- generic input stream methods ------------------ */ 261151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 261251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The following methods are equivalent to their counterparts in 261351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * InputStream, except that they interpret data block boundaries and 261451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * read the requested data from within data blocks when in block data 261551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * mode. 261651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 261751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 261851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read() throws IOException { 261951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blkmode) { 262051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (pos == end) { 262151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski refill(); 262251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 262351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (end >= 0) ? (buf[pos++] & 0xFF) : -1; 262451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 262551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return in.read(); 262651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 262751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 262851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 262951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(byte[] b, int off, int len) throws IOException { 263051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return read(b, off, len, false); 263151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 263251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 263351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long skip(long len) throws IOException { 263451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long remain = len; 263551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (remain > 0) { 263651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blkmode) { 263751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (pos == end) { 263851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski refill(); 263951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 264051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (end < 0) { 264151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 264251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 264351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nread = (int) Math.min(remain, end - pos); 264451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski remain -= nread; 264551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += nread; 264651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 264751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nread = (int) Math.min(remain, MAX_BLOCK_SIZE); 264851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((nread = in.read(buf, 0, nread)) < 0) { 264951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 265051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 265151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski remain -= nread; 265251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 265351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 265451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return len - remain; 265551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 265651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 265751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int available() throws IOException { 265851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blkmode) { 265951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((pos == end) && (unread == 0)) { 266051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n; 266151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ((n = readBlockHeader(false)) == 0) ; 266251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (n) { 266351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case HEADER_BLOCKED: 266451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 266551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 266651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case -1: 266751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 266851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = -1; 266951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 267051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 267151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 267251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 267351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = 0; 267451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unread = n; 267551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 267651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 267751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 267851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // avoid unnecessary call to in.available() if possible 267951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int unreadAvail = (unread > 0) ? 268051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Math.min(in.available(), unread) : 0; 268151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (end >= 0) ? (end - pos) + unreadAvail : 0; 268251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 268351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return in.available(); 268451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 268551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 268651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 268751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() throws IOException { 268851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blkmode) { 268951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 269051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = -1; 269151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unread = 0; 269251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 269351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.close(); 269451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 269551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 269651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 269751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Attempts to read len bytes into byte array b at offset off. Returns 269851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the number of bytes read, or -1 if the end of stream/block data has 269951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * been reached. If copy is true, reads values into an intermediate 270051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * buffer before copying them to b (to avoid exposing a reference to 270151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * b). 270251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 270351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int read(byte[] b, int off, int len, boolean copy) throws IOException { 270451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len == 0) { 270551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 270651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (blkmode) { 270751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (pos == end) { 270851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski refill(); 270951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 271051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (end < 0) { 271151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 271251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 271351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nread = Math.min(len, end - pos); 271451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(buf, pos, b, off, nread); 271551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += nread; 271651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return nread; 271751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (copy) { 271851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nread = in.read(buf, 0, Math.min(len, MAX_BLOCK_SIZE)); 271951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nread > 0) { 272051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(buf, 0, b, off, nread); 272151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 272251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return nread; 272351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 272451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return in.read(b, off, len); 272551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 272651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 272751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 272851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* ----------------- primitive data input methods ------------------ */ 272951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 273051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The following methods are equivalent to their counterparts in 273151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DataInputStream, except that they interpret data block boundaries 273251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and read the requested data from within data blocks when in block 273351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * data mode. 273451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 273551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 273651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void readFully(byte[] b) throws IOException { 273751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readFully(b, 0, b.length, false); 273851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 273951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 274051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void readFully(byte[] b, int off, int len) throws IOException { 274151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readFully(b, off, len, false); 274251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 274351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 274451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void readFully(byte[] b, int off, int len, boolean copy) 274551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 274651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 274751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (len > 0) { 274851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = read(b, off, len, copy); 274951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n < 0) { 275051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new EOFException(); 275151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 275251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski off += n; 275351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len -= n; 275451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 275551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 275651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 275751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int skipBytes(int n) throws IOException { 275851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return din.skipBytes(n); 275951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 276051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 276151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean readBoolean() throws IOException { 276251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int v = read(); 276351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (v < 0) { 276451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new EOFException(); 276551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 276651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (v != 0); 276751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 276851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 276951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte readByte() throws IOException { 277051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int v = read(); 277151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (v < 0) { 277251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new EOFException(); 277351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 277451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (byte) v; 277551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 277651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 277751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int readUnsignedByte() throws IOException { 277851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int v = read(); 277951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (v < 0) { 278051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new EOFException(); 278151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 278251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return v; 278351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 278451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 278551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public char readChar() throws IOException { 278651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 278751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 278851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, 2); 278951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 2) { 279051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return din.readChar(); 279151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 279251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char v = Bits.getChar(buf, pos); 279351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 2; 279451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return v; 279551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 279651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 279751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public short readShort() throws IOException { 279851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 279951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 280051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, 2); 280151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 2) { 280251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return din.readShort(); 280351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 280451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski short v = Bits.getShort(buf, pos); 280551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 2; 280651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return v; 280751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 280851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 280951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int readUnsignedShort() throws IOException { 281051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 281151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 281251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, 2); 281351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 2) { 281451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return din.readUnsignedShort(); 281551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 281651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int v = Bits.getShort(buf, pos) & 0xFFFF; 281751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 2; 281851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return v; 281951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 282051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 282151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int readInt() throws IOException { 282251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 282351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 282451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, 4); 282551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 4) { 282651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return din.readInt(); 282751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 282851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int v = Bits.getInt(buf, pos); 282951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 4; 283051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return v; 283151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 283251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 283351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public float readFloat() throws IOException { 283451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 283551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 283651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, 4); 283751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 4) { 283851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return din.readFloat(); 283951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 284051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski float v = Bits.getFloat(buf, pos); 284151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 4; 284251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return v; 284351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 284451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 284551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long readLong() throws IOException { 284651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 284751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 284851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, 8); 284951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 8) { 285051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return din.readLong(); 285151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 285251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long v = Bits.getLong(buf, pos); 285351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 8; 285451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return v; 285551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 285651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 285751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public double readDouble() throws IOException { 285851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 285951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 286051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, 8); 286151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 8) { 286251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return din.readDouble(); 286351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 286451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski double v = Bits.getDouble(buf, pos); 286551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 8; 286651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return v; 286751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 286851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 286951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String readUTF() throws IOException { 287051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readUTFBody(readUnsignedShort()); 287151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 287251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 287351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String readLine() throws IOException { 287451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return din.readLine(); // deprecated, not worth optimizing 287551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 287651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 287751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* -------------- primitive data array input methods --------------- */ 287851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 287951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The following methods read in spans of primitive data values. 288051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Though equivalent to calling the corresponding primitive read 288151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * methods repeatedly, these methods are optimized for reading groups 288251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of primitive data values more efficiently. 288351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 288451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 288551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void readBooleans(boolean[] v, int off, int len) throws IOException { 288651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int stop, endoff = off + len; 288751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < endoff) { 288851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 288951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int span = Math.min(endoff - off, MAX_BLOCK_SIZE); 289051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, span); 289151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = off + span; 289251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 289351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 1) { 289451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = din.readBoolean(); 289551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 289651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 289751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = Math.min(endoff, off + end - pos); 289851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 289951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 290051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < stop) { 290151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = Bits.getBoolean(buf, pos++); 290251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 290351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 290451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 290551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 290651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void readChars(char[] v, int off, int len) throws IOException { 290751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int stop, endoff = off + len; 290851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < endoff) { 290951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 291051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1); 291151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, span << 1); 291251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = off + span; 291351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 291451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 2) { 291551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = din.readChar(); 291651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 291751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 291851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = Math.min(endoff, off + ((end - pos) >> 1)); 291951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 292051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 292151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < stop) { 292251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = Bits.getChar(buf, pos); 292351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 2; 292451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 292551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 292651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 292751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 292851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void readShorts(short[] v, int off, int len) throws IOException { 292951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int stop, endoff = off + len; 293051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < endoff) { 293151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 293251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1); 293351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, span << 1); 293451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = off + span; 293551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 293651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 2) { 293751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = din.readShort(); 293851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 293951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 294051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = Math.min(endoff, off + ((end - pos) >> 1)); 294151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 294251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 294351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < stop) { 294451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = Bits.getShort(buf, pos); 294551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 2; 294651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 294751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 294851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 294951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 295051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void readInts(int[] v, int off, int len) throws IOException { 295151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int stop, endoff = off + len; 295251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < endoff) { 295351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 295451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2); 295551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, span << 2); 295651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = off + span; 295751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 295851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 4) { 295951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = din.readInt(); 296051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 296151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 296251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = Math.min(endoff, off + ((end - pos) >> 2)); 296351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 296451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 296551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < stop) { 296651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = Bits.getInt(buf, pos); 296751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 4; 296851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 296951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 297051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 297151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 297251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void readFloats(float[] v, int off, int len) throws IOException { 297351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int span, endoff = off + len; 297451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < endoff) { 297551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 297651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2); 297751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, span << 2); 297851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 297951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 4) { 298051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = din.readFloat(); 298151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 298251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 298351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski span = Math.min(endoff - off, ((end - pos) >> 2)); 298451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 298551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 298651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bytesToFloats(buf, pos, v, off, span); 298751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski off += span; 298851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += span << 2; 298951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 299051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 299151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 299251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void readLongs(long[] v, int off, int len) throws IOException { 299351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int stop, endoff = off + len; 299451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < endoff) { 299551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 299651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3); 299751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, span << 3); 299851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = off + span; 299951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 300051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 8) { 300151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = din.readLong(); 300251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 300351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 300451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = Math.min(endoff, off + ((end - pos) >> 3)); 300551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 300651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 300751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < stop) { 300851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = Bits.getLong(buf, pos); 300951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 8; 301051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 301151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 301251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 301351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 301451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void readDoubles(double[] v, int off, int len) throws IOException { 301551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int span, endoff = off + len; 301651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (off < endoff) { 301751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 301851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3); 301951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, 0, span << 3); 302051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 302151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (end - pos < 8) { 302251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v[off++] = din.readDouble(); 302351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 302451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 302551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski span = Math.min(endoff - off, ((end - pos) >> 3)); 302651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 302751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 302851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bytesToDoubles(buf, pos, v, off, span); 302951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski off += span; 303051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += span << 3; 303151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 303251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 303351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 303451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 303551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in string written in "long" UTF format. "Long" UTF format is 303651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * identical to standard UTF, except that it uses an 8 byte header 303751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (instead of the standard 2 bytes) to convey the UTF encoding length. 303851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 303951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String readLongUTF() throws IOException { 304051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readUTFBody(readLong()); 304151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 304251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 304351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 304451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in the "body" (i.e., the UTF representation minus the 2-byte 304551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or 8-byte length header) of a UTF encoding, which occupies the next 304651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * utflen bytes. 304751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 304851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String readUTFBody(long utflen) throws IOException { 304951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuilder sbuf = new StringBuilder(); 305051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!blkmode) { 305151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = pos = 0; 305251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 305351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 305451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (utflen > 0) { 305551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int avail = end - pos; 305651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (avail >= 3 || (long) avail == utflen) { 305751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski utflen -= readUTFSpan(sbuf, utflen); 305851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 305951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (blkmode) { 306051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // near block boundary, read one byte at a time 306151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski utflen -= readUTFChar(sbuf, utflen); 306251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 306351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // shift and refill buffer manually 306451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (avail > 0) { 306551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(buf, pos, buf, 0, avail); 306651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 306751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = 0; 306851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = (int) Math.min(MAX_BLOCK_SIZE, utflen); 306951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.readFully(buf, avail, end - avail); 307051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 307151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 307251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 307351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 307451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return sbuf.toString(); 307551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 307651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 307751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 307851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads span of UTF-encoded characters out of internal buffer 307951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (starting at offset pos and ending at or before offset end), 308051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * consuming no more than utflen bytes. Appends read characters to 308151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * sbuf. Returns the number of bytes consumed. 308251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 308351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private long readUTFSpan(StringBuilder sbuf, long utflen) 308451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 308551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 308651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int cpos = 0; 308751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int start = pos; 308851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int avail = Math.min(end - pos, CHAR_BUF_SIZE); 308951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // stop short of last char unless all of utf bytes in buffer 309051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int stop = pos + ((utflen > avail) ? avail - 2 : (int) utflen); 309151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean outOfBounds = false; 309251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 309351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 309451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (pos < stop) { 309551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int b1, b2, b3; 309651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b1 = buf[pos++] & 0xFF; 309751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (b1 >> 4) { 309851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 0: 309951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 1: 310051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 2: 310151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 3: 310251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 4: 310351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 5: 310451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 6: 310551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 7: // 1 byte format: 0xxxxxxx 310651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cbuf[cpos++] = (char) b1; 310751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 310851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 310951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 12: 311051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 13: // 2 byte format: 110xxxxx 10xxxxxx 311151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b2 = buf[pos++]; 311251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((b2 & 0xC0) != 0x80) { 311351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UTFDataFormatException(); 311451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 311551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cbuf[cpos++] = (char) (((b1 & 0x1F) << 6) | 311651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((b2 & 0x3F) << 0)); 311751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 311851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 311951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx 312051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b3 = buf[pos + 1]; 312151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b2 = buf[pos + 0]; 312251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += 2; 312351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) { 312451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UTFDataFormatException(); 312551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 312651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cbuf[cpos++] = (char) (((b1 & 0x0F) << 12) | 312751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((b2 & 0x3F) << 6) | 312851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((b3 & 0x3F) << 0)); 312951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 313051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 313151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: // 10xx xxxx, 1111 xxxx 313251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UTFDataFormatException(); 313351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 313451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 313551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ArrayIndexOutOfBoundsException ex) { 313651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski outOfBounds = true; 313751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 313851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (outOfBounds || (pos - start) > utflen) { 313951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 314051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Fix for 4450867: if a malformed utf char causes the 314151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * conversion loop to scan past the expected end of the utf 314251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * string, only consume the expected number of utf bytes. 314351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 314451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos = start + (int) utflen; 314551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UTFDataFormatException(); 314651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 314751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 314851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 314951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sbuf.append(cbuf, 0, cpos); 315051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return pos - start; 315151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 315251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 315351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 315451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads in single UTF-encoded character one byte at a time, appends 315551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the character to sbuf, and returns the number of bytes consumed. 315651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method is used when reading in UTF strings written in block 315751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * data mode to handle UTF-encoded characters which (potentially) 315851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * straddle block-data boundaries. 315951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 316051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int readUTFChar(StringBuilder sbuf, long utflen) 316151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 316251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 316351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int b1, b2, b3; 316451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b1 = readByte() & 0xFF; 316551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (b1 >> 4) { 316651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 0: 316751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 1: 316851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 2: 316951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 3: 317051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 4: 317151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 5: 317251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 6: 317351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 7: // 1 byte format: 0xxxxxxx 317451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sbuf.append((char) b1); 317551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 1; 317651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 317751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 12: 317851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 13: // 2 byte format: 110xxxxx 10xxxxxx 317951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (utflen < 2) { 318051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UTFDataFormatException(); 318151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 318251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b2 = readByte(); 318351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((b2 & 0xC0) != 0x80) { 318451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UTFDataFormatException(); 318551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 318651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sbuf.append((char) (((b1 & 0x1F) << 6) | 318751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((b2 & 0x3F) << 0))); 318851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 2; 318951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 319051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx 319151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (utflen < 3) { 319251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (utflen == 2) { 319351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readByte(); // consume remaining byte 319451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 319551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UTFDataFormatException(); 319651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 319751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b2 = readByte(); 319851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b3 = readByte(); 319951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) { 320051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UTFDataFormatException(); 320151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 320251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sbuf.append((char) (((b1 & 0x0F) << 12) | 320351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((b2 & 0x3F) << 6) | 320451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((b3 & 0x3F) << 0))); 320551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 3; 320651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 320751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: // 10xx xxxx, 1111 xxxx 320851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UTFDataFormatException(); 320951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 321051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 321151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 321251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 321351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 321451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Unsynchronized table which tracks wire handle to object mappings, as 321551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * well as ClassNotFoundExceptions associated with deserialized objects. 321651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class implements an exception-propagation algorithm for 321751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * determining which objects should have ClassNotFoundExceptions associated 321851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with them, taking into account cycles and discontinuities (e.g., skipped 321951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * fields) in the object graph. 322051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 322151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>General use of the table is as follows: during deserialization, a 322251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * given object is first assigned a handle by calling the assign method. 322351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method leaves the assigned handle in an "open" state, wherein 322451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * dependencies on the exception status of other handles can be registered 322551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by calling the markDependency method, or an exception can be directly 322651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * associated with the handle by calling markException. When a handle is 322751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * tagged with an exception, the HandleTable assumes responsibility for 322851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * propagating the exception to any other objects which depend 322951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (transitively) on the exception-tagged object. 323051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 323151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Once all exception information/dependencies for the handle have been 323251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * registered, the handle should be "closed" by calling the finish method 323351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on it. The act of finishing a handle allows the exception propagation 323451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * algorithm to aggressively prune dependency links, lessening the 323551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * performance/memory impact of exception tracking. 323651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 323751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Note that the exception propagation algorithm used depends on handles 323851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * being assigned/finished in LIFO order; however, for simplicity as well 323951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as memory conservation, it does not enforce this constraint. 324051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 324151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // REMIND: add full description of exception propagation algorithm? 324251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class HandleTable { 324351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 324451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* status codes indicating whether object has associated exception */ 324551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final byte STATUS_OK = 1; 324651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final byte STATUS_UNKNOWN = 2; 324751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final byte STATUS_EXCEPTION = 3; 324851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 324951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** array mapping handle -> object status */ 325051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] status; 325151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** array mapping handle -> object/exception (depending on status) */ 325251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object[] entries; 325351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** array mapping handle -> list of dependent handles (if any) */ 325451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HandleList[] deps; 325551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** lowest unresolved dependency */ 325651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lowDep = -1; 325751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** number of handles in table */ 325851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int size = 0; 325951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 326051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 326151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates handle table with the given initial capacity. 326251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 326351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HandleTable(int initialCapacity) { 326451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski status = new byte[initialCapacity]; 326551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entries = new Object[initialCapacity]; 326651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski deps = new HandleList[initialCapacity]; 326751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 326851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 326951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 327051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Assigns next available handle to given object, and returns assigned 327151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * handle. Once object has been completely deserialized (and all 327251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * dependencies on other objects identified), the handle should be 327351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "closed" by passing it to finish(). 327451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 327551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int assign(Object obj) { 327651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (size >= entries.length) { 327751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski grow(); 327851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 327951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski status[size] = STATUS_UNKNOWN; 328051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entries[size] = obj; 328151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return size++; 328251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 328351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 328451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 328551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Registers a dependency (in exception status) of one handle on 328651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * another. The dependent handle must be "open" (i.e., assigned, but 328751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not finished yet). No action is taken if either dependent or target 328851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * handle is NULL_HANDLE. 328951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 329051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void markDependency(int dependent, int target) { 329151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (dependent == NULL_HANDLE || target == NULL_HANDLE) { 329251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 329351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 329451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (status[dependent]) { 329551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 329651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_UNKNOWN: 329751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (status[target]) { 329851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_OK: 329951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ignore dependencies on objs with no exception 330051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 330151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 330251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_EXCEPTION: 330351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // eagerly propagate exception 330451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski markException(dependent, 330551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (ClassNotFoundException) entries[target]); 330651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 330751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 330851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_UNKNOWN: 330951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add to dependency list of target 331051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (deps[target] == null) { 331151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski deps[target] = new HandleList(); 331251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 331351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski deps[target].add(dependent); 331451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 331551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // remember lowest unresolved target seen 331651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (lowDep < 0 || lowDep > target) { 331751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lowDep = target; 331851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 331951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 332051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 332151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 332251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 332351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 332451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 332551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 332651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_EXCEPTION: 332751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 332851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 332951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 333051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 333151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 333251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 333351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 333451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 333551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Associates a ClassNotFoundException (if one not already associated) 333651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with the currently active handle and propagates it to other 333751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * referencing objects as appropriate. The specified handle must be 333851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "open" (i.e., assigned, but not finished yet). 333951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 334051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void markException(int handle, ClassNotFoundException ex) { 334151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (status[handle]) { 334251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_UNKNOWN: 334351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski status[handle] = STATUS_EXCEPTION; 334451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entries[handle] = ex; 334551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 334651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // propagate exception to dependents 334751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HandleList dlist = deps[handle]; 334851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (dlist != null) { 334951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ndeps = dlist.size(); 335051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < ndeps; i++) { 335151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski markException(dlist.get(i), ex); 335251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 335351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski deps[handle] = null; 335451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 335551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 335651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 335751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_EXCEPTION: 335851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 335951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 336051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 336151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 336251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 336351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 336451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 336551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 336651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Marks given handle as finished, meaning that no new dependencies 336751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * will be marked for handle. Calls to the assign and finish methods 336851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * must occur in LIFO order. 336951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 337051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void finish(int handle) { 337151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int end; 337251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (lowDep < 0) { 337351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // no pending unknowns, only resolve current handle 337451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = handle + 1; 337551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (lowDep >= handle) { 337651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // pending unknowns now clearable, resolve all upward handles 337751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end = size; 337851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lowDep = -1; 337951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 338051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // unresolved backrefs present, can't resolve anything yet 338151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 338251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 338351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 338451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // change STATUS_UNKNOWN -> STATUS_OK in selected span of handles 338551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = handle; i < end; i++) { 338651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (status[i]) { 338751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_UNKNOWN: 338851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski status[i] = STATUS_OK; 338951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski deps[i] = null; 339051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 339151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 339251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_OK: 339351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_EXCEPTION: 339451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 339551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 339651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 339751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 339851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 339951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 340051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 340151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 340251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 340351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Assigns a new object to the given handle. The object previously 340451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * associated with the handle is forgotten. This method has no effect 340551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if the given handle already has an exception associated with it. 340651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method may be called at any time after the handle is assigned. 340751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 340851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void setObject(int handle, Object obj) { 340951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (status[handle]) { 341051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_UNKNOWN: 341151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_OK: 341251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entries[handle] = obj; 341351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 341451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 341551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case STATUS_EXCEPTION: 341651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 341751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 341851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 341951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 342051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 342151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 342251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 342351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 342451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Looks up and returns object associated with the given handle. 342551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns null if the given handle is NULL_HANDLE, or if it has an 342651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * associated ClassNotFoundException. 342751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 342851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object lookupObject(int handle) { 342951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (handle != NULL_HANDLE && 343051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski status[handle] != STATUS_EXCEPTION) ? 343151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entries[handle] : null; 343251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 343351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 343451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 343551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Looks up and returns ClassNotFoundException associated with the 343651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * given handle. Returns null if the given handle is NULL_HANDLE, or 343751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if there is no ClassNotFoundException associated with the handle. 343851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 343951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassNotFoundException lookupException(int handle) { 344051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (handle != NULL_HANDLE && 344151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski status[handle] == STATUS_EXCEPTION) ? 344251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (ClassNotFoundException) entries[handle] : null; 344351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 344451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 344551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 344651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Resets table to its initial state. 344751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 344851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void clear() { 344951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Arrays.fill(status, 0, size, (byte) 0); 345051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Arrays.fill(entries, 0, size, null); 345151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Arrays.fill(deps, 0, size, null); 345251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lowDep = -1; 345351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size = 0; 345451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 345551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 345651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 345751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns number of handles registered in table. 345851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 345951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int size() { 346051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return size; 346151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 346251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 346351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 346451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Expands capacity of internal arrays. 346551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 346651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void grow() { 346751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int newCapacity = (entries.length << 1) + 1; 346851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 346951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] newStatus = new byte[newCapacity]; 347051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object[] newEntries = new Object[newCapacity]; 347151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HandleList[] newDeps = new HandleList[newCapacity]; 347251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 347351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(status, 0, newStatus, 0, size); 347451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(entries, 0, newEntries, 0, size); 347551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(deps, 0, newDeps, 0, size); 347651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 347751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski status = newStatus; 347851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entries = newEntries; 347951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski deps = newDeps; 348051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 348151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 348251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 348351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Simple growable list of (integer) handles. 348451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 348551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class HandleList { 348651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int[] list = new int[4]; 348751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int size = 0; 348851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 348951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public HandleList() { 349051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 349151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 349251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void add(int handle) { 349351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (size >= list.length) { 349451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int[] newList = new int[list.length << 1]; 349551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(list, 0, newList, 0, list.length); 349651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list = newList; 349751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 349851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list[size++] = handle; 349951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 350051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 350151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int get(int index) { 350251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (index >= size) { 350351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ArrayIndexOutOfBoundsException(); 350451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 350551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return list[index]; 350651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 350751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 350851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int size() { 350951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return size; 351051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 351151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 351251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 351351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 351451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 351551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Method for cloning arrays in case of using unsharing reading 351651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 351751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static Object cloneArray(Object array) { 351851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (array instanceof Object[]) { 351951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((Object[]) array).clone(); 352051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (array instanceof boolean[]) { 352151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((boolean[]) array).clone(); 352251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (array instanceof byte[]) { 352351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((byte[]) array).clone(); 352451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (array instanceof char[]) { 352551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((char[]) array).clone(); 352651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (array instanceof double[]) { 352751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((double[]) array).clone(); 352851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (array instanceof float[]) { 352951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((float[]) array).clone(); 353051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (array instanceof int[]) { 353151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((int[]) array).clone(); 353251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (array instanceof long[]) { 353351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((long[]) array).clone(); 353451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (array instanceof short[]) { 353551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((short[]) array).clone(); 353651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 353751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new AssertionError(); 353851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 353951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 354051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 354151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 3542