}
case ID_STRING_LARGE: {
// ignore unshared setting
int length = readInt();
if (length <= 0) {
throw new StreamCorruptedException("Invalid length value for string in stream (" + length + ")");
}
final String s = UTFUtils.readUTFBytes(this, length);
instanceCache.add(s);
return s;
}
case ID_ARRAY_EMPTY:
case ID_ARRAY_EMPTY_UNSHARED: {
if (unshared != (leadByte == ID_ARRAY_EMPTY_UNSHARED)) {
throw sharedMismatch();
}
final ArrayList<Object> instanceCache = this.instanceCache;
final int idx = instanceCache.size();
instanceCache.add(null);
final Object obj = Array.newInstance(doReadClassDescriptor(readUnsignedByte()).getType(), 0);
instanceCache.set(idx, obj);
final Object resolvedObject = objectResolver.readResolve(obj);
if (unshared) {
instanceCache.set(idx, null);
} else if (obj != resolvedObject) {
instanceCache.set(idx, resolvedObject);
}
return replace(obj);
}
case ID_ARRAY_SMALL:
case ID_ARRAY_SMALL_UNSHARED: {
if (unshared != (leadByte == ID_ARRAY_SMALL_UNSHARED)) {
throw sharedMismatch();
}
final int len = readUnsignedByte();
return replace(doReadArray(len == 0 ? 0x100 : len, unshared));
}
case ID_ARRAY_MEDIUM:
case ID_ARRAY_MEDIUM_UNSHARED: {
if (unshared != (leadByte == ID_ARRAY_MEDIUM_UNSHARED)) {
throw sharedMismatch();
}
final int len = readUnsignedShort();
return replace(doReadArray(len == 0 ? 0x10000 : len, unshared));
}
case ID_ARRAY_LARGE:
case ID_ARRAY_LARGE_UNSHARED: {
if (unshared != (leadByte == ID_ARRAY_LARGE_UNSHARED)) {
throw sharedMismatch();
}
final int len = readInt();
if (len <= 0) {
throw new StreamCorruptedException("Invalid length value for array in stream (" + len + ")");
}
return replace(doReadArray(len, unshared));
}
case ID_PREDEFINED_OBJECT: {
if (unshared) {
throw new InvalidObjectException("Attempt to read a predefined object as unshared");
}
return objectTable.readObject(this);
}
case ID_BOOLEAN_OBJECT_TRUE: {
return replace(objectResolver.readResolve(Boolean.TRUE));
}
case ID_BOOLEAN_OBJECT_FALSE: {
return replace(objectResolver.readResolve(Boolean.FALSE));
}
case ID_BYTE_OBJECT: {
return replace(objectResolver.readResolve(Byte.valueOf(readByte())));
}
case ID_SHORT_OBJECT: {
return replace(objectResolver.readResolve(Short.valueOf(readShort())));
}
case ID_INTEGER_OBJECT: {
return replace(objectResolver.readResolve(Integer.valueOf(readInt())));
}
case ID_LONG_OBJECT: {
return replace(objectResolver.readResolve(Long.valueOf(readLong())));
}
case ID_FLOAT_OBJECT: {
return replace(objectResolver.readResolve(Float.valueOf(readFloat())));
}
case ID_DOUBLE_OBJECT: {
return replace(objectResolver.readResolve(Double.valueOf(readDouble())));
}
case ID_CHARACTER_OBJECT: {
return replace(objectResolver.readResolve(Character.valueOf(readChar())));
}
case ID_PRIM_BYTE: {
return byte.class;
}
case ID_PRIM_BOOLEAN: {
return boolean.class;
}
case ID_PRIM_CHAR: {
return char.class;
}
case ID_PRIM_DOUBLE: {
return double.class;
}
case ID_PRIM_FLOAT: {
return float.class;
}
case ID_PRIM_INT: {
return int.class;
}
case ID_PRIM_LONG: {
return long.class;
}
case ID_PRIM_SHORT: {
return short.class;
}
case ID_VOID: {
return void.class;
}
case ID_BYTE_CLASS: {
return Byte.class;
}
case ID_BOOLEAN_CLASS: {
return Boolean.class;
}
case ID_CHARACTER_CLASS: {
return Character.class;
}
case ID_DOUBLE_CLASS: {
return Double.class;
}
case ID_FLOAT_CLASS: {
return Float.class;
}
case ID_INTEGER_CLASS: {
return Integer.class;
}
case ID_LONG_CLASS: {
return Long.class;
}
case ID_SHORT_CLASS: {
return Short.class;
}
case ID_VOID_CLASS: {
return Void.class;
}
case ID_OBJECT_CLASS: {
return Object.class;
}
case ID_CLASS_CLASS: {
return Class.class;
}
case ID_STRING_CLASS: {
return String.class;
}
case ID_ENUM_CLASS: {
return Enum.class;
}
case ID_BYTE_ARRAY_CLASS: {
return byte[].class;
}
case ID_BOOLEAN_ARRAY_CLASS: {
return boolean[].class;
}
case ID_CHAR_ARRAY_CLASS: {
return char[].class;
}
case ID_DOUBLE_ARRAY_CLASS: {
return double[].class;
}
case ID_FLOAT_ARRAY_CLASS: {
return float[].class;
}
case ID_INT_ARRAY_CLASS: {
return int[].class;
}
case ID_LONG_ARRAY_CLASS: {
return long[].class;
}
case ID_SHORT_ARRAY_CLASS: {
return short[].class;
}
case ID_CC_ARRAY_LIST: {
return ArrayList.class;
}
case ID_CC_LINKED_LIST: {
return LinkedList.class;
}
case ID_CC_HASH_SET: {
return HashSet.class;
}
case ID_CC_LINKED_HASH_SET: {
return LinkedHashSet.class;
}
case ID_CC_TREE_SET: {
return TreeSet.class;
}
case ID_CC_IDENTITY_HASH_MAP: {
return IdentityHashMap.class;
}
case ID_CC_HASH_MAP: {
return HashMap.class;
}
case ID_CC_HASHTABLE: {
return Hashtable.class;
}
case ID_CC_LINKED_HASH_MAP: {
return LinkedHashMap.class;
}
case ID_CC_TREE_MAP: {
return TreeMap.class;
}
case ID_CC_ENUM_SET_PROXY: {
return enumSetProxyClass;
}
case ID_CC_ENUM_SET: {
return EnumSet.class;
}
case ID_CC_ENUM_MAP: {
return EnumMap.class;
}
case ID_ABSTRACT_COLLECTION: {
return AbstractCollection.class;
}
case ID_ABSTRACT_LIST: {
return AbstractList.class;
}
case ID_ABSTRACT_QUEUE: {
return AbstractQueue.class;
}
case ID_ABSTRACT_SEQUENTIAL_LIST: {
return AbstractSequentialList.class;
}
case ID_ABSTRACT_SET: {
return AbstractSet.class;
}
case ID_CC_CONCURRENT_HASH_MAP: {
return ConcurrentHashMap.class;
}
case ID_CC_COPY_ON_WRITE_ARRAY_LIST: {
return CopyOnWriteArrayList.class;
}
case ID_CC_COPY_ON_WRITE_ARRAY_SET: {
return CopyOnWriteArraySet.class;
}
case ID_CC_VECTOR: {
return Vector.class;
}
case ID_CC_STACK: {
return Stack.class;
}
case ID_CC_NCOPIES: {
return nCopiesClass;
}
case ID_SINGLETON_LIST_OBJECT: {
final int idx = instanceCache.size();
instanceCache.add(null);
final Object obj = Collections.singletonList(doReadNestedObject(false, "Collections#singletonList()"));
final Object resolvedObject = objectResolver.readResolve(obj);
if (! unshared) {
instanceCache.set(idx, resolvedObject);
}
return replace(resolvedObject);
}
case ID_SINGLETON_SET_OBJECT: {
final int idx = instanceCache.size();
instanceCache.add(null);
final Object obj = Collections.singleton(doReadNestedObject(false, "Collections#singleton()"));
final Object resolvedObject = objectResolver.readResolve(obj);
if (! unshared) {
instanceCache.set(idx, resolvedObject);
}
return replace(resolvedObject);
}
case ID_SINGLETON_MAP_OBJECT: {
final int idx = instanceCache.size();
instanceCache.add(null);
final Object obj = Collections.singletonMap(doReadNestedObject(false, "Collections#singletonMap() [key]"), doReadNestedObject(false, "Collections#singletonMap() [value]"));
final Object resolvedObject = objectResolver.readResolve(obj);
if (! unshared) {
instanceCache.set(idx, resolvedObject);
}
return replace(resolvedObject);
}
case ID_REVERSE_ORDER2_OBJECT: {
final int idx = instanceCache.size();
instanceCache.add(null);
final Object obj = Collections.reverseOrder((Comparator<?>) doReadNestedObject(false, "Collections#reverseOrder()"));
final Object resolvedObject = objectResolver.readResolve(obj);
if (! unshared) {
instanceCache.set(idx, resolvedObject);
}
return replace(resolvedObject);
}
case ID_EMPTY_LIST_OBJECT: {
return Collections.emptyList();
}
case ID_EMPTY_SET_OBJECT: {
return Collections.emptySet();
}
case ID_EMPTY_MAP_OBJECT: {
return Collections.emptyMap();
}
case ID_REVERSE_ORDER_OBJECT: {
return Collections.reverseOrder();
}
case ID_COLLECTION_EMPTY:
case ID_COLLECTION_EMPTY_UNSHARED:
case ID_COLLECTION_SMALL:
case ID_COLLECTION_SMALL_UNSHARED:
case ID_COLLECTION_MEDIUM:
case ID_COLLECTION_MEDIUM_UNSHARED:
case ID_COLLECTION_LARGE:
case ID_COLLECTION_LARGE_UNSHARED:
{
final int len;
switch (leadByte) {
case ID_COLLECTION_EMPTY:
case ID_COLLECTION_EMPTY_UNSHARED: {
len = 0;
break;
}
case ID_COLLECTION_SMALL:
case ID_COLLECTION_SMALL_UNSHARED: {
int b = readUnsignedByte();
len = b == 0 ? 0x100 : b;
break;
}
case ID_COLLECTION_MEDIUM:
case ID_COLLECTION_MEDIUM_UNSHARED: {
int b = readUnsignedShort();
len = b == 0 ? 0x10000 : b;
break;
}
case ID_COLLECTION_LARGE:
case ID_COLLECTION_LARGE_UNSHARED: {
len = readInt();
break;
}
default: {
throw new IllegalStateException();
}
}
final int id = readUnsignedByte();
switch (id) {
case ID_CC_ARRAY_LIST: {
return replace(readCollectionData(unshared, -1, len, new ArrayList(len)));
}
case ID_CC_HASH_SET: {
return replace(readCollectionData(unshared, -1, len, new HashSet(len)));
}
case ID_CC_LINKED_HASH_SET: {
return replace(readCollectionData(unshared, -1, len, new LinkedHashSet(len)));
}
case ID_CC_LINKED_LIST: {
return replace(readCollectionData(unshared, -1, len, new LinkedList()));
}
case ID_CC_TREE_SET: {
int idx = instanceCache.size();
instanceCache.add(null);
Comparator comp = (Comparator)doReadNestedObject(false, "java.util.TreeSet comparator");
return replace(readSortedSetData(unshared, idx, len, new TreeSet(comp)));
}
case ID_CC_ENUM_SET_PROXY: {
final ClassDescriptor nestedDescriptor = doReadClassDescriptor(readUnsignedByte());
final Class<? extends Enum> elementType = nestedDescriptor.getType().asSubclass(Enum.class);
return replace(readCollectionData(unshared, -1, len, EnumSet.noneOf(elementType)));
}
case ID_CC_VECTOR: {
return replace(readCollectionData(unshared, -1, len, new Vector(len)));
}
case ID_CC_STACK: {
return replace(readCollectionData(unshared, -1, len, new Stack()));
}
case ID_CC_ARRAY_DEQUE: {
return replace(readCollectionData(unshared, -1, len, new ArrayDeque(len)));
}
case ID_CC_HASH_MAP: {
return replace(readMapData(unshared, -1, len, new HashMap(len)));
}
case ID_CC_HASHTABLE: {
return replace(readMapData(unshared, -1, len, new Hashtable(len)));
}
case ID_CC_IDENTITY_HASH_MAP: {
return replace(readMapData(unshared, -1, len, new IdentityHashMap(len)));
}
case ID_CC_LINKED_HASH_MAP: {
return replace(readMapData(unshared, -1, len, new LinkedHashMap(len)));
}
case ID_CC_TREE_MAP: {
int idx = instanceCache.size();
instanceCache.add(null);
Comparator comp = (Comparator)doReadNestedObject(false, "java.util.TreeSet comparator");
return replace(readSortedMapData(unshared, idx, len, new TreeMap(comp)));
}
case ID_CC_ENUM_MAP: {
int idx = instanceCache.size();
instanceCache.add(null);
final ClassDescriptor nestedDescriptor = doReadClassDescriptor(readUnsignedByte());
final Class<? extends Enum> elementType = nestedDescriptor.getType().asSubclass(Enum.class);
return replace(readMapData(unshared, idx, len, new EnumMap(elementType)));
}
case ID_CC_NCOPIES: {
final int idx = instanceCache.size();
instanceCache.add(null);
final Object obj = Collections.nCopies(len, doReadNestedObject(false, "n-copies member object"));
final Object resolvedObject = objectResolver.readResolve(obj);
if (! unshared) {
instanceCache.set(idx, resolvedObject);
}
return replace(resolvedObject);
}
default: {
throw new StreamCorruptedException("Unexpected byte found when reading a collection type: " + leadByte);
}
}
}
case ID_PAIR: {
final int idx = instanceCache.size();
instanceCache.add(null);
final Object obj = Pair.create(doReadNestedObject(unshared, "java.util.marshalling.Pair [A]"), doReadNestedObject(unshared, "java.util.marshalling.Pair [B]"));
final Object resolvedObject = objectResolver.readResolve(obj);
if (! unshared) {
instanceCache.set(idx, resolvedObject);
}
return replace(resolvedObject);
}
case ID_CLEAR_CLASS_CACHE: {
if (depth > 1) {
throw new StreamCorruptedException("ID_CLEAR_CLASS_CACHE token in the middle of stream processing");
}
classCache.clear();
instanceCache.clear();
leadByte = readUnsignedByte();
continue;
}
case ID_CLEAR_INSTANCE_CACHE: {
if (depth > 1) {
throw new StreamCorruptedException("ID_CLEAR_INSTANCE_CACHE token in the middle of stream processing");
}
instanceCache.clear();
leadByte = readUnsignedByte();
continue;
}
default: {
throw new StreamCorruptedException("Unexpected byte found when reading an object: " + leadByte);
}
}
} finally {
depth --;
}