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 2003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughesimport dalvik.system.VMStack; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.EmulatedFields.ObjectSlot; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Array; 23b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughesimport java.lang.reflect.Field; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.InvocationTargetException; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Method; 2605895faacf43e6fd2bcd57baed31832f6888cb31Elliott Hughesimport java.lang.reflect.Modifier; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Proxy; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 29b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughesimport java.util.Arrays; 30f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport java.util.HashMap; 3146241f2f67d7b90e20f3301861f807f330687821Elliott Hughesimport java.util.List; 326186821cb13f4ac7ff50950c813394367e021eaeJesse Wilsonimport libcore.util.EmptyArray; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A specialized {@link InputStream} that is able to read (deserialize) Java 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * objects as well as primitive data types (int, byte, char etc.). The data has 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * typically been saved using an ObjectOutputStream. 38f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectInput 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Serializable 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Externalizable 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 4432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughespublic class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants { 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 46fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes // TODO: this is non-static to avoid sync contention. Would static be faster? 47693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes private InputStream emptyStream = new ByteArrayInputStream(EmptyArray.BYTE); 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // To put into objectsRead when reading unsharedObject 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final Object UNSHARED_OBJ = new Object(); // $NON-LOCK-1$ 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If the receiver has already read & not consumed a TC code 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean hasPushbackTC; 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Push back TC code if the variable above is true 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private byte pushbackTC; 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // How many nested levels to readObject. When we reach 0 we have to validate 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the graph then reset it 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int nestedLevels; 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // All objects are assigned an ID (integer handle) 632543351c360bdfe0046e819dedb069f3724d703aJesse Wilson private int nextHandle; 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Where we read from 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private DataInputStream input; 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Where we read primitive types from 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private DataInputStream primitiveTypes; 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Where we keep primitive type data 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private InputStream primitiveData = emptyStream; 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Resolve object is a mechanism for replacement 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean enableResolve; 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 776523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes /** 786523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes * All the objects we've read, indexed by their serialization handle (minus the base offset). 796523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes */ 806523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes private ArrayList<Object> objectsRead; 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Used by defaultReadObject 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object currentObject; 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Used by defaultReadObject 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private ObjectStreamClass currentClass; 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // All validations to be executed when the complete graph is read. See inner 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // type below. 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private InputValidationDesc[] validations; 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Allows the receiver to decide if it needs to call readObjectOverride 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean subclassOverridingImplementation; 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Original caller's class loader, used to perform class lookups 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private ClassLoader callerClassLoader; 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // false when reading missing fields 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean mustResolve = true; 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Handle for the current class descriptor 1026523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes private int descriptorHandle = -1; 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 104f24bce74a497ed281de23b7e997549725557b730Elliott Hughes private static final HashMap<String, Class<?>> PRIMITIVE_CLASSES = new HashMap<String, Class<?>>(); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 10603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes PRIMITIVE_CLASSES.put("boolean", boolean.class); 107f24bce74a497ed281de23b7e997549725557b730Elliott Hughes PRIMITIVE_CLASSES.put("byte", byte.class); 10803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes PRIMITIVE_CLASSES.put("char", char.class); 10903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes PRIMITIVE_CLASSES.put("double", double.class); 110f24bce74a497ed281de23b7e997549725557b730Elliott Hughes PRIMITIVE_CLASSES.put("float", float.class); 111f24bce74a497ed281de23b7e997549725557b730Elliott Hughes PRIMITIVE_CLASSES.put("int", int.class); 112f24bce74a497ed281de23b7e997549725557b730Elliott Hughes PRIMITIVE_CLASSES.put("long", long.class); 113f24bce74a497ed281de23b7e997549725557b730Elliott Hughes PRIMITIVE_CLASSES.put("short", short.class); 114f24bce74a497ed281de23b7e997549725557b730Elliott Hughes PRIMITIVE_CLASSES.put("void", void.class); 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Internal type used to keep track of validators & corresponding priority 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static class InputValidationDesc { 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectInputValidation validator; 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int priority; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * GetField is an inner class that provides access to the persistent fields 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read from the source stream. 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract static class GetField { 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the ObjectStreamClass that describes a field. 131f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the descriptor class for a serialized field. 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract ObjectStreamClass getObjectStreamClass(); 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates if the field identified by {@code name} is defaulted. This 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * means that it has no value in this stream. 139f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to check. 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the field is defaulted, {@code false} 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code name} does not identify a serializable field. 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract boolean defaulted(String name) throws IOException, 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IllegalArgumentException; 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the value of the boolean field identified by {@code name} from 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the persistent field. 156f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to get. 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param defaultValue 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the default value that is used if the field does not have 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value when read from the source stream. 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the field identified by {@code name}. 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the type of the field identified by {@code name} is 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not {@code boolean}. 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract boolean get(String name, boolean defaultValue) 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, IllegalArgumentException; 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the value of the character field identified by {@code name} from 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the persistent field. 176f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to get. 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param defaultValue 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the default value that is used if the field does not have 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value when read from the source stream. 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the field identified by {@code name}. 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the type of the field identified by {@code name} is 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not {@code char}. 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract char get(String name, char defaultValue) 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, IllegalArgumentException; 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the value of the byte field identified by {@code name} from the 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * persistent field. 196f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to get. 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param defaultValue 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the default value that is used if the field does not have 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value when read from the source stream. 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the field identified by {@code name}. 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the type of the field identified by {@code name} is 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not {@code byte}. 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract byte get(String name, byte defaultValue) 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, IllegalArgumentException; 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the value of the short field identified by {@code name} from the 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * persistent field. 216f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to get. 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param defaultValue 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the default value that is used if the field does not have 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value when read from the source stream. 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the field identified by {@code name}. 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the type of the field identified by {@code name} is 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not {@code short}. 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract short get(String name, short defaultValue) 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, IllegalArgumentException; 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the value of the integer field identified by {@code name} from 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the persistent field. 236f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to get. 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param defaultValue 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the default value that is used if the field does not have 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value when read from the source stream. 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the field identified by {@code name}. 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the type of the field identified by {@code name} is 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not {@code int}. 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract int get(String name, int defaultValue) 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, IllegalArgumentException; 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 253f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the value of the long field identified by {@code name} from the 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * persistent field. 256f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to get. 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param defaultValue 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the default value that is used if the field does not have 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value when read from the source stream. 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the field identified by {@code name}. 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the type of the field identified by {@code name} is 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not {@code long}. 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract long get(String name, long defaultValue) 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, IllegalArgumentException; 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the value of the float field identified by {@code name} from the 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * persistent field. 276f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to get. 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param defaultValue 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the default value that is used if the field does not have 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value when read from the source stream. 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the field identified by {@code name}. 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the type of the field identified by {@code float} is 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not {@code char}. 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract float get(String name, float defaultValue) 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, IllegalArgumentException; 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the value of the double field identified by {@code name} from 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the persistent field. 296f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to get. 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param defaultValue 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the default value that is used if the field does not have 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value when read from the source stream. 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the field identified by {@code name}. 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the type of the field identified by {@code name} is 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not {@code double}. 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract double get(String name, double defaultValue) 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, IllegalArgumentException; 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the value of the object field identified by {@code name} from 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the persistent field. 316f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the field to get. 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param defaultValue 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the default value that is used if the field does not have 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value when read from the source stream. 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the field identified by {@code name}. 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source input 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the type of the field identified by {@code name} is 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not {@code Object}. 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract Object get(String name, Object defaultValue) 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, IllegalArgumentException; 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new ObjectInputStream. This default constructor can be used 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by subclasses that do not want to use the public constructor if it 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * allocates unneeded data. 338f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs when creating this stream. 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 3422f2001f2f769c710ce7ee63412d3e2580388bf4dElliott Hughes protected ObjectInputStream() throws IOException { 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // WARNING - we should throw IOException if not called from a subclass 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // according to the JavaDoc. Add the test. 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.subclassOverridingImplementation = true; 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new ObjectInputStream that reads from the InputStream 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code input}. 351f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the non-null source InputStream to filter reads on. 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading the stream header. 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws StreamCorruptedException 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the source stream does not contain serialized objects that 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * can be read. 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 360ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes public ObjectInputStream(InputStream input) throws StreamCorruptedException, IOException { 361ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes this.input = (input instanceof DataInputStream) 362ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes ? (DataInputStream) input : new DataInputStream(input); 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveTypes = new DataInputStream(this); 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project enableResolve = false; 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.subclassOverridingImplementation = false; 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project resetState(); 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nestedLevels = 0; 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // So read...() methods can be used by 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // subclasses during readStreamHeader() 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = this.input; 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Has to be done here according to the specification 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readStreamHeader(); 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = emptyStream; 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int available() throws IOException { 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // returns 0 if next data is an object, or N if reading primitive types 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkReadPrimitiveTypes(); 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveData.available(); 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks to if it is ok to read primitive types from this stream at 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this point. One is not supposed to read primitive types when about to 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read an object, for example, so an exception has to be thrown. 387f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If any IO problem occurred when trying to read primitive type 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * or if it is illegal to read primitive types 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkReadPrimitiveTypes() throws IOException { 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If we still have primitive data, it is ok to read primitive data 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (primitiveData == input || primitiveData.available() > 0) { 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If we got here either we had no Stream previously created or 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // we no longer have data in that one, so get more bytes 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project do { 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int next = 0; 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (hasPushbackTC) { 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project hasPushbackTC = false; 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project next = input.read(); 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pushbackTC = (byte) next; 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (pushbackTC) { 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_BLOCKDATA: 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = new ByteArrayInputStream(readBlockData()); 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_BLOCKDATALONG: 413b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes primitiveData = new ByteArrayInputStream(readBlockDataLong()); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_RESET: 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project resetState(); 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (next != -1) { 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pushbackTC(); 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Only TC_RESET falls through 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } while (true); 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes this stream. This implementation closes the source stream. 430f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while closing this stream. 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project input.close(); 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Default method to read objects from this stream. Serializable fields 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * defined in the object's class and superclasses are read from the source 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 443f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the object's class cannot be found. 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs while reading the object data. 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NotActiveException 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this method is not called from {@code readObject()}. 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream#defaultWriteObject 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void defaultReadObject() throws IOException, ClassNotFoundException, 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NotActiveException { 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (currentObject != null || !mustResolve) { 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readFieldValues(currentObject, currentClass); 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NotActiveException(); 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Enables object replacement for this stream. By default this is not 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * enabled. Only trusted subclasses (loaded with system class loader) are 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * allowed to change this status. 465f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param enable 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code true} to enable object replacement; {@code false} to 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * disable it. 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the previous setting. 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #resolveObject 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream#enableReplaceObject 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 4732f2001f2f769c710ce7ee63412d3e2580388bf4dElliott Hughes protected boolean enableResolveObject(boolean enable) { 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean originalValue = enableResolve; 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project enableResolve = enable; 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return originalValue; 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return the next {@code int} handle to be used to indicate cyclic 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * references being loaded from the stream. 482f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the next handle to represent the next cyclic reference 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 4856523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes private int nextHandle() { 4862543351c360bdfe0046e819dedb069f3724d703aJesse Wilson return nextHandle++; 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return the next token code (TC) from the receiver, which indicates what 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * kind of object follows 492f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the next TC from the receiver 494f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO error occurs 497f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectStreamConstants 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private byte nextTC() throws IOException { 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (hasPushbackTC) { 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project hasPushbackTC = false; // We are consuming it 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Just in case a later call decides to really push it back, 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // we don't require the caller to pass it as parameter 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pushbackTC = input.readByte(); 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return pushbackTC; 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Pushes back the last TC code read 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void pushbackTC() { 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project hasPushbackTC = true; 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a single byte from the source stream and returns it as an integer 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in the range from 0 to 255. Returns -1 if the end of the source stream 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has been reached. Blocks if no input is available. 522f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the byte read or -1 if the end of the source stream has been 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reached. 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from this stream. 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkReadPrimitiveTypes(); 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveData.read(); 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads at most {@code length} bytes from the source stream and stores them 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in byte array {@code buffer} starting at offset {@code count}. Blocks 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * until {@code count} bytes have been read, the end of the source stream is 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * detected or an exception is thrown. 539f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buffer 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the array in which to store the bytes read. 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the initial position in {@code buffer} to store the bytes 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read from the source stream. 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param length 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the maximum number of bytes to store in {@code buffer}. 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes read or -1 if the end of the source input 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream has been reached. 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code offset < 0} or {@code length < 0}, or if 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code offset + length} is greater than the length of 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buffer}. 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from this stream. 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code buffer} is {@code null}. 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(byte[] buffer, int offset, int length) throws IOException { 560b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes Arrays.checkOffsetAndCount(buffer.length, offset, length); 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (length == 0) { 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkReadPrimitiveTypes(); 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveData.read(buffer, offset, length); 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads and returns an array of raw bytes with primitive data. The array 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will have up to 255 bytes. The primitive data will be in the format 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * described by {@code DataOutputStream}. 572f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return The primitive data read, as raw bytes 574f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the primitive data. 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private byte[] readBlockData() throws IOException { 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] result = new byte[input.readByte() & 0xff]; 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project input.readFully(result); 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads and returns an array of raw bytes with primitive data. The array 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will have more than 255 bytes. The primitive data will be in the format 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * described by {@code DataOutputStream}. 588f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return The primitive data read, as raw bytes 590f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the primitive data. 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private byte[] readBlockDataLong() throws IOException { 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] result = new byte[input.readInt()]; 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project input.readFully(result); 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a boolean from the source stream. 602f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the boolean value read from the source stream. 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean readBoolean() throws IOException { 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readBoolean(); 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a byte (8 bit) from the source stream. 616f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the byte value read from the source stream. 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte readByte() throws IOException { 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readByte(); 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a character (16 bit) from the source stream. 630f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the char value read from the source stream. 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public char readChar() throws IOException { 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readChar(); 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads and discards block data and objects until TC_ENDBLOCKDATA is found. 644f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the optional class 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * annotation. 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the class corresponding to the class descriptor could not 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void discardData() throws ClassNotFoundException, IOException { 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = emptyStream; 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean resolve = mustResolve; 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mustResolve = false; 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project do { 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte tc = nextTC(); 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (tc == TC_ENDBLOCKDATA) { 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mustResolve = resolve; 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; // End of annotation 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readContent(tc); 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } while (true); 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a class descriptor (an {@code ObjectStreamClass}) from the 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. 669f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the class descriptor read from the stream 671f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the class 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor. 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the class corresponding to the class descriptor could not 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 679b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes private ObjectStreamClass readClassDesc() throws ClassNotFoundException, IOException { 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte tc = nextTC(); 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (tc) { 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_CLASSDESC: 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewClassDesc(false); 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_PROXYCLASSDESC: 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> proxyClass = readNewProxyClassDesc(); 686693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes ObjectStreamClass streamClass = ObjectStreamClass.lookup(proxyClass); 687693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes streamClass.setLoadFields(ObjectStreamClass.NO_FIELDS); 688f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson registerObjectRead(streamClass, nextHandle(), false); 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkedSetSuperClassDesc(streamClass, readClassDesc()); 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return streamClass; 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_REFERENCE: 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (ObjectStreamClass) readCyclicReference(); 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_NULL: 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 696b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw corruptStream(tc); 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 700b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes private StreamCorruptedException corruptStream(byte tc) throws StreamCorruptedException { 701b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new StreamCorruptedException("Wrong format: " + Integer.toHexString(tc & 0xff)); 702b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 703b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads the content of the receiver based on the previously read token 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code tc}. 707f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param tc 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The token code for the next item in the stream 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the object read from the stream 711f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the class 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor. 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the class corresponding to the object being read could not 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object readContent(byte tc) throws ClassNotFoundException, 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IOException { 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (tc) { 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_BLOCKDATA: 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readBlockData(); 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_BLOCKDATALONG: 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readBlockDataLong(); 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_CLASS: 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewClass(false); 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_CLASSDESC: 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewClassDesc(false); 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_ARRAY: 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewArray(false); 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_OBJECT: 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewObject(false); 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_STRING: 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewString(false); 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_LONGSTRING: 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewLongString(false); 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_REFERENCE: 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readCyclicReference(); 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_NULL: 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_EXCEPTION: 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Exception exc = readException(); 744b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new WriteAbortedException("Read an exception", exc); 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_RESET: 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project resetState(); 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 749b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw corruptStream(tc); 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads the content of the receiver based on the previously read token 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code tc}. Primitive data content is considered an error. 756f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param unshared 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read the object unshared 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the object read from the stream 760f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the class 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor. 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the class corresponding to the object being read could not 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object readNonPrimitiveContent(boolean unshared) 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws ClassNotFoundException, IOException { 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkReadPrimitiveTypes(); 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (primitiveData.available() > 0) { 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project OptionalDataException e = new OptionalDataException(); 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e.length = primitiveData.available(); 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project do { 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte tc = nextTC(); 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (tc) { 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_CLASS: 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewClass(unshared); 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_CLASSDESC: 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewClassDesc(unshared); 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_ARRAY: 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewArray(unshared); 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_OBJECT: 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewObject(unshared); 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_STRING: 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewString(unshared); 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_LONGSTRING: 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readNewLongString(unshared); 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_ENUM: 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readEnum(unshared); 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_REFERENCE: 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (unshared) { 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readNewHandle(); 797b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new InvalidObjectException("Unshared read of back reference"); 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readCyclicReference(); 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_NULL: 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_EXCEPTION: 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Exception exc = readException(); 804b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new WriteAbortedException("Read an exception", exc); 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_RESET: 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project resetState(); 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_ENDBLOCKDATA: // Can occur reading class annotation 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pushbackTC(); 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project OptionalDataException e = new OptionalDataException(); 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e.eof = true; 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 814b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw corruptStream(tc); 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Only TC_RESET falls through 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } while (true); 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads the next item from the stream assuming it is a cyclic reference to 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an object previously read. Return the actual object previously read. 823f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the object previously read from the stream 825f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the class 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor. 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidObjectException 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the cyclic reference is not valid. 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8326523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes private Object readCyclicReference() throws InvalidObjectException, IOException { 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return registeredObjectRead(readNewHandle()); 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a double (64 bit) from the source stream. 838f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the double value read from the source stream. 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public double readDouble() throws IOException { 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readDouble(); 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Read the next item assuming it is an exception. The exception is not a 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * regular instance in the object graph, but the exception instance that 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * happened (if any) when dumping the original object graph. The set of seen 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * objects will be reset just before and just after loading this exception 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When exceptions are found normally in the object graph, they are loaded 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * as a regular object, and not by this method. In that case, the set of 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "known objects" is not reset. 860f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the exception read 862f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the exception 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If a class could not be found when reading the object graph 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the exception 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws OptionalDataException 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If optional data could not be found when reading the 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exception graph 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws WriteAbortedException 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If another exception was caused when dumping this exception 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Exception readException() throws WriteAbortedException, 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project OptionalDataException, ClassNotFoundException, IOException { 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project resetSeenObjects(); 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Now we read the Throwable object that was saved 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // WARNING - the grammar says it is a Throwable, but the 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // WriteAbortedException constructor takes an Exception. So, we read an 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Exception from the stream 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Exception exc = (Exception) readObject(); 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We reset the receiver's state (the grammar has "reset" in normal 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // font) 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project resetSeenObjects(); 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return exc; 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a collection of field descriptors (name, type name, etc) for the 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class descriptor {@code cDesc} (an {@code ObjectStreamClass}) 895f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cDesc 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The class descriptor (an {@code ObjectStreamClass}) 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for which to write field information 899f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the field 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptors. 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If a class for one of the field types could not be found 905f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #readObject() 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void readFieldDescriptors(ObjectStreamClass cDesc) 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws ClassNotFoundException, IOException { 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project short numFields = input.readShort(); 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField[] fields = new ObjectStreamField[numFields]; 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We set it now, but each element will be inserted in the array further 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // down 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cDesc.setLoadFields(fields); 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Check ObjectOutputStream.writeFieldDescriptors 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (short i = 0; i < numFields; i++) { 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char typecode = (char) input.readByte(); 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String fieldName = input.readUTF(); 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean isPrimType = ObjectStreamClass.isPrimitiveType(typecode); 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String classSig; 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isPrimType) { 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project classSig = String.valueOf(typecode); 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The spec says it is a UTF, but experience shows they dump 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // this String using writeObject (unlike the field name, which 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // is saved with writeUTF). 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // And if resolveObject is enabled, the classSig may be modified 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // so that the original class descriptor cannot be read 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // properly, so it is disabled. 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean old = enableResolve; 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project enableResolve = false; 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project classSig = (String) readObject(); 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project enableResolve = old; 938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 940f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 941f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson classSig = formatClassSig(classSig); 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField f = new ObjectStreamField(classSig, fieldName); 943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fields[i] = f; 944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 947f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /* 948f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Format the class signature for ObjectStreamField, for example, 949f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * "[L[Ljava.lang.String;;" is converted to "[Ljava.lang.String;" 950f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 951f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private static String formatClassSig(String classSig) { 952f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int start = 0; 953f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int end = classSig.length(); 954f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 955f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (end <= 0) { 956f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return classSig; 957f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 958f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 95903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes while (classSig.startsWith("[L", start) 960f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson && classSig.charAt(end - 1) == ';') { 961f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson start += 2; 962f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson end--; 963f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 964f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 965f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (start > 0) { 966f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson start -= 2; 967f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson end++; 968f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return classSig.substring(start, end); 969f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 970f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return classSig; 971f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 972f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads the persistent fields of the object that is currently being read 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from the source stream. The values read are stored in a GetField object 976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that provides access to the persistent fields. This GetField object is 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * then returned. 978f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the GetField object from which persistent fields can be accessed 980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by name. 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the class of an object being deserialized can not be 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * found. 984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from this stream. 986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NotActiveException 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this stream is currently not reading an object. 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 989b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes public GetField readFields() throws IOException, ClassNotFoundException, NotActiveException { 990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (currentObject == null) { 991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NotActiveException(); 992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 99308d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes EmulatedFieldsForLoading result = new EmulatedFieldsForLoading(currentClass); 994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readFieldValues(result); 995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a collection of field values for the emulated fields 1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code emulatedFields} 1001f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param emulatedFields 1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an {@code EmulatedFieldsForLoading}, concrete subclass 1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of {@code GetField} 1005f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the field values. 1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidClassException 1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an incompatible type is being assigned to an emulated 1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * field. 1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws OptionalDataException 1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If optional data could not be found when reading the 1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exception graph 1014f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #readFields 1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #readObject() 1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void readFieldValues(EmulatedFieldsForLoading emulatedFields) 1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws OptionalDataException, InvalidClassException, IOException { 1020b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes EmulatedFields.ObjectSlot[] slots = emulatedFields.emulatedFields().slots(); 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (ObjectSlot element : slots) { 1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project element.defaulted = false; 1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> type = element.field.getType(); 1024e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes if (type == int.class) { 10252543351c360bdfe0046e819dedb069f3724d703aJesse Wilson element.fieldValue = input.readInt(); 1026e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == byte.class) { 10272543351c360bdfe0046e819dedb069f3724d703aJesse Wilson element.fieldValue = input.readByte(); 1028e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == char.class) { 10292543351c360bdfe0046e819dedb069f3724d703aJesse Wilson element.fieldValue = input.readChar(); 1030e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == short.class) { 10312543351c360bdfe0046e819dedb069f3724d703aJesse Wilson element.fieldValue = input.readShort(); 1032e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == boolean.class) { 10332543351c360bdfe0046e819dedb069f3724d703aJesse Wilson element.fieldValue = input.readBoolean(); 1034e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == long.class) { 10352543351c360bdfe0046e819dedb069f3724d703aJesse Wilson element.fieldValue = input.readLong(); 1036e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == float.class) { 10372543351c360bdfe0046e819dedb069f3724d703aJesse Wilson element.fieldValue = input.readFloat(); 1038e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == double.class) { 10392543351c360bdfe0046e819dedb069f3724d703aJesse Wilson element.fieldValue = input.readDouble(); 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Either array or Object 1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project element.fieldValue = readObject(); 1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (ClassNotFoundException cnf) { 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // WARNING- Not sure this is the right thing to do. Write 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // test case. 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new InvalidClassException(cnf.toString()); 1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a collection of field values for the class descriptor 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code classDesc} (an {@code ObjectStreamClass}). The 1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * values will be used to set instance fields in object {@code obj}. 1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is the default mechanism, when emulated fields (an 1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code GetField}) are not used. Actual values to load are stored 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directly into the object {@code obj}. 1060f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj 1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Instance in which the fields will be set. 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param classDesc 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A class descriptor (an {@code ObjectStreamClass}) 1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * defining which fields should be loaded. 1066f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the field values. 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidClassException 1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an incompatible type is being assigned to an emulated 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * field. 1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws OptionalDataException 1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If optional data could not be found when reading the 1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exception graph 1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If a class of an object being de-serialized can not be found 1077f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #readFields 1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #readObject() 1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1081b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes private void readFieldValues(Object obj, ObjectStreamClass classDesc) throws OptionalDataException, ClassNotFoundException, IOException { 1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Now we must read all fields and assign them to the receiver 1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField[] fields = classDesc.getLoadFields(); 1084b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes fields = (fields == null) ? ObjectStreamClass.NO_FIELDS : fields; 1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> declaringClass = classDesc.forClass(); 1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (declaringClass == null && mustResolve) { 1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassNotFoundException(classDesc.getName()); 1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (ObjectStreamField fieldDesc : fields) { 1091b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes Field field = classDesc.getReflectionField(fieldDesc); 1092bd8dfd99b523583c3b5e662975638643e17874eaBrian Carlstrom if (field != null && Modifier.isTransient(field.getModifiers())) { 109305895faacf43e6fd2bcd57baed31832f6888cb31Elliott Hughes field = null; // No setting transient fields! (http://b/4471249) 109405895faacf43e6fd2bcd57baed31832f6888cb31Elliott Hughes } 109505895faacf43e6fd2bcd57baed31832f6888cb31Elliott Hughes // We may not have been able to find the field, or it may be transient, but we still 109605895faacf43e6fd2bcd57baed31832f6888cb31Elliott Hughes // need to read the value and do the other checking... 1097b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes try { 10986c9fda83af2a99ab25cf5ad0487c6d4c6f1e7cb1Elliott Hughes Class<?> type = fieldDesc.getTypeInternal(); 1099e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes if (type == byte.class) { 1100b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes byte b = input.readByte(); 1101b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes if (field != null) { 1102b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes field.setByte(obj, b); 1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1104e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == char.class) { 1105b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes char c = input.readChar(); 1106b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes if (field != null) { 1107b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes field.setChar(obj, c); 1108b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes } 1109e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == double.class) { 1110b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes double d = input.readDouble(); 1111b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes if (field != null) { 1112b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes field.setDouble(obj, d); 1113b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes } 1114e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == float.class) { 1115b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes float f = input.readFloat(); 1116b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes if (field != null) { 1117b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes field.setFloat(obj, f); 1118b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes } 1119e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == int.class) { 1120b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes int i = input.readInt(); 1121b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes if (field != null) { 1122b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes field.setInt(obj, i); 1123b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes } 1124e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == long.class) { 1125b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes long j = input.readLong(); 1126b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes if (field != null) { 1127b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes field.setLong(obj, j); 1128b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes } 1129e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == short.class) { 1130b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes short s = input.readShort(); 1131b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes if (field != null) { 1132b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes field.setShort(obj, s); 1133b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes } 1134e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (type == boolean.class) { 1135b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes boolean z = input.readBoolean(); 1136b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes if (field != null) { 1137b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes field.setBoolean(obj, z); 1138b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes } 11396c9fda83af2a99ab25cf5ad0487c6d4c6f1e7cb1Elliott Hughes } else { 1140685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes Object toSet = fieldDesc.isUnshared() ? readUnshared() : readObject(); 1141685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes if (toSet != null) { 1142685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes // Get the field type from the local field rather than 1143685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes // from the stream's supplied data. That's the field 1144685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes // we'll be setting, so that's the one that needs to be 1145685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes // validated. 1146685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes String fieldName = fieldDesc.getName(); 1147685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes ObjectStreamField localFieldDesc = classDesc.getField(fieldName); 1148685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes Class<?> fieldType = localFieldDesc.getTypeInternal(); 1149685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes Class<?> valueType = toSet.getClass(); 1150685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes if (!fieldType.isAssignableFrom(valueType)) { 1151685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes throw new ClassCastException(classDesc.getName() + "." + fieldName + " - " + fieldType + " not compatible with " + valueType); 1152685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes } 1153685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes if (field != null) { 1154685f9f54501631ef05a9379fa865004dc33a2ae5Elliott Hughes field.set(obj, toSet); 1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1158b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes } catch (IllegalAccessException iae) { 1159b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes // ObjectStreamField should have called setAccessible(true). 1160b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes throw new AssertionError(iae); 1161b854a55df2475a4e9acc96c271cd88da7559f019Elliott Hughes } catch (NoSuchFieldError ignored) { 1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a float (32 bit) from the source stream. 1168f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the float value read from the source stream. 1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public float readFloat() throws IOException { 1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readFloat(); 1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 11810eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes * Reads bytes from the source stream into the byte array {@code dst}. 11820eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes * This method will block until {@code dst.length} bytes have been read. 1183f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 11840eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes * @param dst 1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the array in which to store the bytes read. 1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11920eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes public void readFully(byte[] dst) throws IOException { 11930eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes primitiveTypes.readFully(dst); 1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 11970eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes * Reads {@code byteCount} bytes from the source stream into the byte array {@code dst}. 1198f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 11990eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes * @param dst 1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the byte array in which to store the bytes read. 1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 12020eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes * the initial position in {@code dst} to store the bytes 1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read from the source stream. 12040eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes * @param byteCount 12050eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes * the number of bytes to read. 1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 12120eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes public void readFully(byte[] dst, int offset, int byteCount) throws IOException { 12130eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes primitiveTypes.readFully(dst, offset, byteCount); 1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Walks the hierarchy of classes described by class descriptor 1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code classDesc} and reads the field values corresponding to 1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * fields declared by the corresponding class descriptor. The instance to 1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * store field values into is {@code object}. If the class 1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (corresponding to class descriptor {@code classDesc}) defines 1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * private instance method {@code readObject} it will be used to load 1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * field values. 1224f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param object 1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Instance into which stored field values loaded. 1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param classDesc 1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A class descriptor (an {@code ObjectStreamClass}) 1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * defining which fields should be loaded. 1230f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the field values in 1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the hierarchy. 1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If a class for one of the field types could not be found 1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NotActiveException 1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If {@code defaultReadObject} is called from the wrong 1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * context. 1239f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #defaultReadObject 1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #readObject() 1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void readHierarchy(Object object, ObjectStreamClass classDesc) 1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, ClassNotFoundException, NotActiveException { 1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (object == null && mustResolve) { 1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NotActiveException(); 1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 124946241f2f67d7b90e20f3301861f807f330687821Elliott Hughes List<ObjectStreamClass> streamClassList = classDesc.getHierarchy(); 1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (object == null) { 12512543351c360bdfe0046e819dedb069f3724d703aJesse Wilson for (ObjectStreamClass objectStreamClass : streamClassList) { 12522543351c360bdfe0046e819dedb069f3724d703aJesse Wilson readObjectForClass(null, objectStreamClass); 1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 125508d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes List<Class<?>> superclasses = cachedSuperclasses.get(object.getClass()); 125608d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes if (superclasses == null) { 125708d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes superclasses = cacheSuperclassesFor(object.getClass()); 1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 125908d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int lastIndex = 0; 126108d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes for (int i = 0, end = superclasses.size(); i < end; ++i) { 126208d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes Class<?> superclass = superclasses.get(i); 12632543351c360bdfe0046e819dedb069f3724d703aJesse Wilson int index = findStreamSuperclass(superclass, streamClassList, lastIndex); 1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (index == -1) { 12652543351c360bdfe0046e819dedb069f3724d703aJesse Wilson readObjectNoData(object, superclass, 12662543351c360bdfe0046e819dedb069f3724d703aJesse Wilson ObjectStreamClass.lookupStreamClass(superclass)); 1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int j = lastIndex; j <= index; j++) { 1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readObjectForClass(object, streamClassList.get(j)); 1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastIndex = index + 1; 1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 127708d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes private HashMap<Class<?>, List<Class<?>>> cachedSuperclasses = new HashMap<Class<?>, List<Class<?>>>(); 127808d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes 127908d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes private List<Class<?>> cacheSuperclassesFor(Class<?> c) { 128008d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes ArrayList<Class<?>> result = new ArrayList<Class<?>>(); 128108d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes Class<?> nextClass = c; 128208d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes while (nextClass != null) { 128308d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes Class<?> testClass = nextClass.getSuperclass(); 128408d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes if (testClass != null) { 128508d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes result.add(0, nextClass); 128608d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes } 128708d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes nextClass = testClass; 128808d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes } 128908d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes cachedSuperclasses.put(c, result); 129008d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes return result; 129108d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes } 129208d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes 129346241f2f67d7b90e20f3301861f807f330687821Elliott Hughes private int findStreamSuperclass(Class<?> cl, List<ObjectStreamClass> classList, int lastIndex) { 129408d5f1955b94e07e337c59b63a7051879fa3bbefElliott Hughes for (int i = lastIndex, end = classList.size(); i < end; i++) { 129546241f2f67d7b90e20f3301861f807f330687821Elliott Hughes ObjectStreamClass objCl = classList.get(i); 129646241f2f67d7b90e20f3301861f807f330687821Elliott Hughes String forName = objCl.forClass().getName(); 1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (objCl.getName().equals(forName)) { 1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cl.getName().equals(objCl.getName())) { 1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return i; 1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // there was a class replacement 1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cl.getName().equals(forName)) { 1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return i; 1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1312f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private void readObjectNoData(Object object, Class<?> cl, ObjectStreamClass classDesc) 1313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws ObjectStreamException { 1314f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (!classDesc.isSerializable()) { 1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1317f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (classDesc.hasMethodReadObjectNoData()){ 1318f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson final Method readMethod = classDesc.getMethodReadObjectNoData(); 1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 13202543351c360bdfe0046e819dedb069f3724d703aJesse Wilson readMethod.invoke(object); 1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InvocationTargetException e) { 1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Throwable ex = e.getTargetException(); 1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ex instanceof RuntimeException) { 1324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (RuntimeException) ex; 1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (ex instanceof Error) { 1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (Error) ex; 1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (ObjectStreamException) ex; 1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IllegalAccessException e) { 1330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new RuntimeException(e.toString()); 1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1333f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void readObjectForClass(Object object, ObjectStreamClass classDesc) 1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, ClassNotFoundException, NotActiveException { 1338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Have to do this before calling defaultReadObject or anything that 1339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // calls defaultReadObject 1340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentObject = object; 1341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentClass = classDesc; 1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 134332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes boolean hadWriteMethod = (classDesc.getFlags() & SC_WRITE_METHOD) != 0; 1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> targetClass = classDesc.forClass(); 1345f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final Method readMethod; 1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (targetClass == null || !mustResolve) { 1348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readMethod = null; 1349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1350f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson readMethod = classDesc.getMethodReadObject(); 1351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (readMethod != null) { 1354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We have to be able to fetch its value, even if it is private 1355ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes readMethod.setAccessible(true); 1356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 13572543351c360bdfe0046e819dedb069f3724d703aJesse Wilson readMethod.invoke(object, this); 1358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InvocationTargetException e) { 1359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Throwable ex = e.getTargetException(); 1360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ex instanceof ClassNotFoundException) { 1361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (ClassNotFoundException) ex; 1362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (ex instanceof RuntimeException) { 1363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (RuntimeException) ex; 1364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (ex instanceof Error) { 1365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (Error) ex; 1366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (IOException) ex; 1368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IllegalAccessException e) { 1369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new RuntimeException(e.toString()); 1370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project defaultReadObject(); 1373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (hadWriteMethod) { 1375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project discardData(); 1376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 1378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Cleanup, needs to run always so that we can later detect invalid 1379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // calls to defaultReadObject 1380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentObject = null; // We did not set this, so we do not need to 1381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // clean it 1382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentClass = null; 1383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads an integer (32 bit) from the source stream. 1388f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the integer value read from the source stream. 1390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 1391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 1392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 1393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int readInt() throws IOException { 1397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readInt(); 1398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1401f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Reads the next line from the source stream. Lines are terminated by 1402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code '\r'}, {@code '\n'}, {@code "\r\n"} or an {@code EOF}. 1403f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the string read from the source stream. 1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @deprecated Use {@link BufferedReader} 1408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Deprecated 1410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String readLine() throws IOException { 1411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readLine(); 1412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a long (64 bit) from the source stream. 1416f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the long value read from the source stream. 1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 1419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 1420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 1421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long readLong() throws IOException { 1425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readLong(); 1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Read a new array from the receiver. It is assumed the array has not been 1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read yet (not a cyclic reference). Return the array read. 1431f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param unshared 1433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read the object unshared 1434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array read 1435f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the array. 1438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If a class for one of the objects could not be found 1440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws OptionalDataException 1441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If optional data could not be found when reading the array. 1442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object readNewArray(boolean unshared) throws OptionalDataException, 1444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassNotFoundException, IOException { 1445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass classDesc = readClassDesc(); 1446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (classDesc == null) { 14482543351c360bdfe0046e819dedb069f3724d703aJesse Wilson throw missingClassDescriptor(); 1449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 14516523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes int newHandle = nextHandle(); 1452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Array size 1454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int size = input.readInt(); 1455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> arrayClass = classDesc.forClass(); 1456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> componentType = arrayClass.getComponentType(); 1457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object result = Array.newInstance(componentType, size); 1458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project registerObjectRead(result, newHandle, unshared); 1460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Now we have code duplication just because Java is typed. We have to 1462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // read N elements and assign to array positions, but we must typecast 1463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the array first, and also call different methods depending on the 1464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // elements. 1465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (componentType.isPrimitive()) { 1466e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes if (componentType == int.class) { 1467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] intArray = (int[]) result; 1468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < size; i++) { 1469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project intArray[i] = input.readInt(); 1470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1471e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (componentType == byte.class) { 1472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] byteArray = (byte[]) result; 1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project input.readFully(byteArray, 0, size); 1474e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (componentType == char.class) { 1475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] charArray = (char[]) result; 1476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < size; i++) { 1477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project charArray[i] = input.readChar(); 1478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1479e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (componentType == short.class) { 1480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project short[] shortArray = (short[]) result; 1481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < size; i++) { 1482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project shortArray[i] = input.readShort(); 1483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1484e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (componentType == boolean.class) { 1485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean[] booleanArray = (boolean[]) result; 1486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < size; i++) { 1487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project booleanArray[i] = input.readBoolean(); 1488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1489e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (componentType == long.class) { 1490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long[] longArray = (long[]) result; 1491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < size; i++) { 1492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project longArray[i] = input.readLong(); 1493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1494e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (componentType == float.class) { 1495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project float[] floatArray = (float[]) result; 1496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < size; i++) { 1497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project floatArray[i] = input.readFloat(); 1498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1499e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes } else if (componentType == double.class) { 1500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project double[] doubleArray = (double[]) result; 1501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < size; i++) { 1502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project doubleArray[i] = input.readDouble(); 1503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1505b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new ClassNotFoundException("Wrong base type in " + classDesc.getName()); 1506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Array of Objects 1509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object[] objectArray = (Object[]) result; 1510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < size; i++) { 1511f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // TODO: This place is the opportunity for enhancement 1512f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // We can implement writing elements through fast-path, 1513f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // without setting up the context (see readObject()) for 1514f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // each element with public API 1515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project objectArray[i] = readObject(); 1516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (enableResolve) { 1519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = resolveObject(result); 1520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project registerObjectRead(result, newHandle, false); 1521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 1523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a new class from the receiver. It is assumed the class has not been 1527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read yet (not a cyclic reference). Return the class read. 1528f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param unshared 1530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read the object unshared 1531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return The {@code java.lang.Class} read from the stream. 1532f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the class. 1535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If a class for one of the objects could not be found 1537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1538b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes private Class<?> readNewClass(boolean unshared) throws ClassNotFoundException, IOException { 1539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass classDesc = readClassDesc(); 1540b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes if (classDesc == null) { 15412543351c360bdfe0046e819dedb069f3724d703aJesse Wilson throw missingClassDescriptor(); 1542b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 1543b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes Class<?> localClass = classDesc.forClass(); 1544b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes if (localClass != null) { 1545b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes registerObjectRead(localClass, nextHandle(), unshared); 1546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1547b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes return localClass; 1548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read class type for Enum, note there's difference between enum and normal 1552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * classes 1553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private ObjectStreamClass readEnumDesc() throws IOException, 1555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassNotFoundException { 1556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte tc = nextTC(); 1557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (tc) { 1558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_CLASSDESC: 1559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readEnumDescInternal(); 1560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_REFERENCE: 1561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (ObjectStreamClass) readCyclicReference(); 1562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_NULL: 1563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 1565b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw corruptStream(tc); 1566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 15696523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes private ObjectStreamClass readEnumDescInternal() throws IOException, ClassNotFoundException { 1570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass classDesc; 1571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = input; 15726523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes int oldHandle = descriptorHandle; 1573f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson descriptorHandle = nextHandle(); 1574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project classDesc = readClassDescriptor(); 1575f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson registerObjectRead(classDesc, descriptorHandle, false); 1576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project descriptorHandle = oldHandle; 1577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = emptyStream; 1578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project classDesc.setClass(resolveClass(classDesc)); 1579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Consume unread class annotation data and TC_ENDBLOCKDATA 1580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project discardData(); 1581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass superClass = readClassDesc(); 1582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkedSetSuperClassDesc(classDesc, superClass); 1583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Check SUIDs, note all SUID for Enum is 0L 1584b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes if (0L != classDesc.getSerialVersionUID() || 0L != superClass.getSerialVersionUID()) { 1585b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new InvalidClassException(superClass.getName(), 1586b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes "Incompatible class (SUID): " + superClass + " but expected " + superClass); 1587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte tc = nextTC(); 1589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // discard TC_ENDBLOCKDATA after classDesc if any 1590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (tc == TC_ENDBLOCKDATA) { 1591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // read next parent class. For enum, it may be null 1592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project superClass.setSuperclass(readClassDesc()); 1593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // not TC_ENDBLOCKDATA, push back for next read 1595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pushbackTC(); 1596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return classDesc; 1598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked")// For the Enum.valueOf call 1601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object readEnum(boolean unshared) throws OptionalDataException, 1602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassNotFoundException, IOException { 1603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // read classdesc for Enum first 1604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass classDesc = readEnumDesc(); 16056523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes int newHandle = nextHandle(); 1606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // read name after class desc 1607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name; 1608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte tc = nextTC(); 1609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (tc) { 1610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_REFERENCE: 1611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (unshared) { 1612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readNewHandle(); 1613b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new InvalidObjectException("Unshared read of back reference"); 1614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = (String) readCyclicReference(); 1616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 1617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TC_STRING: 1618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = (String) readNewString(unshared); 1619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 1620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 1621b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw corruptStream(tc); 1622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 162419388c1ccaff3ac404956e2d13a69748c17eee72Jesse Wilson Enum<?> result; 162519388c1ccaff3ac404956e2d13a69748c17eee72Jesse Wilson try { 162619388c1ccaff3ac404956e2d13a69748c17eee72Jesse Wilson result = Enum.valueOf((Class) classDesc.forClass(), name); 162719388c1ccaff3ac404956e2d13a69748c17eee72Jesse Wilson } catch (IllegalArgumentException e) { 162819388c1ccaff3ac404956e2d13a69748c17eee72Jesse Wilson throw new InvalidObjectException(e.getMessage()); 162919388c1ccaff3ac404956e2d13a69748c17eee72Jesse Wilson } 1630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project registerObjectRead(result, newHandle, unshared); 1631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 1632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a new class descriptor from the receiver. It is assumed the class 1636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor has not been read yet (not a cyclic reference). Return the 1637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class descriptor read. 1638f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param unshared 1640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read the object unshared 1641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return The {@code ObjectStreamClass} read from the stream. 1642f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the class 1645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor. 1646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If a class for one of the objects could not be found 1648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private ObjectStreamClass readNewClassDesc(boolean unshared) 1650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws ClassNotFoundException, IOException { 1651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // So read...() methods can be used by 1652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // subclasses during readClassDescriptor() 1653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = input; 16546523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes int oldHandle = descriptorHandle; 1655f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson descriptorHandle = nextHandle(); 1656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass newClassDesc = readClassDescriptor(); 1657f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson registerObjectRead(newClassDesc, descriptorHandle, unshared); 1658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project descriptorHandle = oldHandle; 1659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = emptyStream; 1660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We need to map classDesc to class. 1662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newClassDesc.setClass(resolveClass(newClassDesc)); 1664f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Check SUIDs & base name of the class 1665f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson verifyAndInit(newClassDesc); 1666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (ClassNotFoundException e) { 1667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mustResolve) { 1668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 1669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Just continue, the class may not be required 1670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Resolve the field signatures using the class loader of the 1674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // resolved class 1675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField[] fields = newClassDesc.getLoadFields(); 1676b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes fields = (fields == null) ? ObjectStreamClass.NO_FIELDS : fields; 1677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassLoader loader = newClassDesc.forClass() == null ? callerClassLoader 1678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project : newClassDesc.forClass().getClassLoader(); 1679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (ObjectStreamField element : fields) { 1680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project element.resolve(loader); 1681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Consume unread class annotation data and TC_ENDBLOCKDATA 1684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project discardData(); 1685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkedSetSuperClassDesc(newClassDesc, readClassDesc()); 1686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return newClassDesc; 1687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a new proxy class descriptor from the receiver. It is assumed the 1691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * proxy class descriptor has not been read yet (not a cyclic reference). 1692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return the proxy class descriptor read. 1693f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return The {@code Class} read from the stream. 1695f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the class 1698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor. 1699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If a class for one of the objects could not be found 1701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Class<?> readNewProxyClassDesc() throws ClassNotFoundException, 1703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IOException { 1704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int count = input.readInt(); 1705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] interfaceNames = new String[count]; 1706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < count; i++) { 1707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project interfaceNames[i] = input.readUTF(); 1708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> proxy = resolveProxyClass(interfaceNames); 1710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Consume unread class annotation data and TC_ENDBLOCKDATA 1711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project discardData(); 1712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return proxy; 1713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a class descriptor from the source stream. 1717f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the class descriptor read from the source stream. 1719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a class for one of the objects cannot be found. 1721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 172403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { 1725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass newClassDesc = new ObjectStreamClass(); 1726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = input.readUTF(); 1727f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (name.length() == 0) { 172803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IOException("The stream is corrupted"); 1729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newClassDesc.setName(name); 1731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newClassDesc.setSerialVersionUID(input.readLong()); 1732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newClassDesc.setFlags(input.readByte()); 1733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1734f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /* 1735f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * We must register the class descriptor before reading field 1736f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * descriptors. If called outside of readObject, the descriptorHandle 17376523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes * might be unset. 1738f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 17396523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes if (descriptorHandle == -1) { 17406523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes descriptorHandle = nextHandle(); 17416523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes } 1742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project registerObjectRead(newClassDesc, descriptorHandle, false); 1743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readFieldDescriptors(newClassDesc); 1745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return newClassDesc; 1746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates the proxy class that implements the interfaces specified in 1750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code interfaceNames}. 1751f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param interfaceNames 1753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the interfaces used to create the proxy class. 1754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the proxy class. 1755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the proxy class or any of the specified interfaces cannot 1757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be created. 1758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream#annotateProxyClass(Class) 1761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected Class<?> resolveProxyClass(String[] interfaceNames) 1763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, ClassNotFoundException { 1764f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // TODO: This method is opportunity for performance enhancement 1765f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // We can cache the classloader and recently used interfaces. 1766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassLoader loader = ClassLoader.getSystemClassLoader(); 1767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?>[] interfaces = new Class<?>[interfaceNames.length]; 1768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < interfaceNames.length; i++) { 1769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project interfaces[i] = Class.forName(interfaceNames[i], false, loader); 1770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Proxy.getProxyClass(loader, interfaces); 1773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IllegalArgumentException e) { 1774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassNotFoundException(e.toString(), e); 1775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1778f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private int readNewHandle() throws IOException { 1779f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return input.readInt(); 1780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1782f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 1783f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Read a new object from the stream. It is assumed the object has not been 1784f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * loaded yet (not a cyclic reference). Return the object read. 1785f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1786f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * If the object implements <code>Externalizable</code> its 1787f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * <code>readExternal</code> is called. Otherwise, all fields described by 1788f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * the class hierarchy are loaded. Each class can define how its declared 1789f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * instance fields are loaded by defining a private method 1790f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * <code>readObject</code> 1791f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1792f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @param unshared 1793f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * read the object unshared 1794f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @return the object read 1795f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1796f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IOException 1797f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * If an IO exception happened when reading the object. 1798f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws OptionalDataException 1799f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * If optional data could not be found when reading the object 1800f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * graph 1801f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws ClassNotFoundException 1802f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * If a class for one of the objects could not be found 1803f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 1804f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private Object readNewObject(boolean unshared) 1805f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson throws OptionalDataException, ClassNotFoundException, IOException { 1806f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson ObjectStreamClass classDesc = readClassDesc(); 1807f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1808f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (classDesc == null) { 1809b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw missingClassDescriptor(); 1810f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1811f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 18126523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes int newHandle = nextHandle(); 1813f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Class<?> objectClass = classDesc.forClass(); 181432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes Object result = null; 181532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes Object registeredResult = null; 1816f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (objectClass != null) { 1817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Now we know which class to instantiate and which constructor to 1818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // run. We are allowed to run the constructor. 18196523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes result = classDesc.newInstance(objectClass); 1820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project registerObjectRead(result, newHandle, unshared); 1821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project registeredResult = result; 1822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = null; 1824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // This is how we know what to do in defaultReadObject. And it is 1828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // also used by defaultReadObject to check if it was called from an 1829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // invalid place. It also allows readExternal to call 1830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // defaultReadObject and have it work. 1831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentObject = result; 1832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentClass = classDesc; 1833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If Externalizable, just let the object read itself 183532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // Note that this value comes from the Stream, and in fact it could be 183632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // that the classes have been changed so that the info below now 183732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // conflicts with the newer class 183832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes boolean wasExternalizable = (classDesc.getFlags() & SC_EXTERNALIZABLE) != 0; 1839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (wasExternalizable) { 184032ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes boolean blockData = (classDesc.getFlags() & SC_BLOCK_DATA) != 0; 1841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!blockData) { 1842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = input; 1843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mustResolve) { 1845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Externalizable extern = (Externalizable) result; 1846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project extern.readExternal(this); 1847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (blockData) { 1849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Similar to readHierarchy. Anything not read by 1850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // readExternal has to be consumed here 1851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project discardData(); 1852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = emptyStream; 1854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If we got here, it is Serializable but not Externalizable. 1857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Walk the hierarchy reading each class' slots 1858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readHierarchy(result, classDesc); 1859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 1861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Cleanup, needs to run always so that we can later detect invalid 1862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // calls to defaultReadObject 1863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentObject = null; 1864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentClass = null; 1865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (objectClass != null) { 1868f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1869f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (classDesc.hasMethodReadResolve()){ 1870f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Method methodReadResolve = classDesc.getMethodReadResolve(); 1871f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson try { 1872f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result = methodReadResolve.invoke(result, (Object[]) null); 18732543351c360bdfe0046e819dedb069f3724d703aJesse Wilson } catch (IllegalAccessException ignored) { 1874f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } catch (InvocationTargetException ite) { 1875f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Throwable target = ite.getTargetException(); 1876f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (target instanceof ObjectStreamException) { 1877f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson throw (ObjectStreamException) target; 1878f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else if (target instanceof Error) { 1879f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson throw (Error) target; 1880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1881f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson throw (RuntimeException) target; 1882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1884f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We get here either if class-based replacement was not needed or if it 1888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // was needed but produced the same object or if it could not be 1889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // computed. 1890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The object to return is the one we instantiated or a replacement for 1892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // it 1893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result != null && enableResolve) { 1894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = resolveObject(result); 1895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (registeredResult != result) { 1897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project registerObjectRead(result, newHandle, unshared); 1898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 1900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1902b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes private InvalidClassException missingClassDescriptor() throws InvalidClassException { 1903b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new InvalidClassException("Read null attempting to read class descriptor for object"); 1904b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 1905b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 1906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Read a string encoded in {@link DataInput modified UTF-8} from the 1908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * receiver. Return the string read. 1909f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param unshared 1911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read the object unshared 1912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the string just read. 1913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the String. 1915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object readNewString(boolean unshared) throws IOException { 1917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object result = input.readUTF(); 1918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (enableResolve) { 1919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = resolveObject(result); 1920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1921d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes registerObjectRead(result, nextHandle(), unshared); 1922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 1924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Read a new String in UTF format from the receiver. Return the string 1928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read. 1929f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param unshared 1931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read the object unshared 1932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the string just read. 1933f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an IO exception happened when reading the String. 1936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object readNewLongString(boolean unshared) throws IOException { 1938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long length = input.readLong(); 1939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object result = input.decodeUTF((int) length); 1940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (enableResolve) { 1941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = resolveObject(result); 1942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1943f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson registerObjectRead(result, nextHandle(), unshared); 1944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 1946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads the next object from the source stream. 1950f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the object read from the source stream. 1952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the class of one of the objects in the object graph cannot 1954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 1955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws OptionalDataException 1958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if primitive data types were found instead of an object. 1959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream#writeObject(Object) 1960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Object readObject() throws OptionalDataException, 1962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassNotFoundException, IOException { 1963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readObject(false); 1964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads the next unshared object from the source stream. 1968f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the new object read. 1970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 1971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the class of one of the objects in the object graph cannot 1972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 1973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 1975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream#writeUnshared 1976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object readUnshared() throws IOException, ClassNotFoundException { 1978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readObject(true); 1979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object readObject(boolean unshared) throws OptionalDataException, 1982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassNotFoundException, IOException { 1983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean restoreInput = (primitiveData == input); 1984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (restoreInput) { 1985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = emptyStream; 1986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // This is the spec'ed behavior in JDK 1.2. Very bizarre way to allow 1989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // behavior overriding. 1990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (subclassOverridingImplementation && !unshared) { 1991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readObjectOverride(); 1992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If we still had primitive types to read, should we discard them 1995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (reset the primitiveTypes stream) or leave as is, so that attempts to 1996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // read primitive types won't read 'past data' ??? 1997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object result; 1998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We need this so we can tell when we are returning to the 2000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // original/outside caller 2001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (++nestedLevels == 1) { 2002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Remember the caller's class loader 2003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project callerClassLoader = getClosestUserClassLoader(); 2004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = readNonPrimitiveContent(unshared); 2007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (restoreInput) { 2008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = input; 2009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 2011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We need this so we can tell when we are returning to the 2012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // original/outside caller 2013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (--nestedLevels == 0) { 2014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We are going to return to the original caller, perform 2015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // cleanups. 2016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // No more need to remember the caller's class loader 2017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project callerClassLoader = null; 2018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Done reading this object. Is it time to return to the original 2022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // caller? If so we need to perform validations first. 2023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nestedLevels == 0 && validations != null) { 2024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We are going to return to the original caller. If validation is 2025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // enabled we need to run them now and then cleanup the validation 2026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // collection 2027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 2028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (InputValidationDesc element : validations) { 2029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project element.validator.validateObject(); 2030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 2032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Validations have to be renewed, since they are only called 2033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // from readObject 2034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validations = null; 2035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 2038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2040fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes private static final ClassLoader bootstrapLoader = Object.class.getClassLoader(); 2041fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes private static final ClassLoader systemLoader = ClassLoader.getSystemClassLoader(); 2042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Searches up the call stack to find the closest user-defined class loader. 2045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 2046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a user-defined class loader or null if one isn't found 2047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static ClassLoader getClosestUserClassLoader() { 20493d93b50c1e9d8cb12d17a4331edd27ee2a1dc7a9Dan Bornstein Class<?>[] stackClasses = VMStack.getClasses(-1); 2050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (Class<?> stackClass : stackClasses) { 2051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassLoader loader = stackClass.getClassLoader(); 2052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (loader != null && loader != bootstrapLoader 2053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && loader != systemLoader) { 2054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return loader; 2055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 2058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 20612543351c360bdfe0046e819dedb069f3724d703aJesse Wilson * Method to be overridden by subclasses to read the next object from the 2062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * source stream. 2063f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the object read from the source stream. 2065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 2066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the class of one of the objects in the object graph cannot 2067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 2068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 2069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 2070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws OptionalDataException 2071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if primitive data types were found instead of an object. 2072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream#writeObjectOverride 2073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected Object readObjectOverride() throws OptionalDataException, 2075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassNotFoundException, IOException { 2076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null) { 2077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 2078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Subclasses must override. 2080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IOException(); 2081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a short (16 bit) from the source stream. 2085f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the short value read from the source stream. 2087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 2088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 2089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public short readShort() throws IOException { 2091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readShort(); 2092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads and validates the ObjectInputStream header from the source stream. 2096f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 2098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 2099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws StreamCorruptedException 2100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the source stream does not contain readable serialized 2101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * objects. 2102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void readStreamHeader() throws IOException, 2104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project StreamCorruptedException { 2105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input.readShort() == STREAM_MAGIC 2106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && input.readShort() == STREAM_VERSION) { 2107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 2108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new StreamCorruptedException(); 2110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads an unsigned byte (8 bit) from the source stream. 2114f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the unsigned byte value read from the source stream packaged in 2116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an integer. 2117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 2118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 2119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 2120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 2121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 2122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int readUnsignedByte() throws IOException { 2124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readUnsignedByte(); 2125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads an unsigned short (16 bit) from the source stream. 2129f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the unsigned short value read from the source stream packaged in 2131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an integer. 2132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 2133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 2134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 2135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 2136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 2137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int readUnsignedShort() throws IOException { 2139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readUnsignedShort(); 2140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a string encoded in {@link DataInput modified UTF-8} from the 2144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * source stream. 2145f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the string encoded in {@link DataInput modified UTF-8} read from 2147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source stream. 2148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws EOFException 2149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the end of the input is reached before the read 2150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request can be satisfied. 2151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 2152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while reading from the source stream. 2153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String readUTF() throws IOException { 2155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return primitiveTypes.readUTF(); 2156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 21596523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes * Returns the previously-read object corresponding to the given serialization handle. 2160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidObjectException 21616523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes * If there is no previously-read object with this handle 2162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 21636523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes private Object registeredObjectRead(int handle) throws InvalidObjectException { 21646523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes Object res = objectsRead.get(handle - ObjectStreamConstants.baseWireHandle); 2165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (res == UNSHARED_OBJ) { 2166b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new InvalidObjectException("Cannot read back reference to unshared object"); 2167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return res; 2169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 21726523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes * Associates a read object with the its serialization handle. 2173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 21746523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes private void registerObjectRead(Object obj, int handle, boolean unshared) throws IOException { 21756523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes if (unshared) { 21766523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes obj = UNSHARED_OBJ; 21776523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes } 21786523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes int index = handle - ObjectStreamConstants.baseWireHandle; 2179f24bce74a497ed281de23b7e997549725557b730Elliott Hughes int size = objectsRead.size(); 2180f24bce74a497ed281de23b7e997549725557b730Elliott Hughes // ObjectOutputStream sometimes wastes a handle. I've compared hex dumps of the RI 2181f24bce74a497ed281de23b7e997549725557b730Elliott Hughes // and it seems like that's a 'feature'. Look for calls to objectsWritten.put that 2182f24bce74a497ed281de23b7e997549725557b730Elliott Hughes // are guarded by !unshared tests. 2183f24bce74a497ed281de23b7e997549725557b730Elliott Hughes while (index > size) { 2184f24bce74a497ed281de23b7e997549725557b730Elliott Hughes objectsRead.add(null); 2185f24bce74a497ed281de23b7e997549725557b730Elliott Hughes ++size; 2186f24bce74a497ed281de23b7e997549725557b730Elliott Hughes } 2187f24bce74a497ed281de23b7e997549725557b730Elliott Hughes if (index == size) { 21886523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes objectsRead.add(obj); 21896523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes } else { 2190f24bce74a497ed281de23b7e997549725557b730Elliott Hughes objectsRead.set(index, obj); 21916523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes } 2192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Registers a callback for post-deserialization validation of objects. It 2196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * allows to perform additional consistency checks before the {@code 2197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * readObject()} method of this class returns its result to the caller. This 2198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method can only be called from within the {@code readObject()} method of 2199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a class that implements "special" deserialization rules. It can be called 2200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * multiple times. Validation callbacks are then done in order of decreasing 2201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * priority, defined by {@code priority}. 2202f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param object 2204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an object that can validate itself by receiving a callback. 2205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param priority 2206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the validator's priority. 2207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidObjectException 2208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code object} is {@code null}. 2209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NotActiveException 2210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this stream is currently not reading objects. In that 2211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * case, calling this method is not allowed. 2212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectInputValidation#validateObject() 2213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void registerValidation(ObjectInputValidation object, 2215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int priority) throws NotActiveException, InvalidObjectException { 2216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Validation can only be registered when inside readObject calls 2217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object instanceBeingRead = this.currentObject; 2218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2219f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (instanceBeingRead == null && nestedLevels == 0) { 2220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NotActiveException(); 2221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (object == null) { 2223b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new InvalidObjectException("Callback object cannot be null"); 2224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // From now on it is just insertion in a SortedCollection. Since 2226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the Java class libraries don't provide that, we have to 2227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // implement it from scratch here. 2228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InputValidationDesc desc = new InputValidationDesc(); 2229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project desc.validator = object; 2230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project desc.priority = priority; 2231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // No need for this, validateObject does not take a parameter 2232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // desc.toValidate = instanceBeingRead; 2233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (validations == null) { 2234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validations = new InputValidationDesc[1]; 2235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validations[0] = desc; 2236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 2237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i = 0; 2238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (; i < validations.length; i++) { 2239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InputValidationDesc validation = validations[i]; 2240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Sorted, higher priority first. 2241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (priority >= validation.priority) { 2242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; // Found the index where to insert 2243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InputValidationDesc[] oldValidations = validations; 2246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int currentSize = oldValidations.length; 2247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validations = new InputValidationDesc[currentSize + 1]; 2248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(oldValidations, 0, validations, 0, i); 2249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(oldValidations, i, validations, i + 1, currentSize 2250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project - i); 2251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validations[i] = desc; 2252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reset the collection of objects already loaded by the receiver. 2257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void resetSeenObjects() { 22596523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes objectsRead = new ArrayList<Object>(); 22602543351c360bdfe0046e819dedb069f3724d703aJesse Wilson nextHandle = baseWireHandle; 2261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primitiveData = emptyStream; 2262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reset the receiver. The collection of objects already read by the 2266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * receiver is reset, and internal structures are also reset so that the 2267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * receiver knows it is in a fresh clean state. 2268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void resetState() { 2270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project resetSeenObjects(); 2271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project hasPushbackTC = false; 2272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pushbackTC = 0; 2273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // nestedLevels = 0; 2274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Loads the Java class corresponding to the class descriptor {@code 2278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * osClass} that has just been read from the source stream. 2279f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param osClass 2281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an ObjectStreamClass read from the source stream. 2282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a Class corresponding to the descriptor {@code osClass}. 2283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassNotFoundException 2284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the class for an object cannot be found. 2285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 2286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs while creating the class. 2287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream#annotateClass(Class) 2288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected Class<?> resolveClass(ObjectStreamClass osClass) 2290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, ClassNotFoundException { 2291f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // fastpath: obtain cached value 2292f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Class<?> cls = osClass.forClass(); 2293b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (cls == null) { 2294f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // slowpath: resolve the class 2295f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson String className = osClass.getName(); 2296f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 2297f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // if it is primitive class, for example, long.class 2298f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson cls = PRIMITIVE_CLASSES.get(className); 2299f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 2300b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (cls == null) { 2301f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // not primitive class 2302f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Use the first non-null ClassLoader on the stack. If null, use 2303f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // the system class loader 2304f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson cls = Class.forName(className, true, callerClassLoader); 2305f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 2306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return cls; 2308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Allows trusted subclasses to substitute the specified original {@code 2312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object} with a new object. Object substitution has to be activated first 2313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with calling {@code enableResolveObject(true)}. This implementation just 2314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returns {@code object}. 2315f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param object 2317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the original object for which a replacement may be defined. 2318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the replacement object for {@code object}. 2319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 2320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if any I/O error occurs while creating the replacement 2321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 2322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #enableResolveObject 2323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream#enableReplaceObject 2324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream#replaceObject 2325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected Object resolveObject(Object object) throws IOException { 2327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // By default no object replacement. Subclasses can override 2328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return object; 2329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Skips {@code length} bytes on the source stream. This method should not 2333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be used to skip bytes at any arbitrary position, just when reading 2334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * primitive data types (int, char etc). 2335f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param length 2337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes to skip. 2338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes actually skipped. 2339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 2340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while skipping bytes on the source stream. 2341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 2342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the source stream is {@code null}. 2343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int skipBytes(int length) throws IOException { 2345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // To be used with available. Ok to call if reading primitive buffer 2346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null) { 234786acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("source stream is null"); 2348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int offset = 0; 2351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (offset < length) { 2352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkReadPrimitiveTypes(); 2353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long skipped = primitiveData.skip(length - offset); 2354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (skipped == 0) { 2355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return offset; 2356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset += (int) skipped; 2358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return length; 2360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2363f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Verify if the SUID & the base name for descriptor 2364f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * <code>loadedStreamClass</code>matches 2365f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * the SUID & the base name of the corresponding loaded class and 2366f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * init private fields. 2367f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param loadedStreamClass 2369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An ObjectStreamClass that was loaded from the stream. 2370f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidClassException 2372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the SUID of the stream class does not match the VM class 2373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2374f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private void verifyAndInit(ObjectStreamClass loadedStreamClass) 2375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws InvalidClassException { 2376f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 2377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> localClass = loadedStreamClass.forClass(); 2378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass localStreamClass = ObjectStreamClass 2379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .lookupStreamClass(localClass); 2380f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 2381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (loadedStreamClass.getSerialVersionUID() != localStreamClass 2382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getSerialVersionUID()) { 2383b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new InvalidClassException(loadedStreamClass.getName(), 2384b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes "Incompatible class (SUID): " + loadedStreamClass + 2385b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes " but expected " + localStreamClass); 2386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String loadedClassBaseName = getBaseName(loadedStreamClass.getName()); 2389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String localClassBaseName = getBaseName(localStreamClass.getName()); 2390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!loadedClassBaseName.equals(localClassBaseName)) { 2392b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new InvalidClassException(loadedStreamClass.getName(), 2393b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes String.format("Incompatible class (base name): %s but expected %s", 2394b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes loadedClassBaseName, localClassBaseName)); 2395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2396f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 2397f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson loadedStreamClass.initPrivateFields(localStreamClass); 2398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static String getBaseName(String fullName) { 2401f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int k = fullName.lastIndexOf('.'); 2402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (k == -1 || k == (fullName.length() - 1)) { 2404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return fullName; 2405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return fullName.substring(k + 1); 2407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Avoid recursive defining. 2410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static void checkedSetSuperClassDesc(ObjectStreamClass desc, 2411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass superDesc) throws StreamCorruptedException { 2412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (desc.equals(superDesc)) { 2413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new StreamCorruptedException(); 2414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project desc.setSuperclass(superDesc); 2416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 2418