8033778: ObjectIn/OutputStream improvements
Co-authored-by: Robert Stupp <snazy@gmx.de> Reviewed-by: smarks, psandoz, mduigou, plevart
This commit is contained in:
parent
5911461228
commit
2ffde4a993
@ -39,7 +39,6 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import static java.io.ObjectStreamClass.processQueue;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
@ -534,7 +533,7 @@ public class ObjectInputStream
|
||||
if (ctx == null) {
|
||||
throw new NotActiveException("not in call to readObject");
|
||||
}
|
||||
Object curObj = ctx.getObj();
|
||||
ctx.checkAndSetUsed();
|
||||
ObjectStreamClass curDesc = ctx.getDesc();
|
||||
bin.setBlockDataMode(false);
|
||||
GetFieldImpl getField = new GetFieldImpl(curDesc);
|
||||
@ -1597,7 +1596,7 @@ public class ObjectInputStream
|
||||
int descHandle = handles.assign(unshared ? unsharedMarker : desc);
|
||||
passHandle = NULL_HANDLE;
|
||||
|
||||
ObjectStreamClass readDesc = null;
|
||||
ObjectStreamClass readDesc;
|
||||
try {
|
||||
readDesc = readClassDescriptor();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
@ -1976,29 +1975,34 @@ public class ObjectInputStream
|
||||
}
|
||||
|
||||
int primDataSize = desc.getPrimDataSize();
|
||||
if (primVals == null || primVals.length < primDataSize) {
|
||||
primVals = new byte[primDataSize];
|
||||
}
|
||||
bin.readFully(primVals, 0, primDataSize, false);
|
||||
if (obj != null) {
|
||||
desc.setPrimFieldValues(obj, primVals);
|
||||
}
|
||||
|
||||
int objHandle = passHandle;
|
||||
ObjectStreamField[] fields = desc.getFields(false);
|
||||
Object[] objVals = new Object[desc.getNumObjFields()];
|
||||
int numPrimFields = fields.length - objVals.length;
|
||||
for (int i = 0; i < objVals.length; i++) {
|
||||
ObjectStreamField f = fields[numPrimFields + i];
|
||||
objVals[i] = readObject0(f.isUnshared());
|
||||
if (f.getField() != null) {
|
||||
handles.markDependency(objHandle, passHandle);
|
||||
if (primDataSize > 0) {
|
||||
if (primVals == null || primVals.length < primDataSize) {
|
||||
primVals = new byte[primDataSize];
|
||||
}
|
||||
bin.readFully(primVals, 0, primDataSize, false);
|
||||
if (obj != null) {
|
||||
desc.setPrimFieldValues(obj, primVals);
|
||||
}
|
||||
}
|
||||
if (obj != null) {
|
||||
desc.setObjFieldValues(obj, objVals);
|
||||
|
||||
int numObjFields = desc.getNumObjFields();
|
||||
if (numObjFields > 0) {
|
||||
int objHandle = passHandle;
|
||||
ObjectStreamField[] fields = desc.getFields(false);
|
||||
Object[] objVals = new Object[numObjFields];
|
||||
int numPrimFields = fields.length - objVals.length;
|
||||
for (int i = 0; i < objVals.length; i++) {
|
||||
ObjectStreamField f = fields[numPrimFields + i];
|
||||
objVals[i] = readObject0(f.isUnshared());
|
||||
if (f.getField() != null) {
|
||||
handles.markDependency(objHandle, passHandle);
|
||||
}
|
||||
}
|
||||
if (obj != null) {
|
||||
desc.setObjFieldValues(obj, objVals);
|
||||
}
|
||||
passHandle = objHandle;
|
||||
}
|
||||
passHandle = objHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,7 +35,6 @@ import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import static java.io.ObjectStreamClass.processQueue;
|
||||
import java.io.SerialCallbackContext;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
@ -458,7 +457,7 @@ public class ObjectOutputStream
|
||||
if (ctx == null) {
|
||||
throw new NotActiveException("not in call to writeObject");
|
||||
}
|
||||
Object curObj = ctx.getObj();
|
||||
ctx.checkAndSetUsed();
|
||||
ObjectStreamClass curDesc = ctx.getDesc();
|
||||
curPut = new PutFieldImpl(curDesc);
|
||||
}
|
||||
@ -1527,29 +1526,34 @@ public class ObjectOutputStream
|
||||
desc.checkDefaultSerialize();
|
||||
|
||||
int primDataSize = desc.getPrimDataSize();
|
||||
if (primVals == null || primVals.length < primDataSize) {
|
||||
primVals = new byte[primDataSize];
|
||||
}
|
||||
desc.getPrimFieldValues(obj, primVals);
|
||||
bout.write(primVals, 0, primDataSize, false);
|
||||
|
||||
ObjectStreamField[] fields = desc.getFields(false);
|
||||
Object[] objVals = new Object[desc.getNumObjFields()];
|
||||
int numPrimFields = fields.length - objVals.length;
|
||||
desc.getObjFieldValues(obj, objVals);
|
||||
for (int i = 0; i < objVals.length; i++) {
|
||||
if (extendedDebugInfo) {
|
||||
debugInfoStack.push(
|
||||
"field (class \"" + desc.getName() + "\", name: \"" +
|
||||
fields[numPrimFields + i].getName() + "\", type: \"" +
|
||||
fields[numPrimFields + i].getType() + "\")");
|
||||
if (primDataSize > 0) {
|
||||
if (primVals == null || primVals.length < primDataSize) {
|
||||
primVals = new byte[primDataSize];
|
||||
}
|
||||
try {
|
||||
writeObject0(objVals[i],
|
||||
fields[numPrimFields + i].isUnshared());
|
||||
} finally {
|
||||
desc.getPrimFieldValues(obj, primVals);
|
||||
bout.write(primVals, 0, primDataSize, false);
|
||||
}
|
||||
|
||||
int numObjFields = desc.getNumObjFields();
|
||||
if (numObjFields > 0) {
|
||||
ObjectStreamField[] fields = desc.getFields(false);
|
||||
Object[] objVals = new Object[numObjFields];
|
||||
int numPrimFields = fields.length - objVals.length;
|
||||
desc.getObjFieldValues(obj, objVals);
|
||||
for (int i = 0; i < objVals.length; i++) {
|
||||
if (extendedDebugInfo) {
|
||||
debugInfoStack.pop();
|
||||
debugInfoStack.push(
|
||||
"field (class \"" + desc.getName() + "\", name: \"" +
|
||||
fields[numPrimFields + i].getName() + "\", type: \"" +
|
||||
fields[numPrimFields + i].getType() + "\")");
|
||||
}
|
||||
try {
|
||||
writeObject0(objVals[i],
|
||||
fields[numPrimFields + i].isUnshared());
|
||||
} finally {
|
||||
if (extendedDebugInfo) {
|
||||
debugInfoStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2464,7 +2468,9 @@ public class ObjectOutputStream
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
if (!stack.isEmpty()) {
|
||||
for(int i = stack.size(); i > 0; i-- ) {
|
||||
buffer.append(stack.get(i-1) + ((i != 1) ? "\n" : ""));
|
||||
buffer.append(stack.get(i - 1));
|
||||
if (i != 1)
|
||||
buffer.append('\n');
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
|
@ -1471,43 +1471,56 @@ public class ObjectStreamClass implements Serializable {
|
||||
return name1.equals(name2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns JVM type signature for given primitive.
|
||||
*/
|
||||
private static String getPrimitiveSignature(Class<?> cl) {
|
||||
if (cl == Integer.TYPE)
|
||||
return "I";
|
||||
else if (cl == Byte.TYPE)
|
||||
return "B";
|
||||
else if (cl == Long.TYPE)
|
||||
return "J";
|
||||
else if (cl == Float.TYPE)
|
||||
return "F";
|
||||
else if (cl == Double.TYPE)
|
||||
return "D";
|
||||
else if (cl == Short.TYPE)
|
||||
return "S";
|
||||
else if (cl == Character.TYPE)
|
||||
return "C";
|
||||
else if (cl == Boolean.TYPE)
|
||||
return "Z";
|
||||
else if (cl == Void.TYPE)
|
||||
return "V";
|
||||
else
|
||||
throw new InternalError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns JVM type signature for given class.
|
||||
*/
|
||||
private static String getClassSignature(Class<?> cl) {
|
||||
StringBuilder sbuf = new StringBuilder();
|
||||
while (cl.isArray()) {
|
||||
sbuf.append('[');
|
||||
cl = cl.getComponentType();
|
||||
}
|
||||
if (cl.isPrimitive()) {
|
||||
if (cl == Integer.TYPE) {
|
||||
sbuf.append('I');
|
||||
} else if (cl == Byte.TYPE) {
|
||||
sbuf.append('B');
|
||||
} else if (cl == Long.TYPE) {
|
||||
sbuf.append('J');
|
||||
} else if (cl == Float.TYPE) {
|
||||
sbuf.append('F');
|
||||
} else if (cl == Double.TYPE) {
|
||||
sbuf.append('D');
|
||||
} else if (cl == Short.TYPE) {
|
||||
sbuf.append('S');
|
||||
} else if (cl == Character.TYPE) {
|
||||
sbuf.append('C');
|
||||
} else if (cl == Boolean.TYPE) {
|
||||
sbuf.append('Z');
|
||||
} else if (cl == Void.TYPE) {
|
||||
sbuf.append('V');
|
||||
} else {
|
||||
throw new InternalError();
|
||||
}
|
||||
} else {
|
||||
sbuf.append('L' + cl.getName().replace('.', '/') + ';');
|
||||
}
|
||||
return sbuf.toString();
|
||||
static String getClassSignature(Class<?> cl) {
|
||||
if (cl.isPrimitive())
|
||||
return getPrimitiveSignature(cl);
|
||||
else
|
||||
return appendClassSignature(new StringBuilder(), cl).toString();
|
||||
}
|
||||
|
||||
private static StringBuilder appendClassSignature(StringBuilder sbuf, Class<?> cl) {
|
||||
while (cl.isArray()) {
|
||||
sbuf.append('[');
|
||||
cl = cl.getComponentType();
|
||||
}
|
||||
|
||||
if (cl.isPrimitive())
|
||||
sbuf.append(getPrimitiveSignature(cl));
|
||||
else
|
||||
sbuf.append('L').append(cl.getName().replace('.', '/')).append(';');
|
||||
|
||||
return sbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns JVM type signature for given list of parameters and return type.
|
||||
*/
|
||||
@ -1517,10 +1530,10 @@ public class ObjectStreamClass implements Serializable {
|
||||
StringBuilder sbuf = new StringBuilder();
|
||||
sbuf.append('(');
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
sbuf.append(getClassSignature(paramTypes[i]));
|
||||
appendClassSignature(sbuf, paramTypes[i]);
|
||||
}
|
||||
sbuf.append(')');
|
||||
sbuf.append(getClassSignature(retType));
|
||||
appendClassSignature(sbuf, retType);
|
||||
return sbuf.toString();
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ public class ObjectStreamField
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.unshared = unshared;
|
||||
signature = getClassSignature(type).intern();
|
||||
signature = ObjectStreamClass.getClassSignature(type).intern();
|
||||
field = null;
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ public class ObjectStreamField
|
||||
name = field.getName();
|
||||
Class<?> ftype = field.getType();
|
||||
type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
|
||||
signature = getClassSignature(ftype).intern();
|
||||
signature = ObjectStreamClass.getClassSignature(ftype).intern();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -286,41 +286,4 @@ public class ObjectStreamField
|
||||
String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns JVM type signature for given class.
|
||||
*/
|
||||
private static String getClassSignature(Class<?> cl) {
|
||||
StringBuilder sbuf = new StringBuilder();
|
||||
while (cl.isArray()) {
|
||||
sbuf.append('[');
|
||||
cl = cl.getComponentType();
|
||||
}
|
||||
if (cl.isPrimitive()) {
|
||||
if (cl == Integer.TYPE) {
|
||||
sbuf.append('I');
|
||||
} else if (cl == Byte.TYPE) {
|
||||
sbuf.append('B');
|
||||
} else if (cl == Long.TYPE) {
|
||||
sbuf.append('J');
|
||||
} else if (cl == Float.TYPE) {
|
||||
sbuf.append('F');
|
||||
} else if (cl == Double.TYPE) {
|
||||
sbuf.append('D');
|
||||
} else if (cl == Short.TYPE) {
|
||||
sbuf.append('S');
|
||||
} else if (cl == Character.TYPE) {
|
||||
sbuf.append('C');
|
||||
} else if (cl == Boolean.TYPE) {
|
||||
sbuf.append('Z');
|
||||
} else if (cl == Void.TYPE) {
|
||||
sbuf.append('V');
|
||||
} else {
|
||||
throw new InternalError();
|
||||
}
|
||||
} else {
|
||||
sbuf.append('L' + cl.getName().replace('.', '/') + ';');
|
||||
}
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ final class SerialCallbackContext {
|
||||
return desc;
|
||||
}
|
||||
|
||||
private void checkAndSetUsed() throws NotActiveException {
|
||||
public void checkAndSetUsed() throws NotActiveException {
|
||||
if (thread != Thread.currentThread()) {
|
||||
throw new NotActiveException(
|
||||
"not in readObject invocation or fields already read");
|
||||
|
Loading…
x
Reference in New Issue
Block a user