ObjectInputStream.java revision f5597e626ecf7949d249dea08c1a2964d890ec11
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.io;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// BEGIN android-note
21f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// Harmony uses ObjectAccessors to access fields through JNI. Android has not
22f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// yet migrated that API. As a consequence, there's a lot of changes here...
23f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// END android-note
24f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.EmulatedFields.ObjectSlot;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Array;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Constructor;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.InvocationTargetException;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Method;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Modifier;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Proxy;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessController;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.PrivilegedAction;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList;
35f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport java.util.HashMap;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-added
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport dalvik.system.VMStack;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-added
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
42f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// BEGIN android-removed
43f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// import org.apache.harmony.misc.accessors.ObjectAccessor;
44f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// import org.apache.harmony.misc.accessors.AccessorFactory;
45f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// END android-removed
46f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
47f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport org.apache.harmony.kernel.vm.VM;
48f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport org.apache.harmony.luni.internal.nls.Messages;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Msg;
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.PriviAction;
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A specialized {@link InputStream} that is able to read (deserialize) Java
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * objects as well as primitive data types (int, byte, char etc.). The data has
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * typically been saved using an ObjectOutputStream.
56f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectInput
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Serializable
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Externalizable
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ObjectInputStream extends InputStream implements ObjectInput,
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamConstants {
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
65f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // BEGIN android-note
66f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // this is non-static to avoid sync contention. Would static be faster?
67f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // END android-note
68f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private InputStream emptyStream = new ByteArrayInputStream(
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new byte[0]);
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // To put into objectsRead when reading unsharedObject
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final Object UNSHARED_OBJ = new Object(); // $NON-LOCK-1$
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // If the receiver has already read & not consumed a TC code
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean hasPushbackTC;
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Push back TC code if the variable above is true
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte pushbackTC;
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // How many nested levels to readObject. When we reach 0 we have to validate
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // the graph then reset it
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int nestedLevels;
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // All objects are assigned an ID (integer handle)
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int currentHandle;
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Where we read from
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private DataInputStream input;
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Where we read primitive types from
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private DataInputStream primitiveTypes;
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Where we keep primitive type data
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private InputStream primitiveData = emptyStream;
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Resolve object is a mechanism for replacement
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean enableResolve;
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Table mapping Integer (handle) -> Object
100f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private HashMap<Integer, Object> objectsRead;
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Used by defaultReadObject
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object currentObject;
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Used by defaultReadObject
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ObjectStreamClass currentClass;
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // All validations to be executed when the complete graph is read. See inner
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // type below.
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private InputValidationDesc[] validations;
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Allows the receiver to decide if it needs to call readObjectOverride
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean subclassOverridingImplementation;
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Original caller's class loader, used to perform class lookups
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ClassLoader callerClassLoader;
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // false when reading missing fields
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean mustResolve = true;
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Handle for the current class descriptor
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Integer descriptorHandle;
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
124f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private static final HashMap<String, Class<?>> PRIMITIVE_CLASSES =
125f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        new HashMap<String, Class<?>>();
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static {
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PRIMITIVE_CLASSES.put("byte", byte.class); //$NON-NLS-1$
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PRIMITIVE_CLASSES.put("short", short.class); //$NON-NLS-1$
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PRIMITIVE_CLASSES.put("int", int.class); //$NON-NLS-1$
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PRIMITIVE_CLASSES.put("long", long.class); //$NON-NLS-1$
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PRIMITIVE_CLASSES.put("boolean", boolean.class); //$NON-NLS-1$
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PRIMITIVE_CLASSES.put("char", char.class); //$NON-NLS-1$
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PRIMITIVE_CLASSES.put("float", float.class); //$NON-NLS-1$
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PRIMITIVE_CLASSES.put("double", double.class); //$NON-NLS-1$
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
138f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // BEGIN android-removed
139f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // private ObjectAccessor accessor = AccessorFactory.getObjectAccessor();
140f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // END android-removed
141f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Internal type used to keep track of validators & corresponding priority
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static class InputValidationDesc {
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectInputValidation validator;
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int priority;
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * GetField is an inner class that provides access to the persistent fields
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * read from the source stream.
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract static class GetField {
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the ObjectStreamClass that describes a field.
156f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the descriptor class for a serialized field.
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract ObjectStreamClass getObjectStreamClass();
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Indicates if the field identified by {@code name} is defaulted. This
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * means that it has no value in this stream.
164f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to check.
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return {@code true} if the field is defaulted, {@code false}
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         otherwise.
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code name} does not identify a serializable field.
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract boolean defaulted(String name) throws IOException,
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                IllegalArgumentException;
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the value of the boolean field identified by {@code name} from
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * the persistent field.
181f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to get.
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param defaultValue
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the default value that is used if the field does not have
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            a value when read from the source stream.
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the field identified by {@code name}.
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the type of the field identified by {@code name} is
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             not {@code boolean}.
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract boolean get(String name, boolean defaultValue)
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws IOException, IllegalArgumentException;
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the value of the character field identified by {@code name} from
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * the persistent field.
201f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to get.
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param defaultValue
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the default value that is used if the field does not have
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            a value when read from the source stream.
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the field identified by {@code name}.
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the type of the field identified by {@code name} is
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             not {@code char}.
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract char get(String name, char defaultValue)
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws IOException, IllegalArgumentException;
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the value of the byte field identified by {@code name} from the
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * persistent field.
221f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to get.
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param defaultValue
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the default value that is used if the field does not have
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            a value when read from the source stream.
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the field identified by {@code name}.
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the type of the field identified by {@code name} is
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             not {@code byte}.
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract byte get(String name, byte defaultValue)
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws IOException, IllegalArgumentException;
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the value of the short field identified by {@code name} from the
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * persistent field.
241f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to get.
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param defaultValue
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the default value that is used if the field does not have
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            a value when read from the source stream.
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the field identified by {@code name}.
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the type of the field identified by {@code name} is
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             not {@code short}.
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract short get(String name, short defaultValue)
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws IOException, IllegalArgumentException;
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the value of the integer field identified by {@code name} from
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * the persistent field.
261f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to get.
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param defaultValue
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the default value that is used if the field does not have
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            a value when read from the source stream.
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the field identified by {@code name}.
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the type of the field identified by {@code name} is
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             not {@code int}.
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract int get(String name, int defaultValue)
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws IOException, IllegalArgumentException;
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
278f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        /**
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the value of the long field identified by {@code name} from the
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * persistent field.
281f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to get.
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param defaultValue
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the default value that is used if the field does not have
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            a value when read from the source stream.
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the field identified by {@code name}.
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the type of the field identified by {@code name} is
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             not {@code long}.
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract long get(String name, long defaultValue)
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws IOException, IllegalArgumentException;
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the value of the float field identified by {@code name} from the
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * persistent field.
301f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to get.
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param defaultValue
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the default value that is used if the field does not have
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            a value when read from the source stream.
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the field identified by {@code name}.
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the type of the field identified by {@code float} is
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             not {@code char}.
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract float get(String name, float defaultValue)
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws IOException, IllegalArgumentException;
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the value of the double field identified by {@code name} from
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * the persistent field.
321f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to get.
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param defaultValue
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the default value that is used if the field does not have
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            a value when read from the source stream.
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the field identified by {@code name}.
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the type of the field identified by {@code name} is
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             not {@code double}.
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract double get(String name, double defaultValue)
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws IOException, IllegalArgumentException;
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Gets the value of the object field identified by {@code name} from
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * the persistent field.
341f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         *
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the field to get.
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param defaultValue
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the default value that is used if the field does not have
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            a value when read from the source stream.
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the field identified by {@code name}.
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IOException
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurs while reading from the source input
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             stream.
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the type of the field identified by {@code name} is
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             not {@code Object}.
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract Object get(String name, Object defaultValue)
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws IOException, IllegalArgumentException;
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new ObjectInputStream. This default constructor can be used
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * by subclasses that do not want to use the public constructor if it
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * allocates unneeded data.
363f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs when creating this stream.
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager is installed and it denies subclassing
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             this class.
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SecurityManager#checkPermission(java.security.Permission)
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected ObjectInputStream() throws IOException, SecurityException {
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super();
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager currentManager = System.getSecurityManager();
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (currentManager != null) {
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            currentManager.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // WARNING - we should throw IOException if not called from a subclass
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // according to the JavaDoc. Add the test.
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.subclassOverridingImplementation = true;
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new ObjectInputStream that reads from the InputStream
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code input}.
385f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the non-null source InputStream to filter reads on.
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the stream header.
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws StreamCorruptedException
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the source stream does not contain serialized objects that
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             can be read.
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager is installed and it denies subclassing
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             this class.
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ObjectInputStream(InputStream input)
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws StreamCorruptedException, IOException {
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final Class<?> implementationClass = getClass();
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final Class<?> thisClass = ObjectInputStream.class;
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager sm = System.getSecurityManager();
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (sm != null && implementationClass != thisClass) {
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            boolean mustCheck = (AccessController
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .doPrivileged(new PrivilegedAction<Boolean>() {
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        public Boolean run() {
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            try {
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                Method method = implementationClass
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                        .getMethod(
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                                "readFields", //$NON-NLS-1$
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                                ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                if (method.getDeclaringClass() != thisClass) {
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    return Boolean.TRUE;
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                }
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            } catch (NoSuchMethodException e) {
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            }
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            try {
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                Method method = implementationClass
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                        .getMethod(
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                                "readUnshared", //$NON-NLS-1$
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                                ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                if (method.getDeclaringClass() != thisClass) {
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    return Boolean.TRUE;
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                }
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            } catch (NoSuchMethodException e) {
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            }
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return Boolean.FALSE;
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    })).booleanValue();
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (mustCheck) {
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                sm
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .checkPermission(ObjectStreamConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.input = (input instanceof DataInputStream) ? (DataInputStream) input
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : new DataInputStream(input);
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveTypes = new DataInputStream(this);
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        enableResolve = false;
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.subclassOverridingImplementation = false;
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        resetState();
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nestedLevels = 0;
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // So read...() methods can be used by
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // subclasses during readStreamHeader()
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveData = this.input;
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Has to be done here according to the specification
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        readStreamHeader();
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveData = emptyStream;
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the number of bytes of primitive data that can be read from this
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * stream without blocking. This method should not be used at any arbitrary
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * position; just when reading primitive data types (int, char etc).
453f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of available primitive data bytes.
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if any I/O problem occurs while computing the available
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             bytes.
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int available() throws IOException {
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // returns 0 if next data is an object, or N if reading primitive types
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkReadPrimitiveTypes();
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveData.available();
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks to if it is ok to read primitive types from this stream at
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this point. One is not supposed to read primitive types when about to
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * read an object, for example, so an exception has to be thrown.
470f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If any IO problem occurred when trying to read primitive type
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             or if it is illegal to read primitive types
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkReadPrimitiveTypes() throws IOException {
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If we still have primitive data, it is ok to read primitive data
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (primitiveData == input || primitiveData.available() > 0) {
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If we got here either we had no Stream previously created or
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // we no longer have data in that one, so get more bytes
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        do {
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int next = 0;
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (hasPushbackTC) {
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                hasPushbackTC = false;
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                next = input.read();
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                pushbackTC = (byte) next;
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            switch (pushbackTC) {
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_BLOCKDATA:
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    primitiveData = new ByteArrayInputStream(readBlockData());
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return;
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_BLOCKDATALONG:
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    primitiveData = new ByteArrayInputStream(
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            readBlockDataLong());
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return;
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_RESET:
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    resetState();
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                default:
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (next != -1) {
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        pushbackTC();
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return;
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Only TC_RESET falls through
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } while (true);
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes this stream. This implementation closes the source stream.
514f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing this stream.
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void close() throws IOException {
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        input.close();
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Default method to read objects from this stream. Serializable fields
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * defined in the object's class and superclasses are read from the source
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * stream.
527f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the object's class cannot be found.
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an I/O error occurs while reading the object data.
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NotActiveException
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this method is not called from {@code readObject()}.
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectOutputStream#defaultWriteObject
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void defaultReadObject() throws IOException, ClassNotFoundException,
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            NotActiveException {
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We can't be called from just anywhere. There are rules.
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (currentObject != null || !mustResolve) {
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            readFieldValues(currentObject, currentClass);
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NotActiveException();
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Enables object replacement for this stream. By default this is not
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * enabled. Only trusted subclasses (loaded with system class loader) are
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * allowed to change this status.
550f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param enable
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code true} to enable object replacement; {@code false} to
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            disable it.
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the previous setting.
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager is installed and it denies enabling
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             object replacement for this stream.
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #resolveObject
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectOutputStream#enableReplaceObject
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected boolean enableResolveObject(boolean enable)
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws SecurityException {
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (enable) {
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // The Stream has to be trusted for this feature to be enabled.
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // trusted means the stream's classloader has to be null
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            SecurityManager currentManager = System.getSecurityManager();
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (currentManager != null) {
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                currentManager.checkPermission(SUBSTITUTION_PERMISSION);
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean originalValue = enableResolve;
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        enableResolve = enable;
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return originalValue;
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks if two classes belong to the same package.
578f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param c1
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            one of the classes to test.
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param c2
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the other class to test.
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the two classes belong to the same package,
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean inSamePackage(Class<?> c1, Class<?> c2) {
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String nameC1 = c1.getName();
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String nameC2 = c2.getName();
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int indexDotC1 = nameC1.lastIndexOf('.');
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int indexDotC2 = nameC2.lastIndexOf('.');
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (indexDotC1 != indexDotC2) {
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false; // cannot be in the same package if indices are not
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // the same
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (indexDotC1 < 0) {
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true; // both of them are in default package
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return nameC1.substring(0, indexDotC1).equals(
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                nameC2.substring(0, indexDotC2));
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
602f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // BEGIN android-added
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Create and return a new instance of class {@code instantiationClass}
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * but running the constructor defined in class
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code constructorClass} (same as {@code instantiationClass}
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * or a superclass).
608f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Has to be native to avoid visibility rules and to be able to have
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code instantiationClass} not the same as
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code constructorClass} (no such API in java.lang.reflect).
612f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param instantiationClass
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            The new object will be an instance of this class
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param constructorClass
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            The empty constructor to run will be in this class
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the object created from {@code instantiationClass}
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native Object newInstance(Class<?> instantiationClass,
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> constructorClass);
621f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // END android-added
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Return the next {@code int} handle to be used to indicate cyclic
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * references being loaded from the stream.
626f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the next handle to represent the next cyclic reference
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
629f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private Integer nextHandle() {
630f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return Integer.valueOf(this.currentHandle++);
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Return the next token code (TC) from the receiver, which indicates what
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * kind of object follows
636f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the next TC from the receiver
638f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO error occurs
641f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectStreamConstants
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte nextTC() throws IOException {
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (hasPushbackTC) {
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hasPushbackTC = false; // We are consuming it
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Just in case a later call decides to really push it back,
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // we don't require the caller to pass it as parameter
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            pushbackTC = input.readByte();
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return pushbackTC;
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Pushes back the last TC code read
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void pushbackTC() {
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        hasPushbackTC = true;
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a single byte from the source stream and returns it as an integer
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in the range from 0 to 255. Returns -1 if the end of the source stream
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * has been reached. Blocks if no input is available.
666f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the byte read or -1 if the end of the source stream has been
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         reached.
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from this stream.
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int read() throws IOException {
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkReadPrimitiveTypes();
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveData.read();
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads at most {@code length} bytes from the source stream and stores them
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in byte array {@code buffer} starting at offset {@code count}. Blocks
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * until {@code count} bytes have been read, the end of the source stream is
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * detected or an exception is thrown.
683f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param buffer
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the array in which to store the bytes read.
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the initial position in {@code buffer} to store the bytes
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            read from the source stream.
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param length
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the maximum number of bytes to store in {@code buffer}.
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of bytes read or -1 if the end of the source input
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         stream has been reached.
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset < 0} or {@code length < 0}, or if
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code offset + length} is greater than the length of
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code buffer}.
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from this stream.
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code buffer} is {@code null}.
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int read(byte[] buffer, int offset, int length) throws IOException {
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-changed
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (buffer == null) {
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // avoid int overflow
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Exception priorities (in case of multiple errors) differ from
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // RI, but are spec-compliant.
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // removed redundant check, used (offset | length) < 0 instead of
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // (offset < 0) || (length < 0) to safe one operation
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((offset | length) < 0 || length > buffer.length - offset) {
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-changed
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (length == 0) {
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkReadPrimitiveTypes();
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveData.read(buffer, offset, length);
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads and returns an array of raw bytes with primitive data. The array
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * will have up to 255 bytes. The primitive data will be in the format
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * described by {@code DataOutputStream}.
728f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return The primitive data read, as raw bytes
730f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the primitive data.
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] readBlockData() throws IOException {
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] result = new byte[input.readByte() & 0xff];
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        input.readFully(result);
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads and returns an array of raw bytes with primitive data. The array
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * will have more than 255 bytes. The primitive data will be in the format
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * described by {@code DataOutputStream}.
744f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return The primitive data read, as raw bytes
746f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the primitive data.
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] readBlockDataLong() throws IOException {
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] result = new byte[input.readInt()];
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        input.readFully(result);
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a boolean from the source stream.
758f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the boolean value read from the source stream.
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean readBoolean() throws IOException {
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readBoolean();
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a byte (8 bit) from the source stream.
772f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the byte value read from the source stream.
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte readByte() throws IOException {
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readByte();
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a character (16 bit) from the source stream.
786f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the char value read from the source stream.
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public char readChar() throws IOException {
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readChar();
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads and discards block data and objects until TC_ENDBLOCKDATA is found.
800f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the optional class
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             annotation.
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If the class corresponding to the class descriptor could not
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             be found.
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void discardData() throws ClassNotFoundException, IOException {
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveData = emptyStream;
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean resolve = mustResolve;
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mustResolve = false;
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        do {
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            byte tc = nextTC();
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (tc == TC_ENDBLOCKDATA) {
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                mustResolve = resolve;
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return; // End of annotation
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            readContent(tc);
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } while (true);
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a class descriptor (an {@code ObjectStreamClass}) from the
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * stream.
825f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the class descriptor read from the stream
827f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the class
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             descriptor.
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If the class corresponding to the class descriptor could not
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             be found.
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ObjectStreamClass readClassDesc() throws ClassNotFoundException,
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            IOException {
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte tc = nextTC();
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (tc) {
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_CLASSDESC:
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readNewClassDesc(false);
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_PROXYCLASSDESC:
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Class<?> proxyClass = readNewProxyClassDesc();
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ObjectStreamClass streamClass = ObjectStreamClass
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .lookup(proxyClass);
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                streamClass.setLoadFields(new ObjectStreamField[0]);
846f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                registerObjectRead(streamClass, nextHandle(), false);
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                checkedSetSuperClassDesc(streamClass, readClassDesc());
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return streamClass;
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_REFERENCE:
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return (ObjectStreamClass) readCyclicReference();
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_NULL:
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return null;
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new StreamCorruptedException(Msg.getString(
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        "K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads the content of the receiver based on the previously read token
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code tc}.
862f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param tc
864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            The token code for the next item in the stream
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the object read from the stream
866f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the class
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             descriptor.
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If the class corresponding to the object being read could not
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             be found.
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readContent(byte tc) throws ClassNotFoundException,
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            IOException {
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (tc) {
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_BLOCKDATA:
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readBlockData();
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_BLOCKDATALONG:
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readBlockDataLong();
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_CLASS:
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readNewClass(false);
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_CLASSDESC:
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readNewClassDesc(false);
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_ARRAY:
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readNewArray(false);
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_OBJECT:
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readNewObject(false);
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_STRING:
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readNewString(false);
891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_LONGSTRING:
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readNewLongString(false);
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_REFERENCE:
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readCyclicReference();
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_NULL:
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return null;
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_EXCEPTION:
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Exception exc = readException();
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new WriteAbortedException(Msg.getString("K00d3"), exc); //$NON-NLS-1$
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_RESET:
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                resetState();
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return null;
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new StreamCorruptedException(Msg.getString(
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        "K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads the content of the receiver based on the previously read token
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code tc}. Primitive data content is considered an error.
912f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unshared
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            read the object unshared
915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the object read from the stream
916f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the class
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             descriptor.
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If the class corresponding to the object being read could not
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             be found.
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readNonPrimitiveContent(boolean unshared)
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws ClassNotFoundException, IOException {
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkReadPrimitiveTypes();
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (primitiveData.available() > 0) {
928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            OptionalDataException e = new OptionalDataException();
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            e.length = primitiveData.available();
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw e;
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        do {
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            byte tc = nextTC();
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            switch (tc) {
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_CLASS:
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return readNewClass(unshared);
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_CLASSDESC:
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return readNewClassDesc(unshared);
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_ARRAY:
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return readNewArray(unshared);
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_OBJECT:
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return readNewObject(unshared);
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_STRING:
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return readNewString(unshared);
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_LONGSTRING:
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return readNewLongString(unshared);
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_ENUM:
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return readEnum(unshared);
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_REFERENCE:
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (unshared) {
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        readNewHandle();
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw new InvalidObjectException(Msg.getString("KA002")); //$NON-NLS-1$
954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return readCyclicReference();
956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_NULL:
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return null;
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_EXCEPTION:
959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Exception exc = readException();
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new WriteAbortedException(Msg.getString("K00d3"), exc); //$NON-NLS-1$
961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_RESET:
962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    resetState();
963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case TC_ENDBLOCKDATA: // Can occur reading class annotation
965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    pushbackTC();
966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    OptionalDataException e = new OptionalDataException();
967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    e.eof = true;
968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw e;
969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                default:
970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new StreamCorruptedException(Msg.getString(
971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            "K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Only TC_RESET falls through
974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } while (true);
975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads the next item from the stream assuming it is a cyclic reference to
979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * an object previously read. Return the actual object previously read.
980f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the object previously read from the stream
982f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the class
985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             descriptor.
986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InvalidObjectException
987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If the cyclic reference is not valid.
988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readCyclicReference() throws InvalidObjectException,
990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            IOException {
991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return registeredObjectRead(readNewHandle());
992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a double (64 bit) from the source stream.
996f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the double value read from the source stream.
998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public double readDouble() throws IOException {
1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readDouble();
1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Read the next item assuming it is an exception. The exception is not a
1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * regular instance in the object graph, but the exception instance that
1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * happened (if any) when dumping the original object graph. The set of seen
1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * objects will be reset just before and just after loading this exception
1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * object.
1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * When exceptions are found normally in the object graph, they are loaded
1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as a regular object, and not by this method. In that case, the set of
1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * "known objects" is not reset.
1018f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the exception read
1020f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the exception
1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             object.
1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If a class could not be found when reading the object graph
1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             for the exception
1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws OptionalDataException
1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If optional data could not be found when reading the
1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             exception graph
1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws WriteAbortedException
1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If another exception was caused when dumping this exception
1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Exception readException() throws WriteAbortedException,
1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            OptionalDataException, ClassNotFoundException, IOException {
1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        resetSeenObjects();
1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Now we read the Throwable object that was saved
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // WARNING - the grammar says it is a Throwable, but the
1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // WriteAbortedException constructor takes an Exception. So, we read an
1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Exception from the stream
1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Exception exc = (Exception) readObject();
1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We reset the receiver's state (the grammar has "reset" in normal
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // font)
1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        resetSeenObjects();
1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return exc;
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a collection of field descriptors (name, type name, etc) for the
1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * class descriptor {@code cDesc} (an {@code ObjectStreamClass})
1053f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param cDesc
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            The class descriptor (an {@code ObjectStreamClass})
1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            for which to write field information
1057f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the field
1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             descriptors.
1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If a class for one of the field types could not be found
1063f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #readObject()
1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readFieldDescriptors(ObjectStreamClass cDesc)
1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws ClassNotFoundException, IOException {
1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        short numFields = input.readShort();
1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamField[] fields = new ObjectStreamField[numFields];
1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We set it now, but each element will be inserted in the array further
1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // down
1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        cDesc.setLoadFields(fields);
1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Check ObjectOutputStream.writeFieldDescriptors
1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (short i = 0; i < numFields; i++) {
1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            char typecode = (char) input.readByte();
1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String fieldName = input.readUTF();
1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            boolean isPrimType = ObjectStreamClass.isPrimitiveType(typecode);
1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String classSig;
1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (isPrimType) {
1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                classSig = String.valueOf(typecode);
1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // The spec says it is a UTF, but experience shows they dump
1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // this String using writeObject (unlike the field name, which
1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // is saved with writeUTF).
1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // And if resolveObject is enabled, the classSig may be modified
1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // so that the original class descriptor cannot be read
1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // properly, so it is disabled.
1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                boolean old = enableResolve;
1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    enableResolve = false;
1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    classSig = (String) readObject();
1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } finally {
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    enableResolve = old;
1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1098f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1099f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            classSig = formatClassSig(classSig);
1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ObjectStreamField f = new ObjectStreamField(classSig, fieldName);
1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fields[i] = f;
1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1105f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    /*
1106f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Format the class signature for ObjectStreamField, for example,
1107f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * "[L[Ljava.lang.String;;" is converted to "[Ljava.lang.String;"
1108f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     */
1109f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private static String formatClassSig(String classSig) {
1110f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int start = 0;
1111f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int end = classSig.length();
1112f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1113f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (end <= 0) {
1114f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return classSig;
1115f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
1116f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1117f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        while (classSig.startsWith("[L", start) //$NON-NLS-1$
1118f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                && classSig.charAt(end - 1) == ';') {
1119f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            start += 2;
1120f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            end--;
1121f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
1122f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1123f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (start > 0) {
1124f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            start -= 2;
1125f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            end++;
1126f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return classSig.substring(start, end);
1127f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
1128f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return classSig;
1129f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
1130f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads the persistent fields of the object that is currently being read
1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * from the source stream. The values read are stored in a GetField object
1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * that provides access to the persistent fields. This GetField object is
1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then returned.
1136f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the GetField object from which persistent fields can be accessed
1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         by name.
1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the class of an object being deserialized can not be
1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             found.
1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from this stream.
1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NotActiveException
1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this stream is currently not reading an object.
1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GetField readFields() throws IOException, ClassNotFoundException,
1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            NotActiveException {
1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We can't be called from just anywhere. There are rules.
1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (currentObject == null) {
1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NotActiveException();
1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        EmulatedFieldsForLoading result = new EmulatedFieldsForLoading(
1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                currentClass);
1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        readFieldValues(result);
1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a collection of field values for the emulated fields
1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code emulatedFields}
1162f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param emulatedFields
1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            an {@code EmulatedFieldsForLoading}, concrete subclass
1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            of {@code GetField}
1166f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the field values.
1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InvalidClassException
1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an incompatible type is being assigned to an emulated
1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             field.
1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws OptionalDataException
1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If optional data could not be found when reading the
1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             exception graph
1175f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #readFields
1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #readObject()
1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readFieldValues(EmulatedFieldsForLoading emulatedFields)
1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws OptionalDataException, InvalidClassException, IOException {
1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        EmulatedFields.ObjectSlot[] slots = emulatedFields.emulatedFields()
1182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .slots();
1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (ObjectSlot element : slots) {
1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            element.defaulted = false;
1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> type = element.field.getType();
1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (type == Integer.TYPE) {
1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                element.fieldValue = Integer.valueOf(input.readInt());
1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (type == Byte.TYPE) {
1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                element.fieldValue = Byte.valueOf(input.readByte());
1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (type == Character.TYPE) {
1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                element.fieldValue = Character.valueOf(input.readChar());
1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (type == Short.TYPE) {
1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                element.fieldValue = Short.valueOf(input.readShort());
1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (type == Boolean.TYPE) {
1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                element.fieldValue = Boolean.valueOf(input.readBoolean());
1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (type == Long.TYPE) {
1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                element.fieldValue = Long.valueOf(input.readLong());
1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (type == Float.TYPE) {
1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                element.fieldValue = Float.valueOf(input.readFloat());
1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (type == Double.TYPE) {
1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                element.fieldValue = Double.valueOf(input.readDouble());
1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Either array or Object
1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    element.fieldValue = readObject();
1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (ClassNotFoundException cnf) {
1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // WARNING- Not sure this is the right thing to do. Write
1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // test case.
1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new InvalidClassException(cnf.toString());
1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a collection of field values for the class descriptor
1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code classDesc} (an {@code ObjectStreamClass}). The
1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * values will be used to set instance fields in object {@code obj}.
1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This is the default mechanism, when emulated fields (an
1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code GetField}) are not used. Actual values to load are stored
1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * directly into the object {@code obj}.
1222f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj
1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            Instance in which the fields will be set.
1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param classDesc
1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            A class descriptor (an {@code ObjectStreamClass})
1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            defining which fields should be loaded.
1228f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the field values.
1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InvalidClassException
1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an incompatible type is being assigned to an emulated
1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             field.
1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws OptionalDataException
1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If optional data could not be found when reading the
1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             exception graph
1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If a class of an object being de-serialized can not be found
1239f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #readFields
1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #readObject()
1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readFieldValues(Object obj, ObjectStreamClass classDesc)
1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws OptionalDataException, ClassNotFoundException, IOException {
1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Now we must read all fields and assign them to the receiver
1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamField[] fields = classDesc.getLoadFields();
1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fields = (null == fields ? new ObjectStreamField[] {} : fields);
1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Class<?> declaringClass = classDesc.forClass();
1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (declaringClass == null && mustResolve) {
1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new ClassNotFoundException(classDesc.getName());
1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (ObjectStreamField fieldDesc : fields) {
1254f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1255f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // BEGIN android-removed
1256f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // // get associated Field
1257f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // long fieldID = fieldDesc.getFieldID(accessor, declaringClass);
1258f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // END android-removed
1259f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Code duplication starts, just because Java is typed
1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (fieldDesc.isPrimitive()) {
1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
1263f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    // BEGIN android-changed
1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    switch (fieldDesc.getTypeCode()) {
1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        case 'B':
1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            setField(obj, declaringClass, fieldDesc.getName(),
1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    input.readByte());
1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            break;
1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        case 'C':
1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            setField(obj, declaringClass, fieldDesc.getName(),
1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    input.readChar());
1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            break;
1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        case 'D':
1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            setField(obj, declaringClass, fieldDesc.getName(),
1275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    input.readDouble());
1276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            break;
1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        case 'F':
1278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            setField(obj, declaringClass, fieldDesc.getName(),
1279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    input.readFloat());
1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            break;
1281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        case 'I':
1282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            setField(obj, declaringClass, fieldDesc.getName(),
1283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    input.readInt());
1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            break;
1285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        case 'J':
1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            setField(obj, declaringClass, fieldDesc.getName(),
1287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    input.readLong());
1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            break;
1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        case 'S':
1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            setField(obj, declaringClass, fieldDesc.getName(),
1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    input.readShort());
1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            break;
1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        case 'Z':
1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            setField(obj, declaringClass, fieldDesc.getName(),
1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    input.readBoolean());
1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            break;
1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        default:
1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            throw new StreamCorruptedException(Msg.getString(
1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    "K00d5", fieldDesc.getTypeCode())); //$NON-NLS-1$
1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1301f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    // END android-changed
1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (NoSuchFieldError err) {
1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Object type (array included).
1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String fieldName = fieldDesc.getName();
1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                boolean setBack = false;
1308f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // BEGIN android-added
1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ObjectStreamField field = classDesc.getField(fieldName);
1310f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // END android-added
1311f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                if (mustResolve && fieldDesc == null) {
1312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    setBack = true;
1313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    mustResolve = false;
1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Object toSet;
1316f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                if (fieldDesc != null && fieldDesc.isUnshared()) {
1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    toSet = readUnshared();
1318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    toSet = readObject();
1320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (setBack) {
1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    mustResolve = true;
1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1324f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                if (fieldDesc != null) {
1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (toSet != null) {
1326f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                        Class<?> fieldType = fieldDesc.getType();
1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        Class<?> valueType = toSet.getClass();
1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (!fieldType.isAssignableFrom(valueType)) {
1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            throw new ClassCastException(Msg.getString(
1330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    "K00d4", new String[] { //$NON-NLS-1$
1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    fieldType.toString(), valueType.toString(),
1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                            classDesc.getName() + "." //$NON-NLS-1$
1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                                    + fieldName }));
1334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        try {
1336f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                            // BEGIN android-changed
1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            objSetField(obj, declaringClass, fieldName, field
1338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    .getTypeString(), toSet);
1339f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                            // END android-changed
1340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        } catch (NoSuchFieldError e) {
1341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            // Ignored
1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
1343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a float (32 bit) from the source stream.
1351f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the float value read from the source stream.
1353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
1354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
1355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
1356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
1358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public float readFloat() throws IOException {
1360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readFloat();
1361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads bytes from the source stream into the byte array {@code buffer}.
1365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method will block until {@code buffer.length} bytes have been read.
1366f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param buffer
1368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the array in which to store the bytes read.
1369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
1370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
1371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
1372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
1374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void readFully(byte[] buffer) throws IOException {
1376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveTypes.readFully(buffer);
1377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads bytes from the source stream into the byte array {@code buffer}.
1381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method will block until {@code length} number of bytes have been
1382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * read.
1383f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param buffer
1385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the byte array in which to store the bytes read.
1386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
1387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the initial position in {@code buffer} to store the bytes
1388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            read from the source stream.
1389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param length
1390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the maximum number of bytes to store in {@code buffer}.
1391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
1392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
1393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
1394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
1396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void readFully(byte[] buffer, int offset, int length)
1398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
1399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveTypes.readFully(buffer, offset, length);
1400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Walks the hierarchy of classes described by class descriptor
1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code classDesc} and reads the field values corresponding to
1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * fields declared by the corresponding class descriptor. The instance to
1406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * store field values into is {@code object}. If the class
1407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * (corresponding to class descriptor {@code classDesc}) defines
1408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * private instance method {@code readObject} it will be used to load
1409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * field values.
1410f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param object
1412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            Instance into which stored field values loaded.
1413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param classDesc
1414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            A class descriptor (an {@code ObjectStreamClass})
1415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            defining which fields should be loaded.
1416f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the field values in
1419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             the hierarchy.
1420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If a class for one of the field types could not be found
1422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NotActiveException
1423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If {@code defaultReadObject} is called from the wrong
1424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             context.
1425f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #defaultReadObject
1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #readObject()
1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readHierarchy(Object object, ObjectStreamClass classDesc)
1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException, ClassNotFoundException, NotActiveException {
1431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We can't be called from just anywhere. There are rules.
1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (object == null && mustResolve) {
1433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NotActiveException();
1434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ArrayList<ObjectStreamClass> streamClassList = new ArrayList<ObjectStreamClass>(
1437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                32);
1438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass nextStreamClass = classDesc;
1439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (nextStreamClass != null) {
1440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            streamClassList.add(0, nextStreamClass);
1441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            nextStreamClass = nextStreamClass.getSuperclass();
1442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (object == null) {
1444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Iterator<ObjectStreamClass> streamIt = streamClassList.iterator();
1445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (streamIt.hasNext()) {
1446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ObjectStreamClass streamClass = streamIt.next();
1447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                readObjectForClass(null, streamClass);
1448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
1450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ArrayList<Class<?>> classList = new ArrayList<Class<?>>(32);
1451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> nextClass = object.getClass();
1452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (nextClass != null) {
1453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Class<?> testClass = nextClass.getSuperclass();
1454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (testClass != null) {
1455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    classList.add(0, nextClass);
1456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                nextClass = testClass;
1458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int lastIndex = 0;
1460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < classList.size(); i++) {
1461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Class<?> superclass = classList.get(i);
1462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int index = findStreamSuperclass(superclass, streamClassList,
1463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        lastIndex);
1464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (index == -1) {
1465f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    readObjectNoData(object, superclass, ObjectStreamClass.lookupStreamClass(superclass));
1466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
1467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    for (int j = lastIndex; j <= index; j++) {
1468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        readObjectForClass(object, streamClassList.get(j));
1469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    lastIndex = index + 1;
1471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int findStreamSuperclass(Class<?> cl,
1477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ArrayList<ObjectStreamClass> classList, int lastIndex) {
1478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass objCl;
1479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String forName;
1480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = lastIndex; i < classList.size(); i++) {
1482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            objCl = classList.get(i);
1483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            forName = objCl.forClass().getName();
1484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (objCl.getName().equals(forName)) {
1486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (cl.getName().equals(objCl.getName())) {
1487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return i;
1488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // there was a class replacement
1491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (cl.getName().equals(forName)) {
1492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return i;
1493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return -1;
1497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1499f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private void readObjectNoData(Object object, Class<?> cl, ObjectStreamClass classDesc)
1500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws ObjectStreamException {
1501f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (!classDesc.isSerializable()) {
1502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
1503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1504f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (classDesc.hasMethodReadObjectNoData()){
1505f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            final Method readMethod = classDesc.getMethodReadObjectNoData();
1506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
1507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                readMethod.invoke(object, new Object[0]);
1508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (InvocationTargetException e) {
1509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Throwable ex = e.getTargetException();
1510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (ex instanceof RuntimeException) {
1511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw (RuntimeException) ex;
1512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (ex instanceof Error) {
1513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw (Error) ex;
1514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw (ObjectStreamException) ex;
1516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IllegalAccessException e) {
1517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new RuntimeException(e.toString());
1518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1520f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readObjectForClass(Object object, ObjectStreamClass classDesc)
1524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException, ClassNotFoundException, NotActiveException {
1525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Have to do this before calling defaultReadObject or anything that
1526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // calls defaultReadObject
1527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        currentObject = object;
1528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        currentClass = classDesc;
1529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean hadWriteMethod = (classDesc.getFlags() & SC_WRITE_METHOD) > 0;
1531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Class<?> targetClass = classDesc.forClass();
1532f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final Method readMethod;
1534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (targetClass == null || !mustResolve) {
1535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            readMethod = null;
1536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
1537f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            readMethod = classDesc.getMethodReadObject();
1538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (readMethod != null) {
1541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // We have to be able to fetch its value, even if it is private
1542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                AccessController.doPrivileged(new PriviAction<Object>(
1543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        readMethod));
1544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
1545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    readMethod.invoke(object, new Object[] { this });
1546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (InvocationTargetException e) {
1547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Throwable ex = e.getTargetException();
1548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (ex instanceof ClassNotFoundException) {
1549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw (ClassNotFoundException) ex;
1550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    } else if (ex instanceof RuntimeException) {
1551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw (RuntimeException) ex;
1552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    } else if (ex instanceof Error) {
1553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw (Error) ex;
1554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw (IOException) ex;
1556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (IllegalAccessException e) {
1557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new RuntimeException(e.toString());
1558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                defaultReadObject();
1561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (hadWriteMethod) {
1563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                discardData();
1564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
1566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Cleanup, needs to run always so that we can later detect invalid
1567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // calls to defaultReadObject
1568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            currentObject = null; // We did not set this, so we do not need to
1569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // clean it
1570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            currentClass = null;
1571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads an integer (32 bit) from the source stream.
1576f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the integer value read from the source stream.
1578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
1579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
1580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
1581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
1583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int readInt() throws IOException {
1585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readInt();
1586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1589f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Reads the next line from the source stream. Lines are terminated by
1590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code '\r'}, {@code '\n'}, {@code "\r\n"} or an {@code EOF}.
1591f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the string read from the source stream.
1593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
1595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@link BufferedReader}
1596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
1598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String readLine() throws IOException {
1599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readLine();
1600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a long (64 bit) from the source stream.
1604f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the long value read from the source stream.
1606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
1607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
1608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
1609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
1611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long readLong() throws IOException {
1613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readLong();
1614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Read a new array from the receiver. It is assumed the array has not been
1618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * read yet (not a cyclic reference). Return the array read.
1619f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unshared
1621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            read the object unshared
1622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the array read
1623f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the array.
1626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If a class for one of the objects could not be found
1628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws OptionalDataException
1629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If optional data could not be found when reading the array.
1630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readNewArray(boolean unshared) throws OptionalDataException,
1632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException, IOException {
1633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass classDesc = readClassDesc();
1634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (classDesc == null) {
1636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
1637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1639f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        Integer newHandle = nextHandle();
1640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Array size
1642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int size = input.readInt();
1643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Class<?> arrayClass = classDesc.forClass();
1644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Class<?> componentType = arrayClass.getComponentType();
1645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object result = Array.newInstance(componentType, size);
1646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        registerObjectRead(result, newHandle, unshared);
1648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Now we have code duplication just because Java is typed. We have to
1650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // read N elements and assign to array positions, but we must typecast
1651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // the array first, and also call different methods depending on the
1652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // elements.
1653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (componentType.isPrimitive()) {
1654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (componentType == Integer.TYPE) {
1655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int[] intArray = (int[]) result;
1656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < size; i++) {
1657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    intArray[i] = input.readInt();
1658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (componentType == Byte.TYPE) {
1660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                byte[] byteArray = (byte[]) result;
1661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                input.readFully(byteArray, 0, size);
1662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (componentType == Character.TYPE) {
1663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                char[] charArray = (char[]) result;
1664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < size; i++) {
1665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    charArray[i] = input.readChar();
1666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (componentType == Short.TYPE) {
1668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                short[] shortArray = (short[]) result;
1669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < size; i++) {
1670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    shortArray[i] = input.readShort();
1671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (componentType == Boolean.TYPE) {
1673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                boolean[] booleanArray = (boolean[]) result;
1674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < size; i++) {
1675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    booleanArray[i] = input.readBoolean();
1676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (componentType == Long.TYPE) {
1678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                long[] longArray = (long[]) result;
1679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < size; i++) {
1680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    longArray[i] = input.readLong();
1681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (componentType == Float.TYPE) {
1683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                float[] floatArray = (float[]) result;
1684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < size; i++) {
1685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    floatArray[i] = input.readFloat();
1686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (componentType == Double.TYPE) {
1688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                double[] doubleArray = (double[]) result;
1689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < size; i++) {
1690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    doubleArray[i] = input.readDouble();
1691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new ClassNotFoundException(Msg.getString(
1694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        "K00d7", classDesc.getName())); //$NON-NLS-1$
1695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
1697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Array of Objects
1698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Object[] objectArray = (Object[]) result;
1699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < size; i++) {
1700f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // TODO: This place is the opportunity for enhancement
1701f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                //      We can implement writing elements through fast-path,
1702f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                //      without setting up the context (see readObject()) for
1703f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                //      each element with public API
1704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                objectArray[i] = readObject();
1705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (enableResolve) {
1708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result = resolveObject(result);
1709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            registerObjectRead(result, newHandle, false);
1710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
1712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a new class from the receiver. It is assumed the class has not been
1716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * read yet (not a cyclic reference). Return the class read.
1717f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unshared
1719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            read the object unshared
1720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return The {@code java.lang.Class} read from the stream.
1721f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the class.
1724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If a class for one of the objects could not be found
1726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Class<?> readNewClass(boolean unshared)
1728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws ClassNotFoundException, IOException {
1729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass classDesc = readClassDesc();
1730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (classDesc != null) {
1732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> localClass = classDesc.forClass();
1733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (localClass != null) {
1734f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                registerObjectRead(localClass, nextHandle(), unshared);
1735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return localClass;
1737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
1739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
1742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * read class type for Enum, note there's difference between enum and normal
1743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * classes
1744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ObjectStreamClass readEnumDesc() throws IOException,
1746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException {
1747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte tc = nextTC();
1748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (tc) {
1749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_CLASSDESC:
1750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return readEnumDescInternal();
1751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_REFERENCE:
1752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return (ObjectStreamClass) readCyclicReference();
1753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_NULL:
1754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return null;
1755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
1756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new StreamCorruptedException(Msg.getString(
1757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        "K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
1758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ObjectStreamClass readEnumDescInternal() throws IOException,
1762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException {
1763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass classDesc;
1764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveData = input;
1765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Integer oldHandle = descriptorHandle;
1766f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        descriptorHandle = nextHandle();
1767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        classDesc = readClassDescriptor();
1768f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        registerObjectRead(classDesc, descriptorHandle, false);
1769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        descriptorHandle = oldHandle;
1770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveData = emptyStream;
1771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        classDesc.setClass(resolveClass(classDesc));
1772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Consume unread class annotation data and TC_ENDBLOCKDATA
1773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        discardData();
1774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass superClass = readClassDesc();
1775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkedSetSuperClassDesc(classDesc, superClass);
1776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Check SUIDs, note all SUID for Enum is 0L
1777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (0L != classDesc.getSerialVersionUID()
1778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                || 0L != superClass.getSerialVersionUID()) {
1779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new InvalidClassException(superClass.getName(), Msg
1780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .getString("K00da", superClass, //$NON-NLS-1$
1781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            superClass));
1782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte tc = nextTC();
1784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // discard TC_ENDBLOCKDATA after classDesc if any
1785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (tc == TC_ENDBLOCKDATA) {
1786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // read next parent class. For enum, it may be null
1787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            superClass.setSuperclass(readClassDesc());
1788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
1789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // not TC_ENDBLOCKDATA, push back for next read
1790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            pushbackTC();
1791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return classDesc;
1793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")// For the Enum.valueOf call
1796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readEnum(boolean unshared) throws OptionalDataException,
1797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException, IOException {
1798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // read classdesc for Enum first
1799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass classDesc = readEnumDesc();
1800f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        Integer newHandle = nextHandle();
1801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // read name after class desc
1802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String name;
1803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte tc = nextTC();
1804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (tc) {
1805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_REFERENCE:
1806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (unshared) {
1807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    readNewHandle();
1808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new InvalidObjectException(Msg.getString("KA002")); //$NON-NLS-1$
1809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                name = (String) readCyclicReference();
1811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
1812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case TC_STRING:
1813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                name = (String) readNewString(unshared);
1814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
1815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
1816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new StreamCorruptedException(Msg.getString("K00d2"));//$NON-NLS-1$
1817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Enum<?> result = Enum.valueOf((Class) classDesc.forClass(), name);
1820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        registerObjectRead(result, newHandle, unshared);
1821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
1823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a new class descriptor from the receiver. It is assumed the class
1827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * descriptor has not been read yet (not a cyclic reference). Return the
1828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * class descriptor read.
1829f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unshared
1831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            read the object unshared
1832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return The {@code ObjectStreamClass} read from the stream.
1833f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the class
1836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             descriptor.
1837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If a class for one of the objects could not be found
1839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ObjectStreamClass readNewClassDesc(boolean unshared)
1841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws ClassNotFoundException, IOException {
1842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // So read...() methods can be used by
1843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // subclasses during readClassDescriptor()
1844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveData = input;
1845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Integer oldHandle = descriptorHandle;
1846f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        descriptorHandle = nextHandle();
1847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass newClassDesc = readClassDescriptor();
1848f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        registerObjectRead(newClassDesc, descriptorHandle, unshared);
1849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        descriptorHandle = oldHandle;
1850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveData = emptyStream;
1851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We need to map classDesc to class.
1853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            newClassDesc.setClass(resolveClass(newClassDesc));
1855f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // Check SUIDs & base name of the class
1856f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            verifyAndInit(newClassDesc);
1857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (ClassNotFoundException e) {
1858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (mustResolve) {
1859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
1860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Just continue, the class may not be required
1861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Resolve the field signatures using the class loader of the
1865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // resolved class
1866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamField[] fields = newClassDesc.getLoadFields();
1867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fields = (null == fields ? new ObjectStreamField[] {} : fields);
1868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ClassLoader loader = newClassDesc.forClass() == null ? callerClassLoader
1869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : newClassDesc.forClass().getClassLoader();
1870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (ObjectStreamField element : fields) {
1871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            element.resolve(loader);
1872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Consume unread class annotation data and TC_ENDBLOCKDATA
1875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        discardData();
1876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkedSetSuperClassDesc(newClassDesc, readClassDesc());
1877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return newClassDesc;
1878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a new proxy class descriptor from the receiver. It is assumed the
1882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * proxy class descriptor has not been read yet (not a cyclic reference).
1883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Return the proxy class descriptor read.
1884f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return The {@code Class} read from the stream.
1886f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the class
1889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             descriptor.
1890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If a class for one of the objects could not be found
1892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Class<?> readNewProxyClassDesc() throws ClassNotFoundException,
1894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            IOException {
1895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int count = input.readInt();
1896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String[] interfaceNames = new String[count];
1897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < count; i++) {
1898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            interfaceNames[i] = input.readUTF();
1899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Class<?> proxy = resolveProxyClass(interfaceNames);
1901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Consume unread class annotation data and TC_ENDBLOCKDATA
1902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        discardData();
1903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return proxy;
1904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a class descriptor from the source stream.
1908f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the class descriptor read from the source stream.
1910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a class for one of the objects cannot be found.
1912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
1914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected ObjectStreamClass readClassDescriptor() throws IOException,
1916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException {
1917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass newClassDesc = new ObjectStreamClass();
1919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String name = input.readUTF();
1920f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (name.length() == 0) {
1921f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // luni.07 = The stream is corrupted
1922f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            throw new IOException(Messages.getString("luni.07")); //$NON-NLS-1$
1923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        newClassDesc.setName(name);
1925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        newClassDesc.setSerialVersionUID(input.readLong());
1926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        newClassDesc.setFlags(input.readByte());
1927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1928f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        /*
1929f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         * We must register the class descriptor before reading field
1930f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         * descriptors. If called outside of readObject, the descriptorHandle
1931f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         * might be null.
1932f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson         */
1933f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        descriptorHandle = (null == descriptorHandle ? nextHandle() : descriptorHandle);
1934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        registerObjectRead(newClassDesc, descriptorHandle, false);
1935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        readFieldDescriptors(newClassDesc);
1937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return newClassDesc;
1938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates the proxy class that implements the interfaces specified in
1942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code interfaceNames}.
1943f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param interfaceNames
1945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the interfaces used to create the proxy class.
1946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the proxy class.
1947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
1948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the proxy class or any of the specified interfaces cannot
1949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             be created.
1950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
1952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectOutputStream#annotateProxyClass(Class)
1953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Class<?> resolveProxyClass(String[] interfaceNames)
1955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException, ClassNotFoundException {
1956f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // TODO: This method is opportunity for performance enhancement
1957f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        //       We can cache the classloader and recently used interfaces.
1958f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // BEGIN android-changed
1959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // ClassLoader loader = VM.getNonBootstrapClassLoader();
1960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ClassLoader loader = ClassLoader.getSystemClassLoader();
1961f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // END android-changed
1962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Class<?>[] interfaces = new Class<?>[interfaceNames.length];
1963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < interfaceNames.length; i++) {
1964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            interfaces[i] = Class.forName(interfaceNames[i], false, loader);
1965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return Proxy.getProxyClass(loader, interfaces);
1968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IllegalArgumentException e) {
1969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new ClassNotFoundException(e.toString(), e);
1970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Write a new handle describing a cyclic reference from the stream.
1975f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the handle read
1977f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the handle
1980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1981f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private int readNewHandle() throws IOException {
1982f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return input.readInt();
1983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1985f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private Class<?> resolveConstructorClass(Class<?> objectClass, boolean wasSerializable, boolean wasExternalizable)
1986f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        throws OptionalDataException, ClassNotFoundException, IOException {
1987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // The class of the instance may not be the same as the class of the
1989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // constructor to run
1990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // This is the constructor to run if Externalizable
1991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> constructorClass = objectClass;
1992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // WARNING - What if the object is serializable and externalizable ?
1994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Is that possible ?
1995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (wasSerializable) {
1996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Now we must run the constructor of the class just above the
1997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // one that implements Serializable so that slots that were not
1998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // dumped can be initialized properly
1999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (constructorClass != null
2000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && ObjectStreamClass.isSerializable(constructorClass)) {
2001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    constructorClass = constructorClass.getSuperclass();
2002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Fetch the empty constructor, or null if none.
2006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Constructor<?> constructor = null;
2007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (constructorClass != null) {
2008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
2009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    constructor = constructorClass
2010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .getDeclaredConstructor(ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
2011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (NoSuchMethodException nsmEx) {
2012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // Ignored
2013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Has to have an empty constructor
2017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (constructor == null) {
2018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new InvalidClassException(constructorClass.getName(), Msg
2019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .getString("K00dc")); //$NON-NLS-1$
2020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int constructorModifiers = constructor.getModifiers();
2023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Now we must check if the empty constructor is visible to the
2025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // instantiation class
2026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (Modifier.isPrivate(constructorModifiers)
2027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    || (wasExternalizable && !Modifier
2028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .isPublic(constructorModifiers))) {
2029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new InvalidClassException(constructorClass.getName(), Msg
2030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .getString("K00dc")); //$NON-NLS-1$
2031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // We know we are testing from a subclass, so the only other case
2034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // where the visibility is not allowed is when the constructor has
2035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // default visibility and the instantiation class is in a different
2036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // package than the constructor class
2037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!Modifier.isPublic(constructorModifiers)
2038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    && !Modifier.isProtected(constructorModifiers)) {
2039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Not public, not private and not protected...means default
2040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // visibility. Check if same package
2041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!inSamePackage(constructorClass, objectClass)) {
2042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new InvalidClassException(constructorClass.getName(),
2043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            Msg.getString("K00dc")); //$NON-NLS-1$
2044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2047f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return constructorClass;
2048f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
2049f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2050f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    /**
2051f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Read a new object from the stream. It is assumed the object has not been
2052f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * loaded yet (not a cyclic reference). Return the object read.
2053f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2054f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * If the object implements <code>Externalizable</code> its
2055f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * <code>readExternal</code> is called. Otherwise, all fields described by
2056f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * the class hierarchy are loaded. Each class can define how its declared
2057f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * instance fields are loaded by defining a private method
2058f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * <code>readObject</code>
2059f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2060f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @param unshared
2061f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            read the object unshared
2062f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @return the object read
2063f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2064f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws IOException
2065f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             If an IO exception happened when reading the object.
2066f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws OptionalDataException
2067f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             If optional data could not be found when reading the object
2068f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             graph
2069f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws ClassNotFoundException
2070f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             If a class for one of the objects could not be found
2071f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     */
2072f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private Object readNewObject(boolean unshared)
2073f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            throws OptionalDataException, ClassNotFoundException, IOException {
2074f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        ObjectStreamClass classDesc = readClassDesc();
2075f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2076f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (classDesc == null) {
2077f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
2078f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
2079f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2080f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        Integer newHandle = nextHandle();
2081f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2082f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // Note that these values come from the Stream, and in fact it could be
2083f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // that the classes have been changed so that the info below now
2084f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // conflicts with the newer class
2085f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        boolean wasExternalizable = (classDesc.getFlags() & SC_EXTERNALIZABLE) > 0;
2086f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        boolean wasSerializable = (classDesc.getFlags() & SC_SERIALIZABLE) > 0;
2087f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2088f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2089f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // Maybe we should cache the values above in classDesc ? It may be the
2090f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // case that when reading classDesc we may need to read more stuff
2091f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // depending on the values above
2092f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        Class<?> objectClass = classDesc.forClass();
2093f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2094f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        Object result, registeredResult = null;
2095f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (objectClass != null) {
2096f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2097f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // BEGIN android-changed
2098f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // long constructor = classDesc.getConstructor();
2099f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // if (constructor == ObjectStreamClass.CONSTRUCTOR_IS_NOT_RESOLVED) {
2100f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            //     constructor = accessor.getMethodID(resolveConstructorClass(objectClass, wasSerializable, wasExternalizable), null, new Class[0]);
2101f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            //     classDesc.setConstructor(constructor);
2102f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // }
2103f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            Class constructorClass = resolveConstructorClass(objectClass, wasSerializable, wasExternalizable);
2104f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // END android-changed
2105f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Now we know which class to instantiate and which constructor to
2107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // run. We are allowed to run the constructor.
2108f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // BEGIN android-changed
2109f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // result = accessor.newInstance(objectClass, constructor, null);
2110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result = newInstance(objectClass, constructorClass);
2111f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // END android-changed
2112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            registerObjectRead(result, newHandle, unshared);
2113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            registeredResult = result;
2115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
2116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result = null;
2117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
2120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // This is how we know what to do in defaultReadObject. And it is
2121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // also used by defaultReadObject to check if it was called from an
2122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // invalid place. It also allows readExternal to call
2123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // defaultReadObject and have it work.
2124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            currentObject = result;
2125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            currentClass = classDesc;
2126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // If Externalizable, just let the object read itself
2128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (wasExternalizable) {
2129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                boolean blockData = (classDesc.getFlags() & SC_BLOCK_DATA) > 0;
2130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!blockData) {
2131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    primitiveData = input;
2132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (mustResolve) {
2134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Externalizable extern = (Externalizable) result;
2135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    extern.readExternal(this);
2136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (blockData) {
2138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // Similar to readHierarchy. Anything not read by
2139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // readExternal has to be consumed here
2140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    discardData();
2141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
2142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    primitiveData = emptyStream;
2143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
2145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // If we got here, it is Serializable but not Externalizable.
2146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Walk the hierarchy reading each class' slots
2147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                readHierarchy(result, classDesc);
2148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
2150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Cleanup, needs to run always so that we can later detect invalid
2151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // calls to defaultReadObject
2152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            currentObject = null;
2153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            currentClass = null;
2154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (objectClass != null) {
2157f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2158f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (classDesc.hasMethodReadResolve()){
2159f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                Method methodReadResolve = classDesc.getMethodReadResolve();
2160f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                try {
2161f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    result = methodReadResolve.invoke(result, (Object[]) null);
2162f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                } catch (IllegalAccessException iae) {
2163f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                } catch (InvocationTargetException ite) {
2164f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    Throwable target = ite.getTargetException();
2165f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    if (target instanceof ObjectStreamException) {
2166f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                        throw (ObjectStreamException) target;
2167f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    } else if (target instanceof Error) {
2168f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                        throw (Error) target;
2169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    } else {
2170f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                        throw (RuntimeException) target;
2171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
2172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2173f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We get here either if class-based replacement was not needed or if it
2177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // was needed but produced the same object or if it could not be
2178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // computed.
2179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The object to return is the one we instantiated or a replacement for
2181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // it
2182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (result != null && enableResolve) {
2183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result = resolveObject(result);
2184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (registeredResult != result) {
2186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            registerObjectRead(result, newHandle, unshared);
2187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
2189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Read a string encoded in {@link DataInput modified UTF-8} from the
2193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * receiver. Return the string read.
2194f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unshared
2196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            read the object unshared
2197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the string just read.
2198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the String.
2200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readNewString(boolean unshared) throws IOException {
2202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object result = input.readUTF();
2203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (enableResolve) {
2204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result = resolveObject(result);
2205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2206f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson		registerObjectRead(result, nextHandle(), unshared);
2207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
2209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Read a new String in UTF format from the receiver. Return the string
2213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * read.
2214f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unshared
2216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            read the object unshared
2217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the string just read.
2218f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an IO exception happened when reading the String.
2221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readNewLongString(boolean unshared) throws IOException {
2223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long length = input.readLong();
2224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object result = input.decodeUTF((int) length);
2225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (enableResolve) {
2226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result = resolveObject(result);
2227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2228f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        registerObjectRead(result, nextHandle(), unshared);
2229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
2231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads the next object from the source stream.
2235f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the object read from the source stream.
2237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
2238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the class of one of the objects in the object graph cannot
2239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             be found.
2240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
2242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws OptionalDataException
2243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if primitive data types were found instead of an object.
2244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectOutputStream#writeObject(Object)
2245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Object readObject() throws OptionalDataException,
2247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException, IOException {
2248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return readObject(false);
2249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads the next unshared object from the source stream.
2253f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the new object read.
2255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
2256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the class of one of the objects in the object graph cannot
2257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             be found.
2258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
2260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectOutputStream#writeUnshared
2261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object readUnshared() throws IOException, ClassNotFoundException {
2263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return readObject(true);
2264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readObject(boolean unshared) throws OptionalDataException,
2267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException, IOException {
2268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean restoreInput = (primitiveData == input);
2269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (restoreInput) {
2270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            primitiveData = emptyStream;
2271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // This is the spec'ed behavior in JDK 1.2. Very bizarre way to allow
2274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // behavior overriding.
2275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subclassOverridingImplementation && !unshared) {
2276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return readObjectOverride();
2277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If we still had primitive types to read, should we discard them
2280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // (reset the primitiveTypes stream) or leave as is, so that attempts to
2281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // read primitive types won't read 'past data' ???
2282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object result;
2283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
2284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // We need this so we can tell when we are returning to the
2285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // original/outside caller
2286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (++nestedLevels == 1) {
2287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Remember the caller's class loader
2288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // BEGIN android-changed
2289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                callerClassLoader = getClosestUserClassLoader();
2290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // END android-changed
2291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result = readNonPrimitiveContent(unshared);
2294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (restoreInput) {
2295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                primitiveData = input;
2296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
2298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // We need this so we can tell when we are returning to the
2299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // original/outside caller
2300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (--nestedLevels == 0) {
2301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // We are going to return to the original caller, perform
2302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // cleanups.
2303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // No more need to remember the caller's class loader
2304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                callerClassLoader = null;
2305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Done reading this object. Is it time to return to the original
2309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // caller? If so we need to perform validations first.
2310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nestedLevels == 0 && validations != null) {
2311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // We are going to return to the original caller. If validation is
2312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // enabled we need to run them now and then cleanup the validation
2313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // collection
2314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
2315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (InputValidationDesc element : validations) {
2316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    element.validator.validateObject();
2317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } finally {
2319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Validations have to be renewed, since they are only called
2320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // from readObject
2321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                validations = null;
2322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
2325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-added
2328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final ClassLoader bootstrapLoader
2329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            = Object.class.getClassLoader();
2330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final ClassLoader systemLoader
2331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            = ClassLoader.getSystemClassLoader();
2332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Searches up the call stack to find the closest user-defined class loader.
2335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
2336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a user-defined class loader or null if one isn't found
2337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static ClassLoader getClosestUserClassLoader() {
2339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Class<?>[] stackClasses = VMStack.getClasses(-1, false);
2340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (Class<?> stackClass : stackClasses) {
2341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassLoader loader = stackClass.getClassLoader();
2342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (loader != null && loader != bootstrapLoader
2343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    && loader != systemLoader) {
2344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return loader;
2345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
2348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-added
2350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Method to be overriden by subclasses to read the next object from the
2353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * source stream.
2354f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the object read from the source stream.
2356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
2357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the class of one of the objects in the object graph cannot
2358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             be found.
2359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
2361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws OptionalDataException
2362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if primitive data types were found instead of an object.
2363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectOutputStream#writeObjectOverride
2364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Object readObjectOverride() throws OptionalDataException,
2366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException, IOException {
2367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input == null) {
2368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
2369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Subclasses must override.
2371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new IOException();
2372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a short (16 bit) from the source stream.
2376f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the short value read from the source stream.
2378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
2380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public short readShort() throws IOException {
2382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readShort();
2383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads and validates the ObjectInputStream header from the source stream.
2387f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
2390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws StreamCorruptedException
2391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the source stream does not contain readable serialized
2392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             objects.
2393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void readStreamHeader() throws IOException,
2395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            StreamCorruptedException {
2396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input.readShort() == STREAM_MAGIC
2397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && input.readShort() == STREAM_VERSION) {
2398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
2399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new StreamCorruptedException();
2401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads an unsigned byte (8 bit) from the source stream.
2405f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the unsigned byte value read from the source stream packaged in
2407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         an integer.
2408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
2409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
2410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
2411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
2413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int readUnsignedByte() throws IOException {
2415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readUnsignedByte();
2416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads an unsigned short (16 bit) from the source stream.
2420f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the unsigned short value read from the source stream packaged in
2422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         an integer.
2423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
2424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
2425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
2426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
2428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int readUnsignedShort() throws IOException {
2430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readUnsignedShort();
2431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a string encoded in {@link DataInput modified UTF-8} from the
2435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * source stream.
2436f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the string encoded in {@link DataInput modified UTF-8} read from
2438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         the source stream.
2439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws EOFException
2440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the end of the input is reached before the read
2441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             request can be satisfied.
2442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading from the source stream.
2444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String readUTF() throws IOException {
2446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return primitiveTypes.readUTF();
2447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Return the object previously read tagged with handle {@code handle}.
2451f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param handle
2453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            The handle that this object was assigned when it was read.
2454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the object previously read.
2455f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InvalidObjectException
2457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If there is no previously read object with this handle
2458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object registeredObjectRead(Integer handle)
2460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws InvalidObjectException {
2461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object res = objectsRead.get(handle);
2462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (res == UNSHARED_OBJ) {
2464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new InvalidObjectException(Msg.getString("KA010")); //$NON-NLS-1$
2465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return res;
2468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Assume object {@code obj} has been read, and assign a handle to
2472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * it, {@code handle}.
2473f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj
2475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            Non-null object being loaded.
2476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param handle
2477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            An Integer, the handle to this object
2478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unshared
2479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            Boolean, indicates that caller is reading in unshared mode
2480f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #nextHandle
2482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void registerObjectRead(Object obj, Integer handle, boolean unshared) {
2484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        objectsRead.put(handle, unshared ? UNSHARED_OBJ : obj);
2485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Registers a callback for post-deserialization validation of objects. It
2489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * allows to perform additional consistency checks before the {@code
2490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * readObject()} method of this class returns its result to the caller. This
2491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * method can only be called from within the {@code readObject()} method of
2492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * a class that implements "special" deserialization rules. It can be called
2493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * multiple times. Validation callbacks are then done in order of decreasing
2494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * priority, defined by {@code priority}.
2495f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param object
2497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            an object that can validate itself by receiving a callback.
2498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param priority
2499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the validator's priority.
2500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InvalidObjectException
2501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code object} is {@code null}.
2502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NotActiveException
2503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this stream is currently not reading objects. In that
2504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             case, calling this method is not allowed.
2505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectInputValidation#validateObject()
2506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void registerValidation(ObjectInputValidation object,
2508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int priority) throws NotActiveException, InvalidObjectException {
2509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Validation can only be registered when inside readObject calls
2510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object instanceBeingRead = this.currentObject;
2511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We can't be called from just anywhere. There are rules.
2513f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (instanceBeingRead == null && nestedLevels == 0) {
2514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NotActiveException();
2515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (object == null) {
2517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new InvalidObjectException(Msg.getString("K00d9")); //$NON-NLS-1$
2518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // From now on it is just insertion in a SortedCollection. Since
2520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // the Java class libraries don't provide that, we have to
2521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // implement it from scratch here.
2522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InputValidationDesc desc = new InputValidationDesc();
2523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        desc.validator = object;
2524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        desc.priority = priority;
2525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // No need for this, validateObject does not take a parameter
2526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // desc.toValidate = instanceBeingRead;
2527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (validations == null) {
2528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            validations = new InputValidationDesc[1];
2529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            validations[0] = desc;
2530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
2531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int i = 0;
2532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (; i < validations.length; i++) {
2533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                InputValidationDesc validation = validations[i];
2534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Sorted, higher priority first.
2535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (priority >= validation.priority) {
2536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break; // Found the index where to insert
2537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InputValidationDesc[] oldValidations = validations;
2540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int currentSize = oldValidations.length;
2541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            validations = new InputValidationDesc[currentSize + 1];
2542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(oldValidations, 0, validations, 0, i);
2543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(oldValidations, i, validations, i + 1, currentSize
2544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    - i);
2545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            validations[i] = desc;
2546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reset the collection of objects already loaded by the receiver.
2551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void resetSeenObjects() {
2553f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        objectsRead = new HashMap<Integer, Object>();
2554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        currentHandle = baseWireHandle;
2555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        primitiveData = emptyStream;
2556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reset the receiver. The collection of objects already read by the
2560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * receiver is reset, and internal structures are also reset so that the
2561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * receiver knows it is in a fresh clean state.
2562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void resetState() {
2564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        resetSeenObjects();
2565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        hasPushbackTC = false;
2566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pushbackTC = 0;
2567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // nestedLevels = 0;
2568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Loads the Java class corresponding to the class descriptor {@code
2572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * osClass} that has just been read from the source stream.
2573f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param osClass
2575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            an ObjectStreamClass read from the source stream.
2576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a Class corresponding to the descriptor {@code osClass}.
2577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassNotFoundException
2578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the class for an object cannot be found.
2579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an I/O error occurs while creating the class.
2581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectOutputStream#annotateClass(Class)
2582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Class<?> resolveClass(ObjectStreamClass osClass)
2584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException, ClassNotFoundException {
2585f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // fastpath: obtain cached value
2586f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        Class<?> cls = osClass.forClass();
2587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (null == cls) {
2588f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // slowpath: resolve the class
2589f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            String className = osClass.getName();
2590f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2591f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // if it is primitive class, for example, long.class
2592f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            cls = PRIMITIVE_CLASSES.get(className);
2593f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2594f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (null == cls) {
2595f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // not primitive class
2596f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // Use the first non-null ClassLoader on the stack. If null, use
2597f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // the system class loader
2598f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                cls = Class.forName(className, true, callerClassLoader);
2599f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
2600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return cls;
2602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Allows trusted subclasses to substitute the specified original {@code
2606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * object} with a new object. Object substitution has to be activated first
2607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * with calling {@code enableResolveObject(true)}. This implementation just
2608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * returns {@code object}.
2609f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param object
2611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the original object for which a replacement may be defined.
2612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the replacement object for {@code object}.
2613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if any I/O error occurs while creating the replacement
2615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             object.
2616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #enableResolveObject
2617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectOutputStream#enableReplaceObject
2618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ObjectOutputStream#replaceObject
2619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Object resolveObject(Object object) throws IOException {
2621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // By default no object replacement. Subclasses can override
2622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return object;
2623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2625f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // BEGIN android-added
2626f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2627f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    /*
2628f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * These methods set the value of a field named fieldName of instance. The
2629f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * field is declared by declaringClass. The field is the same type as the
2630f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * value parameter.
2631f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2632f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * these methods could be implemented non-natively on top of
2633f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * java.lang.reflect at the expense of extra object creation
2634f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * (java.lang.reflect.Field). Otherwise Serialization could not fetch
2635f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * private fields, except by the use of a native method like this one.
2636f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2637f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NoSuchFieldError If the field does not exist.
2638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native void setField(Object instance,
2640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> declaringClass, String fieldName, byte value)
2641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchFieldError;
2642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2643f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native void setField(Object instance,
2645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> declaringClass, String fieldName, char value)
2646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchFieldError;
2647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2648f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native void setField(Object instance,
2650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> declaringClass, String fieldName, double value)
2651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchFieldError;
2652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native void setField(Object instance,
2654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> declaringClass, String fieldName, float value)
2655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchFieldError;
2656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native void setField(Object instance,
2658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> declaringClass, String fieldName, int value)
2659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchFieldError;
2660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native void setField(Object instance,
2662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> declaringClass, String fieldName, long value)
2663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchFieldError;
2664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native void objSetField(Object instance,
2666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> declaringClass, String fieldName, String fieldTypeName,
2667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Object value) throws NoSuchFieldError;
2668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native void setField(Object instance,
2670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> declaringClass, String fieldName, short value)
2671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchFieldError;
2672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static native void setField(Object instance,
2674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<?> declaringClass, String fieldName, boolean value)
2675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchFieldError;
2676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2677f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // END android-added
2678f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Skips {@code length} bytes on the source stream. This method should not
2681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * be used to skip bytes at any arbitrary position, just when reading
2682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * primitive data types (int, char etc).
2683f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param length
2685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of bytes to skip.
2686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of bytes actually skipped.
2687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
2688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while skipping bytes on the source stream.
2689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
2690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the source stream is {@code null}.
2691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int skipBytes(int length) throws IOException {
2693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To be used with available. Ok to call if reading primitive buffer
2694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input == null) {
2695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException();
2696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int offset = 0;
2699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (offset < length) {
2700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkReadPrimitiveTypes();
2701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long skipped = primitiveData.skip(length - offset);
2702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (skipped == 0) {
2703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return offset;
2704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            offset += (int) skipped;
2706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return length;
2708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2711f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Verify if the SUID & the base name for descriptor
2712f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * <code>loadedStreamClass</code>matches
2713f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * the SUID & the base name of the corresponding loaded class and
2714f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * init private fields.
2715f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param loadedStreamClass
2717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            An ObjectStreamClass that was loaded from the stream.
2718f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InvalidClassException
2720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If the SUID of the stream class does not match the VM class
2721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2722f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private void verifyAndInit(ObjectStreamClass loadedStreamClass)
2723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws InvalidClassException {
2724f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Class<?> localClass = loadedStreamClass.forClass();
2726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectStreamClass localStreamClass = ObjectStreamClass
2727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .lookupStreamClass(localClass);
2728f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (loadedStreamClass.getSerialVersionUID() != localStreamClass
2730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .getSerialVersionUID()) {
2731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new InvalidClassException(loadedStreamClass.getName(), Msg
2732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .getString("K00da", loadedStreamClass, //$NON-NLS-1$
2733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            localStreamClass));
2734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String loadedClassBaseName = getBaseName(loadedStreamClass.getName());
2737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String localClassBaseName = getBaseName(localStreamClass.getName());
2738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!loadedClassBaseName.equals(localClassBaseName)) {
2740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new InvalidClassException(loadedStreamClass.getName(), Msg
2741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .getString("KA015", loadedClassBaseName, //$NON-NLS-1$
2742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            localClassBaseName));
2743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2744f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
2745f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        loadedStreamClass.initPrivateFields(localStreamClass);
2746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static String getBaseName(String fullName) {
2749f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int k = fullName.lastIndexOf('.');
2750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (k == -1 || k == (fullName.length() - 1)) {
2752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return fullName;
2753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return fullName.substring(k + 1);
2755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Avoid recursive defining.
2758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static void checkedSetSuperClassDesc(ObjectStreamClass desc,
2759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ObjectStreamClass superDesc) throws StreamCorruptedException {
2760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (desc.equals(superDesc)) {
2761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new StreamCorruptedException();
2762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        desc.setSuperclass(superDesc);
2764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
2766