Commit 4480b3dc by Mark Wielaard Committed by Mark Wielaard

Makefile.am (nat_source_files): Remove java/io/natObjectOutputStream.cc.

        * Makefile.am (nat_source_files): Remove
        java/io/natObjectOutputStream.cc.
        * Makefile.in: Regenerated.
        * mauve-libgcj: Don't exclude java.io.ObjectInputOutput tests.
        * java/io/ObjectStreamField.java (typename): New field.
        (ObjectStreamField(String, Class)): Initialize new field.
        (ObjectStreamField(String, String)): New Constructor.
        (getTypeCode): Use new field.
        (getTypeString): Use new field.
        * java/io/ObjectOutputStream.java (writeObject): Rethrow fatal
        ObjectStreamExceptions. Remember and reset old BlockDataMode.
        Handle reading of Proxy classes. Never drain(), just write
        TC_ENDBLOCKDATA. Rethrow ObjectStreamExceptions.
        (drain): Check writeDataAsBlocks before calling writeBlockDataHeader.
        (flush): Call flush(), not just drain().
        (writeBoolean): Always use blockDataOutput.
        (writeByte): Likewise.
        (writeShort): Likewise.
        (writeChar): Likewise.
        (writeInt): Likewise.
        (writeLong): Likewise.
        (writeFloat): Likewise.
        (writeDouble): Likewise.
        (writeBytes): Likewise.
        (putfield (put(String,Object))): Throw IllegalArgumentException if
        field cannot be found.
        (putfield (write(ObjectOutput))): Remember old BlockDataMode.
        (writeArraySizeAndElements): Write byte[] in one go.
        (writeFields): Write TC_ENDBLOCKDATA when call_write_method, otherwise
        set BlockDataMode to false.
        (annotateProxyClass): New method.
        (defaultProtocolVersion): Now defaults to PROTOCOL_VERSION_2
        (getField): No longer native.
        (getMethod): Likewise.
        (setBlockDataMode): Always drain() on switch, return old mode.
        (static): New static code block.
        * java/io/natObjectOutputStream.cc: Removed.
        * java/io/ObjectInputStream.java (getField): No longer native.
        (getMethod): Likewise.
        (readObject): Remember and reset old BlockDataMode. Track whether
        object is consumed. Handle TC_ENDBLOCKDATA, TC_PROXYCLASSDESC and
        TC_LONGSTRING.
        (defaultReadObject): Set BlockDataMode to false during readFields.
        (resolveClass): Create new SecurityManager if necessary.
        Use Class.forName() if null ClassLoader found.
        (read(byte[],int,int): Copy remaining bytes to data before calling
        readNextBlock().
        (readFields): Set and reset BlockDataMode on call_read_method.
        Catch NoSuchFieldErrors.
        (setBlockDataMode): Return old mode.
        (static): New static code block.
        * java/io/natObjectInputStream.cc (getField): Removed.
        (getMethod): Likewise.

From-SVN: r63556
parent 28727f1f
2003-02-28 Mark Wielaard <mark@klomp.org>
* Makefile.am (nat_source_files): Remove
java/io/natObjectOutputStream.cc.
* Makefile.in: Regenerated.
* mauve-libgcj: Don't exclude java.io.ObjectInputOutput tests.
* java/io/ObjectStreamField.java (typename): New field.
(ObjectStreamField(String, Class)): Initialize new field.
(ObjectStreamField(String, String)): New Constructor.
(getTypeCode): Use new field.
(getTypeString): Use new field.
* java/io/ObjectOutputStream.java (writeObject): Rethrow fatal
ObjectStreamExceptions. Remember and reset old BlockDataMode.
Handle reading of Proxy classes. Never drain(), just write
TC_ENDBLOCKDATA. Rethrow ObjectStreamExceptions.
(drain): Check writeDataAsBlocks before calling writeBlockDataHeader.
(flush): Call flush(), not just drain().
(writeBoolean): Always use blockDataOutput.
(writeByte): Likewise.
(writeShort): Likewise.
(writeChar): Likewise.
(writeInt): Likewise.
(writeLong): Likewise.
(writeFloat): Likewise.
(writeDouble): Likewise.
(writeBytes): Likewise.
(putfield (put(String,Object))): Throw IllegalArgumentException if
field cannot be found.
(putfield (write(ObjectOutput))): Remember old BlockDataMode.
(writeArraySizeAndElements): Write byte[] in one go.
(writeFields): Write TC_ENDBLOCKDATA when call_write_method, otherwise
set BlockDataMode to false.
(annotateProxyClass): New method.
(defaultProtocolVersion): Now defaults to PROTOCOL_VERSION_2
(getField): No longer native.
(getMethod): Likewise.
(setBlockDataMode): Always drain() on switch, return old mode.
(static): New static code block.
* java/io/natObjectOutputStream.cc: Removed.
* java/io/ObjectInputStream.java (getField): No longer native.
(getMethod): Likewise.
(readObject): Remember and reset old BlockDataMode. Track whether
object is consumed. Handle TC_ENDBLOCKDATA, TC_PROXYCLASSDESC and
TC_LONGSTRING.
(defaultReadObject): Set BlockDataMode to false during readFields.
(resolveClass): Create new SecurityManager if necessary.
Use Class.forName() if null ClassLoader found.
(read(byte[],int,int): Copy remaining bytes to data before calling
readNextBlock().
(readFields): Set and reset BlockDataMode on call_read_method.
Catch NoSuchFieldErrors.
(setBlockDataMode): Return old mode.
(static): New static code block.
* java/io/natObjectInputStream.cc (getField): Removed.
(getMethod): Likewise.
2003-02-27 Michael Koch <konqueror@gmx.de>
* java/beans/Beans.java,
......
......@@ -2496,7 +2496,6 @@ gnu/java/nio/natSocketChannelImpl.cc \
java/io/natFile.cc \
java/io/natFileDescriptor.cc \
java/io/natObjectInputStream.cc \
java/io/natObjectOutputStream.cc \
java/io/natVMObjectStreamClass.cc \
java/lang/natCharacter.cc \
java/lang/natClass.cc \
......
......@@ -2257,7 +2257,6 @@ gnu/java/nio/natSocketChannelImpl.cc \
java/io/natFile.cc \
java/io/natFileDescriptor.cc \
java/io/natObjectInputStream.cc \
java/io/natObjectOutputStream.cc \
java/io/natVMObjectStreamClass.cc \
java/lang/natCharacter.cc \
java/lang/natClass.cc \
......@@ -2432,11 +2431,11 @@ gnu/java/nio/natIntBufferImpl.lo gnu/java/nio/natLongBufferImpl.lo \
gnu/java/nio/natSelectorImpl.lo gnu/java/nio/natShortBufferImpl.lo \
gnu/java/nio/natSocketChannelImpl.lo java/io/natFile.lo \
java/io/natFileDescriptor.lo java/io/natObjectInputStream.lo \
java/io/natObjectOutputStream.lo java/io/natVMObjectStreamClass.lo \
java/lang/natCharacter.lo java/lang/natClass.lo \
java/lang/natClassLoader.lo java/lang/natConcreteProcess.lo \
java/lang/natDouble.lo java/lang/natFloat.lo java/lang/natMath.lo \
java/lang/natObject.lo java/lang/natRuntime.lo java/lang/natString.lo \
java/io/natVMObjectStreamClass.lo java/lang/natCharacter.lo \
java/lang/natClass.lo java/lang/natClassLoader.lo \
java/lang/natConcreteProcess.lo java/lang/natDouble.lo \
java/lang/natFloat.lo java/lang/natMath.lo java/lang/natObject.lo \
java/lang/natRuntime.lo java/lang/natString.lo \
java/lang/natStringBuffer.lo java/lang/natSystem.lo \
java/lang/natThread.lo java/lang/natVMSecurityManager.lo \
java/lang/ref/natReference.lo java/lang/reflect/natArray.lo \
......@@ -2599,7 +2598,7 @@ libgcj-test.spec.in libgcj.spec.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = gtar
TAR = tar
GZIP_ENV = --best
DIST_SUBDIRS = @DIRLTDL@ testsuite gcj include @DIRLTDL@ gcj include
DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
......@@ -3270,7 +3269,6 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/io/WriteAbortedException.P .deps/java/io/Writer.P \
.deps/java/io/natFile.P .deps/java/io/natFileDescriptor.P \
.deps/java/io/natObjectInputStream.P \
.deps/java/io/natObjectOutputStream.P \
.deps/java/io/natVMObjectStreamClass.P \
.deps/java/lang/AbstractMethodError.P \
.deps/java/lang/ArithmeticException.P \
......
/* ObjectInputStream.java -- Class used to read serialized objects
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
......@@ -38,8 +38,6 @@ exception statement from your version. */
package java.io;
import gnu.classpath.Configuration;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
......@@ -53,7 +51,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import gnu.classpath.Configuration;
public class ObjectInputStream extends InputStream
implements ObjectInput, ObjectStreamConstants
......@@ -130,29 +128,42 @@ public class ObjectInputStream extends InputStream
Object ret_val;
was_deserializing = this.isDeserializing;
if (! was_deserializing)
setBlockDataMode (false);
boolean is_consumed = false;
boolean old_mode = setBlockDataMode (false);
this.isDeserializing = true;
byte marker = this.realInputStream.readByte ();
dumpElement ("MARKER: 0x" + Integer.toHexString(marker) + " ");
try
{
switch (marker)
{
case TC_ENDBLOCKDATA:
{
ret_val = null;
is_consumed = true;
break;
}
case TC_BLOCKDATA:
case TC_BLOCKDATALONG:
{
if (marker == TC_BLOCKDATALONG)
dumpElementln ("BLOCKDATALONG");
else
dumpElementln ("BLOCKDATA");
readNextBlock (marker);
throw new StreamCorruptedException ("Unexpected blockData");
}
case TC_NULL:
{
dumpElementln ("NULL");
ret_val = null;
break;
}
case TC_REFERENCE:
{
......@@ -174,6 +185,38 @@ public class ObjectInputStream extends InputStream
break;
}
case TC_PROXYCLASSDESC:
{
dumpElementln ("PROXYCLASS");
int n_intf = this.realInputStream.readInt();
String[] intfs = new String[n_intf];
for (int i = 0; i < n_intf; i++)
{
intfs[i] = this.realInputStream.readUTF();
System.out.println(intfs[i]);
}
boolean oldmode = setBlockDataMode (true);
Class cl = resolveProxyClass(intfs);
setBlockDataMode(oldmode);
ObjectStreamClass osc = ObjectStreamClass.lookup(cl);
assignNewHandle (osc);
if (!is_consumed)
{
byte b = this.realInputStream.readByte ();
if (b != TC_ENDBLOCKDATA)
throw new IOException ("Data annotated to class was not consumed." + b);
}
else
is_consumed = false;
ObjectStreamClass superosc = (ObjectStreamClass)readObject ();
osc.setSuperclass (superosc);
ret_val = osc;
break;
}
case TC_CLASSDESC:
{
dumpElement ("CLASSDESC NAME=");
......@@ -205,19 +248,25 @@ public class ObjectInputStream extends InputStream
else
class_name = String.valueOf (type_code);
// There're many cases you can't get java.lang.Class from
// typename if your context class loader can't load it,
// then use typename to construct the field
fields[i] =
new ObjectStreamField (field_name,
TypeSignature.getClassForEncoding
(class_name));
new ObjectStreamField (field_name, class_name);
}
Class cl = resolveClass (osc);
osc.setClass (cl);
setBlockDataMode (false);
boolean oldmode = setBlockDataMode (true);
osc.setClass (resolveClass (osc));
setBlockDataMode (oldmode);
if (this.realInputStream.readByte () != TC_ENDBLOCKDATA)
throw new IOException ("Data annotated to class was not consumed.");
dumpElementln ("ENDBLOCKDATA ");
if (!is_consumed)
{
byte b = this.realInputStream.readByte ();
if (b != TC_ENDBLOCKDATA)
throw new IOException ("Data annotated to class was not consumed." + b);
}
else
is_consumed = false;
osc.setSuperclass ((ObjectStreamClass)readObject ());
ret_val = osc;
......@@ -225,6 +274,7 @@ public class ObjectInputStream extends InputStream
}
case TC_STRING:
case TC_LONGSTRING:
{
dumpElement ("STRING=");
String s = this.realInputStream.readUTF ();
......@@ -287,13 +337,14 @@ public class ObjectInputStream extends InputStream
boolean read_from_blocks = ((osc.getFlags () & SC_BLOCK_DATA) != 0);
boolean oldmode = this.readDataFromBlock;
if (read_from_blocks)
setBlockDataMode (true);
obj.readExternal (this);
if (read_from_blocks)
setBlockDataMode (false);
setBlockDataMode (oldmode);
ret_val = processResolution (obj, handle);
break;
......@@ -306,8 +357,8 @@ public class ObjectInputStream extends InputStream
|| Modifier.isAbstract (first_nonserial.getModifiers ()))
first_nonserial = first_nonserial.getSuperclass ();
// DEBUGln ("Using " + first_nonserial
// + " as starting point for constructing " + clazz);
// DEBUGln ("Using " + first_nonserial
// + " as starting point for constructing " + clazz);
Object obj = null;
obj = newObject (clazz, first_nonserial);
......@@ -321,7 +372,7 @@ public class ObjectInputStream extends InputStream
ObjectStreamClass[] hierarchy =
ObjectStreamClass.getObjectStreamClasses (clazz);
// DEBUGln ("Got class hierarchy of depth " + hierarchy.length);
// DEBUGln ("Got class hierarchy of depth " + hierarchy.length);
boolean has_read;
for (int i=0; i < hierarchy.length; i++)
......@@ -394,18 +445,22 @@ public class ObjectInputStream extends InputStream
}
default:
throw new IOException ("Unknown marker on stream");
throw new IOException ("Unknown marker on stream: " + marker);
}
}
finally
{
setBlockDataMode (old_mode);
this.isDeserializing = was_deserializing;
if (! was_deserializing)
{
setBlockDataMode (true);
if (validators.size () > 0)
invokeValidators ();
}
}
return ret_val;
}
......@@ -439,9 +494,11 @@ public class ObjectInputStream extends InputStream
if (fieldsAlreadyRead)
throw new NotActiveException ("defaultReadObject called but fields already read from stream (by defaultReadObject or readFields)");
boolean oldmode = setBlockDataMode(false);
readFields (this.currentObject,
this.currentObjectStreamClass.fields,
false, this.currentObjectStreamClass);
setBlockDataMode(oldmode);
fieldsAlreadyRead = true;
}
......@@ -500,13 +557,18 @@ public class ObjectInputStream extends InputStream
throws ClassNotFoundException, IOException
{
SecurityManager sm = System.getSecurityManager ();
if (sm == null)
sm = new SecurityManager () {};
// FIXME: currentClassLoader doesn't yet do anything useful. We need
// to call forName() with the classloader of the class which called
// readObject(). See SecurityManager.getClassContext().
ClassLoader cl = currentClassLoader (sm);
return Class.forName (osc.getName (), true, cl);
if (cl == null)
return Class.forName (osc.getName ());
else
return cl.loadClass (osc.getName ());
}
/**
......@@ -617,7 +679,17 @@ public class ObjectInputStream extends InputStream
if (this.readDataFromBlock)
{
if (this.blockDataPosition + length > this.blockDataBytes)
{
int remain = this.blockDataBytes - this.blockDataPosition;
if (remain != 0)
{
System.arraycopy (this.blockData, this.blockDataPosition,
data, offset, remain);
offset += remain;
length -= remain;
}
readNextBlock ();
}
System.arraycopy (this.blockData, this.blockDataPosition,
data, offset, length);
......@@ -785,11 +857,11 @@ public class ObjectInputStream extends InputStream
// Apparently Block data is not used with GetField as per
// empirical evidence against JDK 1.2. Also see Mauve test
// java.io.ObjectInputOutput.Test.GetPutField.
setBlockDataMode (false);
boolean oldmode = setBlockDataMode (false);
readFully (prim_field_data);
for (int i = 0; i < objs.length; ++ i)
objs[i] = readObject ();
setBlockDataMode (true);
setBlockDataMode (oldmode);
return new GetField ()
{
......@@ -990,7 +1062,7 @@ public class ObjectInputStream extends InputStream
de serialization mechanism provided by
<code>ObjectInputStream</code>. To make this method be used for
writing objects, subclasses must invoke the 0-argument
constructor on this class from there constructor.
constructor on this class from their constructor.
@see ObjectInputStream ()
*/
......@@ -1175,9 +1247,9 @@ public class ObjectInputStream extends InputStream
{
// DEBUGln (" call_read_method is true");
fieldsAlreadyRead = false;
setBlockDataMode (true);
boolean oldmode = setBlockDataMode (true);
callReadMethod (obj, stream_osc.forClass ());
setBlockDataMode (false);
setBlockDataMode (oldmode);
return;
}
......@@ -1237,6 +1309,8 @@ public class ObjectInputStream extends InputStream
}
}
try
{
if (type == Boolean.TYPE)
{
boolean value =
......@@ -1318,20 +1392,26 @@ public class ObjectInputStream extends InputStream
real_field.getTypeString (), value);
}
}
catch (NoSuchFieldError e)
{
dumpElementln("XXXX " + field_name + " does not exist.");
}
}
}
// Toggles writing primitive data to block-data buffer.
private void setBlockDataMode (boolean on)
private boolean setBlockDataMode (boolean on)
{
// DEBUGln ("Setting block data mode to " + on);
boolean oldmode = this.readDataFromBlock;
this.readDataFromBlock = on;
if (on)
this.dataInputStream = this.blockDataInput;
else
this.dataInputStream = this.realInputStream;
return oldmode;
}
......@@ -1380,11 +1460,17 @@ public class ObjectInputStream extends InputStream
return ClassLoader.getSystemClassLoader ();
}
private static native Field getField (Class klass, String name)
throws java.lang.NoSuchFieldException;
private static Field getField (Class klass, String name)
throws java.lang.NoSuchFieldException
{
return klass.getDeclaredField(name);
}
private static native Method getMethod (Class klass, String name, Class args[])
throws java.lang.NoSuchMethodException;
private static Method getMethod (Class klass, String name, Class args[])
throws java.lang.NoSuchMethodException
{
return klass.getDeclaredMethod(name, args);
}
private void callReadMethod (Object obj, Class klass) throws IOException
{
......@@ -1593,6 +1679,14 @@ public class ObjectInputStream extends InputStream
if (Configuration.DEBUG && dump)
System.out.println(msg);
}
static
{
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary ("javaio");
}
}
}
......
/* ObjectOutputStream.java -- Class used to write serialized objects
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
......@@ -46,6 +46,7 @@ import java.util.Hashtable;
import gnu.java.io.ObjectIdentityWrapper;
import gnu.java.lang.reflect.TypeSignature;
import gnu.classpath.Configuration;
/**
An <code>ObjectOutputStream</code> can be used to write objects
......@@ -173,16 +174,12 @@ public class ObjectOutputStream extends OutputStream
}
boolean was_serializing = isSerializing;
if (! was_serializing)
setBlockDataMode (false);
boolean old_mode = setBlockDataMode (false);
try
{
isSerializing = true;
boolean replaceDone = false;
drain ();
Object replacedObject = null;
while (true)
{
......@@ -202,9 +199,29 @@ public class ObjectOutputStream extends OutputStream
if (obj instanceof Class)
{
realOutput.writeByte (TC_CLASS);
writeObject (ObjectStreamClass.lookup ((Class)obj));
Class cl = (Class)obj;
ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject(cl);
assignNewHandle (obj);
realOutput.writeByte (TC_CLASS);
if (!osc.isProxyClass)
{
writeObject(osc);
}
else
{
realOutput.writeByte (TC_PROXYCLASSDESC);
Class[] intfs = cl.getInterfaces();
realOutput.writeInt(intfs.length);
for (int i = 0; i < intfs.length; i++)
realOutput.writeUTF(intfs[i].getName());
boolean oldmode = setBlockDataMode (true);
annotateProxyClass(cl);
setBlockDataMode (oldmode);
realOutput.writeByte(TC_ENDBLOCKDATA);
writeObject (osc.getSuper());
}
break;
}
......@@ -238,9 +255,9 @@ public class ObjectOutputStream extends OutputStream
writeObject (field.getTypeString ());
}
setBlockDataMode (true);
boolean oldmode = setBlockDataMode (true);
annotateClass (osc.forClass ());
setBlockDataMode (false);
setBlockDataMode (oldmode);
realOutput.writeByte (TC_ENDBLOCKDATA);
if (osc.isSerializable ())
......@@ -250,9 +267,6 @@ public class ObjectOutputStream extends OutputStream
break;
}
Object replacedObject = null;
if ((replacementEnabled || obj instanceof Serializable)
&& ! replaceDone)
{
......@@ -297,7 +311,7 @@ public class ObjectOutputStream extends OutputStream
}
Class clazz = obj.getClass ();
ObjectStreamClass osc = ObjectStreamClass.lookup (clazz);
ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject (clazz);
if (osc == null)
throw new NotSerializableException (clazz.getName ());
......@@ -328,7 +342,7 @@ public class ObjectOutputStream extends OutputStream
if (protocolVersion == PROTOCOL_VERSION_2)
{
setBlockDataMode (false);
drain ();
realOutput.writeByte (TC_ENDBLOCKDATA);
}
break;
......@@ -351,11 +365,6 @@ public class ObjectOutputStream extends OutputStream
writeFields (obj, currentObjectStreamClass.fields,
has_write);
if (has_write)
{
drain ();
realOutput.writeByte (TC_ENDBLOCKDATA);
}
}
currentObject = null;
......@@ -367,11 +376,17 @@ public class ObjectOutputStream extends OutputStream
throw new NotSerializableException (clazz.getName ());
} // end pseudo-loop
}
catch (ObjectStreamException ose)
{
// Rethrow these are fatal.
throw ose;
}
catch (IOException e)
{
realOutput.writeByte (TC_EXCEPTION);
reset (true);
setBlockDataMode (false);
try
{
writeObject (e);
......@@ -387,8 +402,7 @@ public class ObjectOutputStream extends OutputStream
{
isSerializing = was_serializing;
if (! was_serializing)
setBlockDataMode (true);
setBlockDataMode (old_mode);
}
}
......@@ -466,8 +480,8 @@ public class ObjectOutputStream extends OutputStream
according to the specified protocol. There are currently two
different protocols, specified by <code>PROTOCOL_VERSION_1</code>
and <code>PROTOCOL_VERSION_2</code>. This implementation writes
data using <code>PROTOCOL_VERSION_1</code> by default, as is done
by the JDK 1.1.
data using <code>PROTOCOL_VERSION_2</code> by default, as is done
by the JDK 1.2.
A non-portable method, <code>setDefaultProtocolVersion (int
version)</code> is provided to change the default protocol
......@@ -528,6 +542,8 @@ public class ObjectOutputStream extends OutputStream
protected void annotateClass (Class cl) throws IOException
{}
protected void annotateProxyClass(Class cl) throws IOException
{}
/**
Allows subclasses to replace objects that are written to the
......@@ -702,6 +718,7 @@ public class ObjectOutputStream extends OutputStream
if (blockDataCount == 0)
return;
if (writeDataAsBlocks)
writeBlockDataHeader (blockDataCount);
realOutput.write (blockData, 0, blockDataCount);
blockDataCount = 0;
......@@ -713,7 +730,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void close () throws IOException
{
drain ();
flush ();
realOutput.close ();
}
......@@ -723,7 +740,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeBoolean (boolean data) throws IOException
{
dataOutput.writeBoolean (data);
blockDataOutput.writeBoolean (data);
}
......@@ -732,7 +749,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeByte (int data) throws IOException
{
dataOutput.writeByte (data);
blockDataOutput.writeByte (data);
}
......@@ -741,7 +758,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeShort (int data) throws IOException
{
dataOutput.writeShort (data);
blockDataOutput.writeShort (data);
}
......@@ -750,7 +767,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeChar (int data) throws IOException
{
dataOutput.writeChar (data);
blockDataOutput.writeChar (data);
}
......@@ -759,7 +776,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeInt (int data) throws IOException
{
dataOutput.writeInt (data);
blockDataOutput.writeInt (data);
}
......@@ -768,7 +785,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeLong (long data) throws IOException
{
dataOutput.writeLong (data);
blockDataOutput.writeLong (data);
}
......@@ -777,7 +794,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeFloat (float data) throws IOException
{
dataOutput.writeFloat (data);
blockDataOutput.writeFloat (data);
}
......@@ -786,7 +803,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeDouble (double data) throws IOException
{
dataOutput.writeDouble (data);
blockDataOutput.writeDouble (data);
}
......@@ -795,7 +812,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeBytes (String data) throws IOException
{
dataOutput.writeBytes (data);
blockDataOutput.writeBytes (data);
}
......@@ -965,6 +982,8 @@ public class ObjectOutputStream extends OutputStream
{
ObjectStreamField field
= currentObjectStreamClass.getField (name);
if (field == null)
throw new IllegalArgumentException ();
if (value != null &&
! field.getType ().isAssignableFrom (value.getClass ()))
throw new IllegalArgumentException ();
......@@ -976,11 +995,11 @@ public class ObjectOutputStream extends OutputStream
// Apparently Block data is not used with PutField as per
// empirical evidence against JDK 1.2. Also see Mauve test
// java.io.ObjectInputOutput.Test.GetPutField.
setBlockDataMode (false);
boolean oldmode = setBlockDataMode (false);
out.write (prim_field_data);
for (int i = 0; i < objs.length; ++ i)
out.writeObject (objs[i]);
setBlockDataMode (true);
setBlockDataMode (oldmode);
}
private void checkType (ObjectStreamField field, char type)
......@@ -1067,8 +1086,7 @@ public class ObjectOutputStream extends OutputStream
{
byte[] cast_array = (byte[])array;
realOutput.writeInt (length);
for (int i=0; i < length; i++)
realOutput.writeByte (cast_array[i]);
realOutput.write(cast_array, 0, length);
return;
}
if (clazz == Character.TYPE)
......@@ -1142,9 +1160,11 @@ public class ObjectOutputStream extends OutputStream
setBlockDataMode (true);
callWriteMethod (obj);
setBlockDataMode (false);
realOutput.writeByte (TC_ENDBLOCKDATA);
return;
}
boolean oldmode = setBlockDataMode (false);
String field_name;
Class type;
for (int i=0; i < fields.length; i++)
......@@ -1170,20 +1190,28 @@ public class ObjectOutputStream extends OutputStream
realOutput.writeShort (getShortField (obj, field_name));
else
writeObject (getObjectField (obj, field_name,
TypeSignature.getEncodingOfClass (type)));
fields[i].getTypeString ()));
}
setBlockDataMode(oldmode);
}
// Toggles writing primitive data to block-data buffer.
private void setBlockDataMode (boolean on)
private boolean setBlockDataMode (boolean on) throws IOException
{
if (on == writeDataAsBlocks)
return on;
drain();
boolean oldmode = writeDataAsBlocks;
writeDataAsBlocks = on;
if (on)
dataOutput = blockDataOutput;
else
dataOutput = realOutput;
return oldmode;
}
......@@ -1355,16 +1383,22 @@ public class ObjectOutputStream extends OutputStream
}
}
private static native Field getField (Class klass, String name)
throws java.lang.NoSuchFieldException;
private static Field getField (Class klass, String name)
throws java.lang.NoSuchFieldException
{
return klass.getDeclaredField(name);
}
private static native Method getMethod (Class klass, String name, Class[] args)
throws java.lang.NoSuchMethodException;
private static Method getMethod (Class klass, String name, Class[] args)
throws java.lang.NoSuchMethodException
{
return klass.getDeclaredMethod(name, args);
}
// this value comes from 1.2 spec, but is used in 1.1 as well
private final static int BUFFER_SIZE = 1024;
private static int defaultProtocolVersion = PROTOCOL_VERSION_1;
private static int defaultProtocolVersion = PROTOCOL_VERSION_2;
private DataOutputStream dataOutput;
private boolean writeDataAsBlocks;
......@@ -1382,4 +1416,12 @@ public class ObjectOutputStream extends OutputStream
private Hashtable OIDLookupTable;
private int protocolVersion;
private boolean useSubclassMethod;
static
{
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary ("javaio");
}
}
}
......@@ -47,6 +47,21 @@ public class ObjectStreamField implements java.lang.Comparable
{
this.name = name;
this.type = type;
this.typename = TypeSignature.getEncodingOfClass(type);
}
/**
* There're many cases you can't get java.lang.Class from typename if your context
* class loader can't load it, then use typename to construct the field
*/
ObjectStreamField (String name, String typename){
this.name = name;
this.typename = typename;
try{
type = TypeSignature.getClassForEncoding(typename);
}catch(ClassNotFoundException e){
type = Object.class; //??
}
}
public String getName ()
......@@ -61,12 +76,13 @@ public class ObjectStreamField implements java.lang.Comparable
public char getTypeCode ()
{
return TypeSignature.getEncodingOfClass (type).charAt (0);
return typename.charAt (0);
}
public String getTypeString ()
{
return TypeSignature.getEncodingOfClass (type);
// use intern()
return typename.intern();
}
public int getOffset ()
......@@ -106,5 +122,6 @@ public class ObjectStreamField implements java.lang.Comparable
private String name;
private Class type;
private String typename;
private int offset = -1; // XXX make sure this is correct
}
......@@ -69,16 +69,3 @@ java::io::ObjectInputStream::callConstructor (jclass klass, jobject obj)
+ m->offset);
_Jv_CallAnyMethodA (obj, JvPrimClass (void), meth, false, arg_types, NULL);
}
java::lang::reflect::Field *
java::io::ObjectInputStream::getField (jclass klass, jstring name)
{
return klass->getPrivateField (name);
}
java::lang::reflect::Method *
java::io::ObjectInputStream::getMethod (jclass klass, jstring name,
JArray<jclass> *arg_types)
{
return klass->getPrivateMethod (name, arg_types);
}
// natObjectOutputStream.cc - Native part of ObjectOutputStream class.
/* Copyright (C) 1998, 1999 Free Software Foundation
This ObjectOutputStream is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the ObjectOutputStream "LIBGCJ_LICENSE" for
details. */
#include <config.h>
#include <gcj/cni.h>
#include <jvm.h>
#include <java/io/ObjectOutputStream$PutField.h>
#include <java/io/ObjectOutputStream.h>
#include <java/io/IOException.h>
#include <java/lang/Class.h>
java::lang::reflect::Field *
java::io::ObjectOutputStream::getField (jclass klass, jstring name)
{
return klass->getPrivateField (name);
}
java::lang::reflect::Method *
java::io::ObjectOutputStream::getMethod (jclass klass, jstring name,
JArray<jclass> *arg_types)
{
return klass->getPrivateMethod (name, arg_types);
}
......@@ -15,7 +15,6 @@ JDBC2.0
# The following tests seem to hang or crash the testsuite.
# This a problem when running Mauve "standalone".
!java.io.ObjectInputOutput
!java.lang.reflect.Array.newInstance
# Character.unicode seems to be very broken (the test)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment