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