diff options
author | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-15 23:20:01 +0000 |
---|---|---|
committer | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-15 23:20:01 +0000 |
commit | 3b3101d8b5ae4f08a16c0b7111da6cad41bbd282 (patch) | |
tree | a5eb7cf42a51869cc8aa1fad7ad6a90cca47fdd8 /libjava/classpath/java/io | |
parent | 7e55c49d7d91ef9f09e93c1100119b1ab3652446 (diff) | |
download | gcc-3b3101d8b5ae4f08a16c0b7111da6cad41bbd282.tar.gz |
Imported GNU Classpath 0.19 + gcj-import-20051115.
* sources.am: Regenerated.
* Makefile.in: Likewise.
* scripts/makemake.tcl: Use glob -nocomplain.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107049 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/java/io')
-rw-r--r-- | libjava/classpath/java/io/ByteArrayOutputStream.java | 5 | ||||
-rw-r--r-- | libjava/classpath/java/io/DataOutputStream.java | 6 | ||||
-rw-r--r-- | libjava/classpath/java/io/File.java | 39 | ||||
-rw-r--r-- | libjava/classpath/java/io/FileWriter.java | 2 | ||||
-rw-r--r-- | libjava/classpath/java/io/FilterReader.java | 2 | ||||
-rw-r--r-- | libjava/classpath/java/io/InputStreamReader.java | 25 | ||||
-rw-r--r-- | libjava/classpath/java/io/LineNumberReader.java | 6 | ||||
-rw-r--r-- | libjava/classpath/java/io/ObjectInputStream.java | 588 | ||||
-rw-r--r-- | libjava/classpath/java/io/ObjectOutputStream.java | 79 | ||||
-rw-r--r-- | libjava/classpath/java/io/ObjectStreamField.java | 2 | ||||
-rw-r--r-- | libjava/classpath/java/io/OutputStreamWriter.java | 160 | ||||
-rw-r--r-- | libjava/classpath/java/io/PipedInputStream.java | 2 | ||||
-rw-r--r-- | libjava/classpath/java/io/PrintWriter.java | 75 | ||||
-rw-r--r-- | libjava/classpath/java/io/PushbackInputStream.java | 9 |
14 files changed, 591 insertions, 409 deletions
diff --git a/libjava/classpath/java/io/ByteArrayOutputStream.java b/libjava/classpath/java/io/ByteArrayOutputStream.java index e996ebbc70f..4196523d28e 100644 --- a/libjava/classpath/java/io/ByteArrayOutputStream.java +++ b/libjava/classpath/java/io/ByteArrayOutputStream.java @@ -1,5 +1,6 @@ /* BufferedReader.java - Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -192,7 +193,7 @@ public class ByteArrayOutputStream extends OutputStream */ public String toString (int hibyte) { - return new String (buf, 0, count, hibyte); + return new String (buf, hibyte, 0, count); } // Resize buffer to accommodate new bytes. diff --git a/libjava/classpath/java/io/DataOutputStream.java b/libjava/classpath/java/io/DataOutputStream.java index 39f7ed1ff24..25178160dc8 100644 --- a/libjava/classpath/java/io/DataOutputStream.java +++ b/libjava/classpath/java/io/DataOutputStream.java @@ -302,7 +302,7 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput * * @exception IOException If an error occurs * - * @see writeInt + * @see #writeInt(int) * @see DataInput#readFloat * @see Float#floatToIntBits */ @@ -326,7 +326,7 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput * * @exception IOException If an error occurs * - * @see writeLong + * @see #writeLong(long) * @see DataInput#readDouble * @see Double#doubleToLongBits */ @@ -363,7 +363,7 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput * * @exception IOException If an error occurs * - * @see writeChar + * @see #writeChar(char) */ public final void writeChars (String value) throws IOException { diff --git a/libjava/classpath/java/io/File.java b/libjava/classpath/java/io/File.java index 3b747e6bd03..3c7ac21301c 100644 --- a/libjava/classpath/java/io/File.java +++ b/libjava/classpath/java/io/File.java @@ -100,6 +100,17 @@ public class File implements Serializable, Comparable * may be an absolute or relative path name. */ private String path; + + + /** + * The time (millisecond), when the last temporary file was created. + */ + private static long last_tmp; + + /** + * The number of files, created during the current millisecond. + */ + private static int n_created; /** * This method tests whether or not the current thread is allowed to @@ -446,6 +457,8 @@ public class File implements Serializable, Comparable else return drvDir; } + else if (path.equals("")) + return System.getProperty ("user.dir"); else return System.getProperty ("user.dir") + separatorChar + path; } @@ -532,6 +545,9 @@ public class File implements Serializable, Comparable { String prefix = null; int nameSeqIndex = 0; + + if (path.equals("")) + return null; // The "prefix", if present, is the leading "/" on UNIX and // either the drive specifier (e.g. "C:") or the leading "\\" @@ -943,8 +959,8 @@ public class File implements Serializable, Comparable public URI toURI() { String abspath = getAbsolutePath(); - - if (isDirectory()) + + if (isDirectory() || path.equals("")) abspath = abspath + separatorChar; if (separatorChar == '\\') @@ -1059,7 +1075,7 @@ public class File implements Serializable, Comparable * * @since 1.2 */ - public static File createTempFile(String prefix, String suffix, + public static synchronized File createTempFile(String prefix, String suffix, File directory) throws IOException { @@ -1091,10 +1107,23 @@ public class File implements Serializable, Comparable // Now identify a file name and make sure it doesn't exist. File file; if (!VMFile.IS_DOS_8_3) - { + { do { - String filename = prefix + System.currentTimeMillis() + suffix; + long now = System.currentTimeMillis(); + if (now > last_tmp) + { + // The last temporary file was created more than 1 ms ago. + last_tmp = now; + n_created = 0; + } + else + n_created++; + + String name = Long.toHexString(now); + if (n_created > 0) + name += '_'+Integer.toHexString(n_created); + String filename = prefix + name + suffix; file = new File(directory, filename); } while (VMFile.exists(file.path)); diff --git a/libjava/classpath/java/io/FileWriter.java b/libjava/classpath/java/io/FileWriter.java index b34db83231e..ce18efe5e39 100644 --- a/libjava/classpath/java/io/FileWriter.java +++ b/libjava/classpath/java/io/FileWriter.java @@ -119,7 +119,7 @@ public class FileWriter extends OutputStreamWriter * This method intializes a new <code>FileWriter</code> object to * write to the * specified named file. This form of the constructor allows the caller - * to determin whether data should be written starting at the beginning or + * to determine whether data should be written starting at the beginning or * the end of the file. * * @param name The name of the file to write to diff --git a/libjava/classpath/java/io/FilterReader.java b/libjava/classpath/java/io/FilterReader.java index 2bd040a7f72..1abaa8a4b68 100644 --- a/libjava/classpath/java/io/FilterReader.java +++ b/libjava/classpath/java/io/FilterReader.java @@ -131,7 +131,7 @@ public abstract class FilterReader extends Reader /** * Calls the <code>in.skip(long)</code> method * - * @param numBytes The requested number of chars to skip. + * @param num_chars The requested number of chars to skip. * * @return The value returned from <code>in.skip(long)</code> * diff --git a/libjava/classpath/java/io/InputStreamReader.java b/libjava/classpath/java/io/InputStreamReader.java index 315af83e1a4..57cdc53ed22 100644 --- a/libjava/classpath/java/io/InputStreamReader.java +++ b/libjava/classpath/java/io/InputStreamReader.java @@ -38,16 +38,14 @@ exception statement from your version. */ package java.io; -import java.nio.charset.UnsupportedCharsetException; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.CoderResult; -import java.nio.charset.CodingErrorAction; +import gnu.java.nio.charset.EncodingHelper; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; -import java.nio.CharBuffer; -import java.nio.ByteBuffer; -import gnu.java.nio.charset.EncodingHelper; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; /** * This class reads characters from a byte input stream. The characters @@ -251,8 +249,12 @@ public class InputStreamReader extends Reader this.in = in; this.decoder = decoder; + Charset charset = decoder.charset(); try { - maxBytesPerChar = decoder.charset().newEncoder().maxBytesPerChar(); + if (charset == null) + maxBytesPerChar = 1f; + else + maxBytesPerChar = charset.newEncoder().maxBytesPerChar(); } catch(UnsupportedOperationException _){ maxBytesPerChar = 1f; } @@ -260,7 +262,10 @@ public class InputStreamReader extends Reader decoder.onMalformedInput(CodingErrorAction.REPLACE); decoder.onUnmappableCharacter(CodingErrorAction.REPLACE); decoder.reset(); - encoding = EncodingHelper.getOldCanonical(decoder.charset().name()); + if (charset == null) + encoding = "US-ASCII"; + else + encoding = EncodingHelper.getOldCanonical(decoder.charset().name()); } /** diff --git a/libjava/classpath/java/io/LineNumberReader.java b/libjava/classpath/java/io/LineNumberReader.java index ea418a5e4d6..5e263f76111 100644 --- a/libjava/classpath/java/io/LineNumberReader.java +++ b/libjava/classpath/java/io/LineNumberReader.java @@ -115,7 +115,7 @@ public class LineNumberReader extends BufferedReader /** * This method sets the current line number to the specified value. * - * @param line_number The new line number + * @param lineNumber The new line number */ public void setLineNumber(int lineNumber) { @@ -139,7 +139,7 @@ public class LineNumberReader extends BufferedReader * is called, the line number will be restored to the saved line number in * addition to the stream position. * - * @param readlimit The number of chars that can be read before the + * @param readLimit The number of chars that can be read before the * mark becomes invalid * * @exception IOException If an error occurs @@ -269,7 +269,7 @@ public class LineNumberReader extends BufferedReader * * @param buf The array into which the chars read should be stored * @param offset The offset into the array to start storing chars - * @param len The requested number of chars to read + * @param count The requested number of chars to read * * @return The actual number of chars read, or -1 if end of stream * diff --git a/libjava/classpath/java/io/ObjectInputStream.java b/libjava/classpath/java/io/ObjectInputStream.java index 54d5eeafadd..98a11dae3e1 100644 --- a/libjava/classpath/java/io/ObjectInputStream.java +++ b/libjava/classpath/java/io/ObjectInputStream.java @@ -39,7 +39,6 @@ exception statement from your version. */ package java.io; -import gnu.classpath.Configuration; import gnu.java.io.ObjectIdentityWrapper; import java.lang.reflect.Array; @@ -53,6 +52,8 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Hashtable; +import java.util.Iterator; +import java.util.TreeSet; import java.util.Vector; public class ObjectInputStream extends InputStream @@ -91,7 +92,6 @@ public class ObjectInputStream extends InputStream } this.resolveEnabled = false; - this.isDeserializing = false; this.blockDataPosition = 0; this.blockDataBytes = 0; this.blockData = new byte[BUFFER_SIZE]; @@ -99,7 +99,6 @@ public class ObjectInputStream extends InputStream this.realInputStream = new DataInputStream(in); this.nextOID = baseWireHandle; this.objectLookupTable = new Hashtable(); - this.validators = new Vector(); this.classLookupTable = new Hashtable(); setBlockDataMode(true); readStreamHeader(); @@ -113,7 +112,10 @@ public class ObjectInputStream extends InputStream * <code>private void readObject (ObjectInputStream)</code>. * * If an exception is thrown from this method, the stream is left in - * an undefined state. + * an undefined state. This method can also throw Errors and + * RuntimeExceptions if caused by existing readResolve() user code. + * + * @return The object read from the underlying stream. * * @exception ClassNotFoundException The class that an object being * read in belongs to cannot be found. @@ -121,291 +123,312 @@ public class ObjectInputStream extends InputStream * @exception IOException Exception from underlying * <code>InputStream</code>. */ - public final Object readObject() throws ClassNotFoundException, IOException + public final Object readObject() + throws ClassNotFoundException, IOException { if (this.useSubclassMethod) return readObjectOverride(); - boolean was_deserializing; - Object ret_val; - was_deserializing = this.isDeserializing; - - boolean is_consumed = false; boolean old_mode = setBlockDataMode(false); - - this.isDeserializing = true; - byte marker = this.realInputStream.readByte(); - depth += 2; + if (DEBUG) + depth += 2; if(dump) 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) - { if(dump) dumpElementln("BLOCKDATALONG"); } - else - { if(dump) dumpElementln("BLOCKDATA"); } - readNextBlock(marker); - throw new StreamCorruptedException("Unexpected blockData"); - } - - case TC_NULL: - { - if(dump) dumpElementln("NULL"); - ret_val = null; - break; - } - - case TC_REFERENCE: - { - if(dump) dumpElement("REFERENCE "); - Integer oid = new Integer(this.realInputStream.readInt()); - if(dump) dumpElementln(Integer.toHexString(oid.intValue())); - ret_val = ((ObjectIdentityWrapper) - this.objectLookupTable.get(oid)).object; - break; - } - - case TC_CLASS: - { - if(dump) dumpElementln("CLASS"); - ObjectStreamClass osc = (ObjectStreamClass)readObject(); - Class clazz = osc.forClass(); - assignNewHandle(clazz); - ret_val = clazz; - break; - } + ret_val = parseContent(marker); + } + finally + { + setBlockDataMode(old_mode); + if (DEBUG) + depth -= 2; + } + + return ret_val; + } - case TC_PROXYCLASSDESC: + /** + * Handles a content block within the stream, which begins with a marker + * byte indicating its type. + * + * @param marker the byte marker. + * @return an object which represents the parsed content. + * @throws ClassNotFoundException if the class of an object being + * read in cannot be found. + * @throws IOException if invalid data occurs or one is thrown by the + * underlying <code>InputStream</code>. + */ + private Object parseContent(byte marker) + throws ClassNotFoundException, IOException + { + Object ret_val; + boolean is_consumed = false; + + switch (marker) + { + case TC_ENDBLOCKDATA: + { + ret_val = null; + is_consumed = true; + break; + } + + case TC_BLOCKDATA: + case TC_BLOCKDATALONG: + { + if (marker == TC_BLOCKDATALONG) + { if(dump) dumpElementln("BLOCKDATALONG"); } + else + { if(dump) dumpElementln("BLOCKDATA"); } + readNextBlock(marker); + } + + case TC_NULL: + { + if(dump) dumpElementln("NULL"); + ret_val = null; + break; + } + + case TC_REFERENCE: + { + if(dump) dumpElement("REFERENCE "); + Integer oid = new Integer(this.realInputStream.readInt()); + if(dump) dumpElementln(Integer.toHexString(oid.intValue())); + ret_val = ((ObjectIdentityWrapper) + this.objectLookupTable.get(oid)).object; + break; + } + + case TC_CLASS: + { + if(dump) dumpElementln("CLASS"); + ObjectStreamClass osc = (ObjectStreamClass)readObject(); + Class clazz = osc.forClass(); + assignNewHandle(clazz); + ret_val = clazz; + break; + } + + case TC_PROXYCLASSDESC: + { + if(dump) 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(); + } + + boolean oldmode = setBlockDataMode(true); + Class cl = resolveProxyClass(intfs); + setBlockDataMode(oldmode); + + ObjectStreamClass osc = lookupClass(cl); + if (osc.firstNonSerializableParentConstructor == null) + { + osc.realClassIsSerializable = true; + osc.fields = osc.fieldMapping = new ObjectStreamField[0]; + try + { + osc.firstNonSerializableParentConstructor = + Object.class.getConstructor(new Class[0]); + } + catch (NoSuchMethodException x) + { + throw (InternalError) + new InternalError("Object ctor missing").initCause(x); + } + } + 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: + { + ObjectStreamClass osc = readClassDescriptor(); + + 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; + break; + } + + case TC_STRING: + case TC_LONGSTRING: + { + if(dump) dumpElement("STRING="); + String s = this.realInputStream.readUTF(); + if(dump) dumpElementln(s); + ret_val = processResolution(null, s, assignNewHandle(s)); + break; + } + + case TC_ARRAY: + { + if(dump) dumpElementln("ARRAY"); + ObjectStreamClass osc = (ObjectStreamClass)readObject(); + Class componentType = osc.forClass().getComponentType(); + if(dump) dumpElement("ARRAY LENGTH="); + int length = this.realInputStream.readInt(); + if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType); + Object array = Array.newInstance(componentType, length); + int handle = assignNewHandle(array); + readArrayElements(array, componentType); + if(dump) + for (int i = 0, len = Array.getLength(array); i < len; i++) + dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i)); + ret_val = processResolution(null, array, handle); + break; + } + + case TC_OBJECT: + { + if(dump) dumpElementln("OBJECT"); + ObjectStreamClass osc = (ObjectStreamClass)readObject(); + Class clazz = osc.forClass(); + + if (!osc.realClassIsSerializable) + throw new NotSerializableException + (clazz + " is not Serializable, and thus cannot be deserialized."); + + if (osc.realClassIsExternalizable) { - if(dump) 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]); - } + Externalizable obj = osc.newInstance(); - boolean oldmode = setBlockDataMode(true); - Class cl = resolveProxyClass(intfs); - setBlockDataMode(oldmode); + int handle = assignNewHandle(obj); - ObjectStreamClass osc = lookupClass(cl); - assignNewHandle(osc); + boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0); - 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: - { - ObjectStreamClass osc = readClassDescriptor(); + boolean oldmode = this.readDataFromBlock; + if (read_from_blocks) + setBlockDataMode(true); - if (!is_consumed) - { - byte b = this.realInputStream.readByte(); - if (b != TC_ENDBLOCKDATA) - throw new IOException("Data annotated to class was not consumed." + b); + obj.readExternal(this); + + if (read_from_blocks) + { + setBlockDataMode(oldmode); + if (!oldmode) + if (this.realInputStream.readByte() != TC_ENDBLOCKDATA) + throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method."); } - else - is_consumed = false; - - osc.setSuperclass ((ObjectStreamClass)readObject()); - ret_val = osc; - break; - } - - case TC_STRING: - case TC_LONGSTRING: - { - if(dump) dumpElement("STRING="); - String s = this.realInputStream.readUTF(); - if(dump) dumpElementln(s); - ret_val = processResolution(null, s, assignNewHandle(s)); - break; - } - - case TC_ARRAY: - { - if(dump) dumpElementln("ARRAY"); - ObjectStreamClass osc = (ObjectStreamClass)readObject(); - Class componentType = osc.forClass().getComponentType(); - if(dump) dumpElement("ARRAY LENGTH="); - int length = this.realInputStream.readInt(); - if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType); - Object array = Array.newInstance(componentType, length); - int handle = assignNewHandle(array); - readArrayElements(array, componentType); - if(dump) - for (int i = 0, len = Array.getLength(array); i < len; i++) - dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i)); - ret_val = processResolution(null, array, handle); - break; - } - - case TC_OBJECT: - { - if(dump) dumpElementln("OBJECT"); - ObjectStreamClass osc = (ObjectStreamClass)readObject(); - Class clazz = osc.forClass(); - - if (!osc.realClassIsSerializable) - throw new NotSerializableException - (clazz + " is not Serializable, and thus cannot be deserialized."); - - if (osc.realClassIsExternalizable) - { - Externalizable obj = osc.newInstance(); - - int handle = assignNewHandle(obj); - - 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(oldmode); - if (!oldmode) - if (this.realInputStream.readByte() != TC_ENDBLOCKDATA) - throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method."); - } - - ret_val = processResolution(osc, obj, handle); - break; - } // end if (osc.realClassIsExternalizable) - Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor); - - int handle = assignNewHandle(obj); - Object prevObject = this.currentObject; - ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass; - - this.currentObject = obj; - ObjectStreamClass[] hierarchy = - inputGetObjectStreamClasses(clazz); + ret_val = processResolution(osc, obj, handle); + break; - for (int i = 0; i < hierarchy.length; i++) - { - this.currentObjectStreamClass = hierarchy[i]; - - if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ()); - - // XXX: should initialize fields in classes in the hierarchy - // that aren't in the stream - // should skip over classes in the stream that aren't in the - // real classes hierarchy - - Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod; - if (readObjectMethod != null) - { - fieldsAlreadyRead = false; - boolean oldmode = setBlockDataMode(true); - callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj); - setBlockDataMode(oldmode); - } - else - { - readFields(obj, currentObjectStreamClass); - } - - if (this.currentObjectStreamClass.hasWriteMethod()) - { - if(dump) dumpElement("ENDBLOCKDATA? "); - try - { - // FIXME: XXX: This try block is to - // catch EOF which is thrown for some - // objects. That indicates a bug in - // the logic. - - if (this.realInputStream.readByte() != TC_ENDBLOCKDATA) - throw new IOException - ("No end of block data seen for class with readObject (ObjectInputStream) method."); - if(dump) dumpElementln("yes"); - } -// catch (EOFException e) -// { -// if(dump) dumpElementln("no, got EOFException"); -// } - catch (IOException e) - { - if(dump) dumpElementln("no, got IOException"); + } // end if (osc.realClassIsExternalizable) + + Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor); + + int handle = assignNewHandle(obj); + Object prevObject = this.currentObject; + ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass; + TreeSet prevObjectValidators = this.currentObjectValidators; + + this.currentObject = obj; + this.currentObjectValidators = null; + ObjectStreamClass[] hierarchy = + inputGetObjectStreamClasses(clazz); + + for (int i = 0; i < hierarchy.length; i++) + { + this.currentObjectStreamClass = hierarchy[i]; + if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ()); + + // XXX: should initialize fields in classes in the hierarchy + // that aren't in the stream + // should skip over classes in the stream that aren't in the + // real classes hierarchy + + Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod; + if (readObjectMethod != null) + { + fieldsAlreadyRead = false; + boolean oldmode = setBlockDataMode(true); + callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj); + setBlockDataMode(oldmode); + } + else + { + readFields(obj, currentObjectStreamClass); + } + + if (this.currentObjectStreamClass.hasWriteMethod()) + { + if(dump) dumpElement("ENDBLOCKDATA? "); + try + { + /* Read blocks until an end marker */ + byte writeMarker = this.realInputStream.readByte(); + while (writeMarker != TC_ENDBLOCKDATA) + { + parseContent(writeMarker); + writeMarker = this.realInputStream.readByte(); } + if(dump) dumpElementln("yes"); + } + catch (EOFException e) + { + throw (IOException) new IOException + ("No end of block data seen for class with readObject (ObjectInputStream) method.").initCause(e); } } - - this.currentObject = prevObject; - this.currentObjectStreamClass = prevObjectStreamClass; - ret_val = processResolution(osc, obj, handle); - - break; - } - - case TC_RESET: - if(dump) dumpElementln("RESET"); - clearHandles(); - ret_val = readObject(); - break; - - case TC_EXCEPTION: - { - if(dump) dumpElement("EXCEPTION="); - Exception e = (Exception)readObject(); - if(dump) dumpElementln(e.toString()); - clearHandles(); - throw new WriteAbortedException("Exception thrown during writing of stream", e); } - - default: - throw new IOException("Unknown marker on stream: " + marker); - } - } - finally - { - setBlockDataMode(old_mode); + + this.currentObject = prevObject; + this.currentObjectStreamClass = prevObjectStreamClass; + ret_val = processResolution(osc, obj, handle); + if (currentObjectValidators != null) + invokeValidators(); + this.currentObjectValidators = prevObjectValidators; + + break; + } - this.isDeserializing = was_deserializing; + case TC_RESET: + if(dump) dumpElementln("RESET"); + clearHandles(); + ret_val = readObject(); + break; - depth -= 2; + case TC_EXCEPTION: + { + if(dump) dumpElement("EXCEPTION="); + Exception e = (Exception)readObject(); + if(dump) dumpElementln(e.toString()); + clearHandles(); + throw new WriteAbortedException("Exception thrown during writing of stream", e); + } - if (! was_deserializing) - { - if (validators.size() > 0) - invokeValidators(); - } + default: + throw new IOException("Unknown marker on stream: " + marker); } - return ret_val; } @@ -716,8 +739,10 @@ public class ObjectInputStream extends InputStream throw new InvalidObjectException("attempt to add a null " + "ObjectInputValidation object"); - this.validators.addElement(new ValidatorAndPriority (validator, - priority)); + if (currentObjectValidators == null) + currentObjectValidators = new TreeSet(); + + currentObjectValidators.add(new ValidatorAndPriority(validator, priority)); } @@ -805,7 +830,7 @@ public class ObjectInputStream extends InputStream /** * Reconstruct class hierarchy the same way - * {@link java.io.ObjectStreamClass.getObjectStreamClasses(java.lang.Class)} does + * {@link java.io.ObjectStreamClass#getObjectStreamClasses(Class)} does * but using lookupClass instead of ObjectStreamClass.lookup. This * dup is necessary localize the lookup table. Hopefully some future * rewritings will be able to prevent this. @@ -874,7 +899,7 @@ public class ObjectInputStream extends InputStream } else for (int i = 0; i < intfs.length; i++) - clss[i] = cl.loadClass(intfs[i]); + clss[i] = Class.forName(intfs[i], false, cl); try { return Proxy.getProxyClass(cl, clss); @@ -1195,7 +1220,7 @@ public class ObjectInputStream extends InputStream * This method should be called by a method called 'readObject' in the * deserializing class (if present). It cannot (and should not)be called * outside of it. Its goal is to read all fields in the real input stream - * and keep them accessible through the {@link #GetField} class. Calling + * and keep them accessible through the {@link GetField} class. Calling * this method will not alter the deserializing object. * * @return A valid freshly created 'GetField' instance to get access to @@ -1543,8 +1568,15 @@ public class ObjectInputStream extends InputStream catch (IllegalAccessException ignore) { } - catch (InvocationTargetException ignore) + catch (InvocationTargetException exception) { + Throwable cause = exception.getCause(); + if (cause instanceof ObjectStreamException) + throw (ObjectStreamException) cause; + else if (cause instanceof RuntimeException) + throw (RuntimeException) cause; + else if (cause instanceof Error) + throw (Error) cause; } } @@ -1821,18 +1853,19 @@ public class ObjectInputStream extends InputStream // on OBJ private void invokeValidators() throws InvalidObjectException { - Object[] validators = new Object[this.validators.size()]; - this.validators.copyInto (validators); - Arrays.sort (validators); - try { - for (int i=0; i < validators.length; i++) - ((ObjectInputValidation)validators[i]).validateObject(); + Iterator it = currentObjectValidators.iterator(); + while(it.hasNext()) + { + ValidatorAndPriority vap = (ValidatorAndPriority) it.next(); + ObjectInputValidation validator = vap.validator; + validator.validateObject(); + } } finally { - this.validators.removeAllElements(); + currentObjectValidators = null; } } @@ -1881,10 +1914,9 @@ public class ObjectInputStream extends InputStream private Hashtable objectLookupTable; private Object currentObject; private ObjectStreamClass currentObjectStreamClass; + private TreeSet currentObjectValidators; private boolean readDataFromBlock; - private boolean isDeserializing; private boolean fieldsAlreadyRead; - private Vector validators; private Hashtable classLookupTable; private GetField prereadFields; @@ -1908,14 +1940,6 @@ public class ObjectInputStream extends InputStream System.out.print (Thread.currentThread() + ": "); } - static - { - if (Configuration.INIT_LOAD_LIBRARY) - { - System.loadLibrary ("javaio"); - } - } - // used to keep a prioritized list of object validators private static final class ValidatorAndPriority implements Comparable { diff --git a/libjava/classpath/java/io/ObjectOutputStream.java b/libjava/classpath/java/io/ObjectOutputStream.java index 5e754c5ec7a..573b9cfa1de 100644 --- a/libjava/classpath/java/io/ObjectOutputStream.java +++ b/libjava/classpath/java/io/ObjectOutputStream.java @@ -39,7 +39,6 @@ exception statement from your version. */ package java.io; -import gnu.classpath.Configuration; import gnu.java.io.ObjectIdentityWrapper; import gnu.java.lang.reflect.TypeSignature; import gnu.java.security.action.SetAccessibleAction; @@ -362,7 +361,9 @@ public class ObjectOutputStream extends OutputStream break; } - throw new NotSerializableException(clazz.getName ()); + throw new NotSerializableException(clazz.getName() + + " in " + + obj.getClass()); } // end pseudo-loop } catch (ObjectStreamException ose) @@ -412,37 +413,53 @@ public class ObjectOutputStream extends OutputStream protected void writeClassDescriptor(ObjectStreamClass osc) throws IOException { - realOutput.writeByte(TC_CLASSDESC); - realOutput.writeUTF(osc.getName()); - realOutput.writeLong(osc.getSerialVersionUID()); - assignNewHandle(osc); + if (osc.isProxyClass) + { + realOutput.writeByte(TC_PROXYCLASSDESC); + Class[] intfs = osc.forClass().getInterfaces(); + realOutput.writeInt(intfs.length); + for (int i = 0; i < intfs.length; i++) + realOutput.writeUTF(intfs[i].getName()); + + boolean oldmode = setBlockDataMode(true); + annotateProxyClass(osc.forClass()); + setBlockDataMode(oldmode); + realOutput.writeByte(TC_ENDBLOCKDATA); + } + else + { + realOutput.writeByte(TC_CLASSDESC); + realOutput.writeUTF(osc.getName()); + realOutput.writeLong(osc.getSerialVersionUID()); + assignNewHandle(osc); - int flags = osc.getFlags(); + int flags = osc.getFlags(); - if (protocolVersion == PROTOCOL_VERSION_2 - && osc.isExternalizable()) - flags |= SC_BLOCK_DATA; + if (protocolVersion == PROTOCOL_VERSION_2 + && osc.isExternalizable()) + flags |= SC_BLOCK_DATA; - realOutput.writeByte(flags); + realOutput.writeByte(flags); - ObjectStreamField[] fields = osc.fields; - realOutput.writeShort(fields.length); + ObjectStreamField[] fields = osc.fields; + realOutput.writeShort(fields.length); - ObjectStreamField field; - for (int i = 0; i < fields.length; i++) - { - field = fields[i]; - realOutput.writeByte(field.getTypeCode ()); - realOutput.writeUTF(field.getName ()); + ObjectStreamField field; + for (int i = 0; i < fields.length; i++) + { + field = fields[i]; + realOutput.writeByte(field.getTypeCode ()); + realOutput.writeUTF(field.getName ()); - if (! field.isPrimitive()) - writeObject(field.getTypeString()); - } + if (! field.isPrimitive()) + writeObject(field.getTypeString()); + } - boolean oldmode = setBlockDataMode(true); - annotateClass(osc.forClass()); - setBlockDataMode(oldmode); - realOutput.writeByte(TC_ENDBLOCKDATA); + boolean oldmode = setBlockDataMode(true); + annotateClass(osc.forClass()); + setBlockDataMode(oldmode); + realOutput.writeByte(TC_ENDBLOCKDATA); + } if (osc.isSerializable() || osc.isExternalizable()) writeObject(osc.getSuper()); @@ -531,7 +548,7 @@ public class ObjectOutputStream extends OutputStream * version)</code> is provided to change the default protocol * version. * - * For an explination of the differences beween the two protocols + * For an explanation of the differences between the two protocols * see XXX: the Java ObjectSerialization Specification. * * @exception IOException if <code>version</code> is not a valid @@ -1567,12 +1584,4 @@ public class ObjectOutputStream extends OutputStream private boolean dump = false; private static final boolean DEBUG = false; - - static - { - if (Configuration.INIT_LOAD_LIBRARY) - { - System.loadLibrary("javaio"); - } - } } diff --git a/libjava/classpath/java/io/ObjectStreamField.java b/libjava/classpath/java/io/ObjectStreamField.java index 611457b3cfb..61ccdc7db76 100644 --- a/libjava/classpath/java/io/ObjectStreamField.java +++ b/libjava/classpath/java/io/ObjectStreamField.java @@ -208,7 +208,7 @@ public class ObjectStreamField implements Comparable * This method sets the current offset of the field. * * @param off The offset of the field in bytes. - * @see getOffset() + * @see #getOffset() */ protected void setOffset (int off) { diff --git a/libjava/classpath/java/io/OutputStreamWriter.java b/libjava/classpath/java/io/OutputStreamWriter.java index ee229796cce..29fb631faf4 100644 --- a/libjava/classpath/java/io/OutputStreamWriter.java +++ b/libjava/classpath/java/io/OutputStreamWriter.java @@ -39,16 +39,14 @@ exception statement from your version. */ package java.io; import gnu.java.nio.charset.EncodingHelper; + import java.nio.ByteBuffer; import java.nio.CharBuffer; -import java.nio.charset.MalformedInputException; -import java.nio.charset.UnsupportedCharsetException; import java.nio.charset.CharacterCodingException; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.CoderResult; -import java.nio.charset.CodingErrorAction; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.MalformedInputException; /** * This class writes characters to an output stream that is byte oriented @@ -124,52 +122,58 @@ public class OutputStreamWriter extends Writer { this.out = out; try - { - // Don't use NIO if avoidable - if(EncodingHelper.isISOLatin1(encoding_scheme)) { - encodingName = "ISO8859_1"; - encoder = null; - return; - } - - /* - * Workraround for encodings with a byte-order-mark. - * We only want to write it once per stream. - */ - try { - if(encoding_scheme.equalsIgnoreCase("UnicodeBig") || - encoding_scheme.equalsIgnoreCase("UTF-16") || - encoding_scheme.equalsIgnoreCase("UTF16")) - { - encoding_scheme = "UTF-16BE"; - out.write((byte)0xFE); - out.write((byte)0xFF); - } else if(encoding_scheme.equalsIgnoreCase("UnicodeLittle")){ - encoding_scheme = "UTF-16LE"; - out.write((byte)0xFF); - out.write((byte)0xFE); - } - } catch(IOException ioe){ - } + // Don't use NIO if avoidable + if(EncodingHelper.isISOLatin1(encoding_scheme)) + { + encodingName = "ISO8859_1"; + encoder = null; + return; + } - outputBuffer = CharBuffer.allocate(BUFFER_SIZE); + /* + * Workraround for encodings with a byte-order-mark. + * We only want to write it once per stream. + */ + try + { + if(encoding_scheme.equalsIgnoreCase("UnicodeBig") || + encoding_scheme.equalsIgnoreCase("UTF-16") || + encoding_scheme.equalsIgnoreCase("UTF16")) + { + encoding_scheme = "UTF-16BE"; + out.write((byte)0xFE); + out.write((byte)0xFF); + } + else if(encoding_scheme.equalsIgnoreCase("UnicodeLittle")){ + encoding_scheme = "UTF-16LE"; + out.write((byte)0xFF); + out.write((byte)0xFE); + } + } + catch(IOException ioe) + { + } + + outputBuffer = CharBuffer.allocate(BUFFER_SIZE); - Charset cs = EncodingHelper.getCharset(encoding_scheme); - if(cs == null) - throw new UnsupportedEncodingException("Encoding "+encoding_scheme+ - " unknown"); - encoder = cs.newEncoder(); - encodingName = EncodingHelper.getOldCanonical(cs.name()); + Charset cs = EncodingHelper.getCharset(encoding_scheme); + if(cs == null) + throw new UnsupportedEncodingException("Encoding "+encoding_scheme+ + " unknown"); + encoder = cs.newEncoder(); + encodingName = EncodingHelper.getOldCanonical(cs.name()); - encoder.onMalformedInput(CodingErrorAction.REPLACE); - encoder.onUnmappableCharacter(CodingErrorAction.REPLACE); - } catch(RuntimeException e) { - // Default to ISO Latin-1, will happen if this is called, for instance, - // before the NIO provider is loadable. - encoder = null; - encodingName = "ISO8859_1"; - } + encoder.onMalformedInput(CodingErrorAction.REPLACE); + encoder.onUnmappableCharacter(CodingErrorAction.REPLACE); + } + catch(RuntimeException e) + { + // Default to ISO Latin-1, will happen if this is called, for instance, + // before the NIO provider is loadable. + encoder = null; + encodingName = "ISO8859_1"; + } } /** @@ -183,21 +187,55 @@ public class OutputStreamWriter extends Writer this.out = out; outputBuffer = null; try - { - String encoding = System.getProperty("file.encoding"); - Charset cs = Charset.forName(encoding); - encoder = cs.newEncoder(); - encodingName = EncodingHelper.getOldCanonical(cs.name()); - } catch(RuntimeException e) { - encoder = null; - encodingName = "ISO8859_1"; - } + { + String encoding = System.getProperty("file.encoding"); + Charset cs = Charset.forName(encoding); + encoder = cs.newEncoder(); + encodingName = EncodingHelper.getOldCanonical(cs.name()); + } + catch(RuntimeException e) + { + encoder = null; + encodingName = "ISO8859_1"; + } + if(encoder != null) - { - encoder.onMalformedInput(CodingErrorAction.REPLACE); - encoder.onUnmappableCharacter(CodingErrorAction.REPLACE); - outputBuffer = CharBuffer.allocate(BUFFER_SIZE); - } + { + encoder.onMalformedInput(CodingErrorAction.REPLACE); + encoder.onUnmappableCharacter(CodingErrorAction.REPLACE); + outputBuffer = CharBuffer.allocate(BUFFER_SIZE); + } + } + + /** + * This method initializes a new instance of <code>OutputStreamWriter</code> + * to write to the specified stream using a given <code>Charset</code>. + * + * @param out The <code>OutputStream</code> to write to + * @param cs The <code>Charset</code> of the encoding to use + */ + public OutputStreamWriter(OutputStream out, Charset cs) + { + this.out = out; + encoder = cs.newEncoder(); + encoder.onMalformedInput(CodingErrorAction.REPLACE); + encoder.onUnmappableCharacter(CodingErrorAction.REPLACE); + outputBuffer = CharBuffer.allocate(BUFFER_SIZE); + } + + /** + * This method initializes a new instance of <code>OutputStreamWriter</code> + * to write to the specified stream using a given + * <code>CharsetEncoder</code>. + * + * @param out The <code>OutputStream</code> to write to + * @param enc The <code>CharsetEncoder</code> to encode the output with + */ + public OutputStreamWriter(OutputStream out, CharsetEncoder enc) + { + this.out = out; + encoder = enc; + outputBuffer = CharBuffer.allocate(BUFFER_SIZE); } /** diff --git a/libjava/classpath/java/io/PipedInputStream.java b/libjava/classpath/java/io/PipedInputStream.java index beb310b4f0c..523ae2c70d3 100644 --- a/libjava/classpath/java/io/PipedInputStream.java +++ b/libjava/classpath/java/io/PipedInputStream.java @@ -130,7 +130,7 @@ public class PipedInputStream extends InputStream * This stream is then ready for reading. If this stream is already * connected or has been previously closed, then an exception is thrown * - * @param src The <code>PipedOutputStream</code> to connect this stream to + * @param source The <code>PipedOutputStream</code> to connect this stream to * * @exception IOException If this PipedInputStream or <code>source</code> * has been connected already. diff --git a/libjava/classpath/java/io/PrintWriter.java b/libjava/classpath/java/io/PrintWriter.java index 5fd0b162f31..5667e705004 100644 --- a/libjava/classpath/java/io/PrintWriter.java +++ b/libjava/classpath/java/io/PrintWriter.java @@ -70,6 +70,11 @@ public class PrintWriter extends Writer * on this stream. */ private boolean error; + + /** + * Indicates whether or not the stream has been closed. + */ + private boolean closed; /** * This is the underlying <code>Writer</code> we are sending output @@ -139,6 +144,68 @@ public class PrintWriter extends Writer } /** + * This initializes a new PrintWriter object to write to the specified + * file. It creates a FileOutputStream object and wraps it in an + * OutputStreamWriter using the default encoding. + * @param file name of the file to write to + * @throws FileNotFoundException if the file cannot be written or created + * + * @since 1.5 + */ + public PrintWriter(String file) throws FileNotFoundException + { + this(new FileOutputStream(file)); + } + + /** + * This initializes a new PrintWriter object to write to the specified + * file. It creates a FileOutputStream object and wraps it in an + * OutputStreamWriter using the specified encoding. + * @param file name of the file to write to + * @param enc the encoding to use + * @throws FileNotFoundException if the file cannot be written or created + * @throws UnsupportedEncodingException if the encoding is not supported + * + * @since 1.5 + */ + public PrintWriter(String file, String enc) + throws FileNotFoundException, UnsupportedEncodingException + { + this(new OutputStreamWriter(new FileOutputStream(file), enc)); + } + + /** + * This initializes a new PrintWriter object to write to the specified + * file. It creates a FileOutputStream object and wraps it in an + * OutputStreamWriter using the default encoding. + * @param file the file to write to + * @throws FileNotFoundException if the file cannot be written or created + * + * @since 1.5 + */ + public PrintWriter(File file) throws FileNotFoundException + { + this(new FileOutputStream(file)); + } + + /** + * This initializes a new PrintWriter object to write to the specified + * file. It creates a FileOutputStream object and wraps it in an + * OutputStreamWriter using the specified encoding. + * @param file the file to write to + * @param enc the encoding to use + * @throws FileNotFoundException if the file cannot be written or created + * @throws UnsupportedEncodingException if the encoding is not supported + * + * @since 1.5 + */ + public PrintWriter(File file, String enc) + throws FileNotFoundException, UnsupportedEncodingException + { + this(new OutputStreamWriter(new FileOutputStream(file), enc)); + } + + /** * This method can be called by subclasses to indicate that an error * has occurred and should be reported by <code>checkError</code>. */ @@ -158,7 +225,8 @@ public class PrintWriter extends Writer */ public boolean checkError() { - flush(); + if (! closed) + flush(); return error; } @@ -185,7 +253,8 @@ public class PrintWriter extends Writer { try { - out.close(); + out.close(); + closed = true; } catch (IOException ex) { @@ -310,7 +379,7 @@ public class PrintWriter extends Writer * This is the system dependent line separator */ private static final char[] line_separator - = System.getProperty("line.separator").toCharArray(); + = System.getProperty("line.separator", "\n").toCharArray(); /** * This method prints a line separator sequence to the stream. The value diff --git a/libjava/classpath/java/io/PushbackInputStream.java b/libjava/classpath/java/io/PushbackInputStream.java index 71cf244274e..ff202c72df1 100644 --- a/libjava/classpath/java/io/PushbackInputStream.java +++ b/libjava/classpath/java/io/PushbackInputStream.java @@ -116,7 +116,14 @@ public class PushbackInputStream extends FilterInputStream */ public int available() throws IOException { - return (buf.length - pos) + super.available(); + try + { + return (buf.length - pos) + super.available(); + } + catch (NullPointerException npe) + { + throw new IOException ("Stream closed"); + } } /** |