Merged gcj-eclipse branch to trunk.

From-SVN: r120621
This commit is contained in:
Tom Tromey
2007-01-09 19:58:05 +00:00
parent c648dedbde
commit 97b8365caf
17478 changed files with 606493 additions and 100744 deletions
@@ -267,7 +267,7 @@ public class CharArrayWriter extends Writer
* sequence is wrapped around an input buffer, the results will
* depend on the current position and length of that buffer.
*
* @param cs the character sequence to append. If cs is null,
* @param seq the character sequence to append. If seq is null,
* then the string "null" (the string representation of null)
* is appended.
* @return a reference to this object.
@@ -291,10 +291,10 @@ public class CharArrayWriter extends Writer
* output stream underlying this writer, starting and ending at the
* specified positions within the sequence. The behaviour of this
* method matches the behaviour of writing the result of
* <code>append(cs.subSequence(start,end))</code> when the sequence
* <code>append(seq.subSequence(start,end))</code> when the sequence
* is not null.
*
* @param cs the character sequence to append. If cs is null,
* @param seq the character sequence to append. If seq is null,
* then the string "null" (the string representation of null)
* is appended.
* @param start the index of the first Unicode character to use from
@@ -1,5 +1,5 @@
/* DeleteFileHelper.java -- Helper class to delete files on VM exit
Copyright (C) 2004 Free Software Foundation, Inc.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,22 +40,22 @@ package java.io;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author Guilhem Lavaux (guilhem@kaffe.org)
* @author Jeroen Frijters (jeroen@sumatra.nl)
* @author Michael Koch (konqueror@gmx.de)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
*/
final class DeleteFileHelper extends Thread
{
private static ArrayList filesToDelete;
private static ArrayList<File> filesToDelete;
static synchronized void add(File file)
{
if (filesToDelete == null)
{
filesToDelete = new ArrayList();
filesToDelete = new ArrayList<File>();
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -81,13 +81,10 @@ final class DeleteFileHelper extends Thread
private static synchronized void deleteFiles()
{
Iterator it = filesToDelete.iterator();
while (it.hasNext())
for (File file : filesToDelete)
{
try
{
File file = (File) it.next();
file.delete();
}
catch (Exception e)
+21 -86
View File
@@ -60,7 +60,7 @@ import java.net.URL;
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class File implements Serializable, Comparable
public class File implements Serializable, Comparable<File>
{
private static final long serialVersionUID = 301077366599181567L;
@@ -286,7 +286,8 @@ public class File implements Serializable, Comparable
// example, is a valid and minimal path).
if (plen > 1 && p.charAt (plen - 1) == separatorChar)
{
if (! (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':'))
if (! (separatorChar == '\\' && ((plen == 3 && p.charAt(1) == ':')
|| (plen == 2 && p.charAt(0) == separatorChar))))
return p.substring (0, plen - 1);
}
else
@@ -303,7 +304,16 @@ public class File implements Serializable, Comparable
{
dupIndex++;
if (dupIndex == plen)
return newpath.toString();
{
if ((separatorChar == '\\'
&& newpath.length() == 2
&& newpath.charAt(1) == ':')
|| (separatorChar != '\\' && newpath.length() == 0))
{
newpath.append(separatorChar);
}
return newpath.toString();
}
}
newpath.append(separatorChar);
last = dupIndex;
@@ -315,7 +325,9 @@ public class File implements Serializable, Comparable
int end;
if (plen > 1 && p.charAt (plen - 1) == separatorChar)
{
if (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':')
if (separatorChar == '\\'
&& ((plen == 3 && p.charAt(1) == ':')
|| (plen == 2 && p.charAt(0) == separatorChar)))
end = plen;
else
end = plen - 1;
@@ -427,45 +439,8 @@ public class File implements Serializable, Comparable
{
if (isAbsolute())
return path;
else if (separatorChar == '\\'
&& path.length() > 0 && path.charAt (0) == '\\')
{
// On Windows, even if the path starts with a '\\' it is not
// really absolute until we prefix the drive specifier from
// the current working directory to it.
return System.getProperty ("user.dir").substring (0, 2) + path;
}
else if (separatorChar == '\\'
&& path.length() > 1 && path.charAt (1) == ':'
&& ((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
|| (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')))
{
// On Windows, a process has a current working directory for
// each drive and a path like "G:foo\bar" would mean the
// absolute path "G:\wombat\foo\bar" if "\wombat" is the
// working directory on the G drive.
String drvDir = null;
try
{
drvDir = new File (path.substring (0, 2)).getCanonicalPath();
}
catch (IOException e)
{
drvDir = path.substring (0, 2) + "\\";
}
// Note: this would return "C:\\." for the path "C:.", if "\"
// is the working folder on the C drive, but this is
// consistent with what Sun's JRE 1.4.1.01 actually returns!
if (path.length() > 2)
return drvDir + '\\' + path.substring (2, path.length());
else
return drvDir;
}
else if (path.equals(""))
return System.getProperty ("user.dir");
else
return System.getProperty ("user.dir") + separatorChar + path;
return VMFile.getAbsolutePath(path);
}
/**
@@ -657,15 +632,7 @@ public class File implements Serializable, Comparable
*/
public boolean isAbsolute()
{
if (separatorChar == '\\')
return path.startsWith(dupSeparator) ||
(path.length() > 2 &&
((path.charAt(0) >= 'a' && path.charAt(0) <= 'z') ||
(path.charAt(0) >= 'A' && path.charAt(0) <= 'Z')) &&
path.charAt(1) == ':' &&
path.charAt(2) == '\\');
else
return path.startsWith(separator);
return VMFile.isAbsolute(path);
}
/**
@@ -787,8 +754,9 @@ public class File implements Serializable, Comparable
String files[] = VMFile.list(path);
// Check if an error occured in listInternal().
// This is an unreadable directory, pretend there is nothing inside.
if (files == null)
return null;
return new String[0];
if (filter == null)
return files;
@@ -998,14 +966,7 @@ public class File implements Serializable, Comparable
*/
public URL toURL() throws MalformedURLException
{
// On Win32, Sun's JDK returns URLs of the form "file:/c:/foo/bar.txt",
// while on UNIX, it returns URLs of the form "file:/foo/bar.txt".
if (separatorChar == '\\')
return new URL ("file:/" + getAbsolutePath().replace ('\\', '/')
+ (isDirectory() ? "/" : ""));
else
return new URL ("file:" + getAbsolutePath()
+ (isDirectory() ? "/" : ""));
return VMFile.toURL(this);
}
@@ -1291,32 +1252,6 @@ public class File implements Serializable, Comparable
return path.compareToIgnoreCase (other.path);
}
/**
* This method compares the specified <code>Object</code> to this one
* to test for equality. It does this by comparing the canonical path names
* of the files. This method is identical to <code>compareTo(File)</code>
* except that if the <code>Object</code> passed to it is not a
* <code>File</code>, it throws a <code>ClassCastException</code>
* <p>
* The canonical paths of the files are determined by calling the
* <code>getCanonicalPath</code> method on each object.
* <p>
* This method returns a 0 if the specified <code>Object</code> is equal
* to this one, a negative value if it is less than this one
* a positive value if it is greater than this one.
*
* @return An integer as described above
*
* @exception ClassCastException If the passed <code>Object</code> is
* not a <code>File</code>
*
* @since 1.2
*/
public int compareTo(Object obj)
{
return compareTo((File) obj);
}
/**
* This method renames the file represented by this object to the path
* of the file represented by the argument <code>File</code>.
@@ -39,7 +39,7 @@ exception statement from your version. */
package java.io;
import gnu.java.nio.channels.FileChannelImpl;
import gnu.java.nio.FileChannelImpl;
import java.nio.channels.ByteChannel;
import java.nio.channels.FileChannel;
@@ -133,7 +133,8 @@ public final class FileDescriptor
* native file handle, <code>false</code> otherwise
*/
public boolean valid ()
{
return channel != null && channel.isOpen();
{
ByteChannel c = channel;
return (c != null) && (c.isOpen());
}
}
+17 -3
View File
@@ -38,8 +38,9 @@ exception statement from your version. */
package java.io;
import gnu.java.nio.channels.FileChannelImpl;
import gnu.java.nio.FileChannelImpl;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
@@ -107,7 +108,20 @@ public class FileInputStream extends InputStream
if (s != null)
s.checkRead(file.getPath());
ch = FileChannelImpl.create(file, FileChannelImpl.READ);
try
{
ch = FileChannelImpl.create(file, FileChannelImpl.READ);
}
catch (FileNotFoundException fnfe)
{
throw fnfe;
}
catch (IOException ioe)
{
FileNotFoundException fnfe = new FileNotFoundException(file.getPath());
fnfe.initCause(ioe);
throw fnfe;
}
}
/**
@@ -266,7 +280,7 @@ public class FileInputStream extends InputStream
|| offset + len > buf.length)
throw new ArrayIndexOutOfBoundsException();
return ch.read(buf, offset, len);
return ch.read(ByteBuffer.wrap(buf, offset, len));
}
/**
@@ -38,8 +38,9 @@ exception statement from your version. */
package java.io;
import gnu.java.nio.channels.FileChannelImpl;
import gnu.java.nio.FileChannelImpl;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
@@ -155,10 +156,23 @@ public class FileOutputStream extends OutputStream
if (s != null)
s.checkWrite(file.getPath());
ch = FileChannelImpl.create(file, (append
? FileChannelImpl.WRITE
| FileChannelImpl.APPEND
: FileChannelImpl.WRITE));
try
{
ch = FileChannelImpl.create(file, (append
? FileChannelImpl.WRITE
| FileChannelImpl.APPEND
: FileChannelImpl.WRITE));
}
catch (FileNotFoundException fnfe)
{
throw fnfe;
}
catch (IOException ioe)
{
FileNotFoundException fnfe = new FileNotFoundException(file.getPath());
fnfe.initCause(ioe);
throw fnfe;
}
}
/**
@@ -266,7 +280,7 @@ public class FileOutputStream extends OutputStream
|| offset + len > buf.length)
throw new ArrayIndexOutOfBoundsException ();
ch.write (buf, offset, len);
ch.write(ByteBuffer.wrap(buf, offset, len));
}
/**
@@ -134,6 +134,16 @@ public class InputStreamReader extends Reader
private char savedSurrogate;
private boolean hasSavedSurrogate = false;
/**
* A byte array to be reused in read(byte[], int, int).
*/
private byte[] bytesCache;
/**
* Locks the bytesCache above in read(byte[], int, int).
*/
private Object cacheLock = new Object();
/**
* This method initializes a new instance of <code>InputStreamReader</code>
* to read from the specified stream using the default encoding.
@@ -355,9 +365,21 @@ public class InputStreamReader extends Reader
throw new IOException("Reader has been closed");
if (isDone)
return -1;
if(decoder != null){
int totalBytes = (int)((double)length * maxBytesPerChar);
byte[] bytes = new byte[totalBytes];
if(decoder != null)
{
int totalBytes = (int)((double) length * maxBytesPerChar);
if (byteBuffer != null)
totalBytes = Math.max(totalBytes, byteBuffer.remaining());
byte[] bytes;
// Fetch cached bytes array if available and big enough.
synchronized(cacheLock)
{
bytes = bytesCache;
if (bytes == null || bytes.length < totalBytes)
bytes = new byte[totalBytes];
else
bytesCache = null;
}
int remaining = 0;
if(byteBuffer != null)
@@ -410,12 +432,40 @@ public class InputStreamReader extends Reader
byteBuffer = null;
read = cb.position() - startPos;
return (read <= 0) ? -1 : read;
} else {
byte[] bytes = new byte[length];
// Put cached bytes array back if we are finished and the cache
// is null or smaller than the used bytes array.
synchronized (cacheLock)
{
if (byteBuffer == null
&& (bytesCache == null || bytesCache.length < bytes.length))
bytesCache = bytes;
}
return (read <= 0) ? -1 : read;
}
else
{
byte[] bytes;
// Fetch cached bytes array if available and big enough.
synchronized (cacheLock)
{
bytes = bytesCache;
if (bytes == null || length < bytes.length)
bytes = new byte[length];
else
bytesCache = null;
}
int read = in.read(bytes);
for(int i=0;i<read;i++)
buf[offset+i] = (char)(bytes[i]&0xFF);
// Put back byte array into cache if appropriate.
synchronized (cacheLock)
{
if (bytesCache == null || bytesCache.length < bytes.length)
bytesCache = bytes;
}
return read;
}
}
@@ -39,7 +39,7 @@ exception statement from your version. */
package java.io;
import gnu.java.io.ObjectIdentityWrapper;
import gnu.classpath.VMStackWalker;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
@@ -55,6 +55,13 @@ import java.util.Iterator;
import java.util.TreeSet;
import java.util.Vector;
/**
* @author Tom Tromey (tromey@redhat.com)
* @author Jeroen Frijters (jeroen@frijters.net)
* @author Guilhem Lavaux (guilhem@kaffe.org)
* @author Michael Koch (konqueror@gmx.de)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
*/
public class ObjectInputStream extends InputStream
implements ObjectInput, ObjectStreamConstants
{
@@ -97,8 +104,8 @@ public class ObjectInputStream extends InputStream
this.blockDataInput = new DataInputStream(this);
this.realInputStream = new DataInputStream(in);
this.nextOID = baseWireHandle;
this.objectLookupTable = new Hashtable();
this.classLookupTable = new Hashtable();
this.objectLookupTable = new Vector<Object>();
this.classLookupTable = new Hashtable<Class,ObjectStreamClass>();
setBlockDataMode(true);
readStreamHeader();
}
@@ -197,10 +204,9 @@ public class ObjectInputStream extends InputStream
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;
int oid = realInputStream.readInt();
if(dump) dumpElementln(Integer.toHexString(oid));
ret_val = lookupHandle(oid);
break;
}
@@ -348,12 +354,12 @@ public class ObjectInputStream extends InputStream
int handle = assignNewHandle(obj);
Object prevObject = this.currentObject;
ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
TreeSet prevObjectValidators = this.currentObjectValidators;
TreeSet<ValidatorAndPriority> prevObjectValidators =
this.currentObjectValidators;
this.currentObject = obj;
this.currentObjectValidators = null;
ObjectStreamClass[] hierarchy =
inputGetObjectStreamClasses(clazz);
ObjectStreamClass[] hierarchy = hierarchy(clazz);
for (int i = 0; i < hierarchy.length; i++)
{
@@ -539,8 +545,6 @@ public class ObjectInputStream extends InputStream
flags, fields);
assignNewHandle(osc);
ClassLoader callersClassLoader = currentLoader();
for (int i = 0; i < field_count; i++)
{
if(dump) dumpElement(" TYPE CODE=");
@@ -560,12 +564,17 @@ public class ObjectInputStream extends InputStream
class_name = String.valueOf(type_code);
fields[i] =
new ObjectStreamField(field_name, class_name, callersClassLoader);
new ObjectStreamField(field_name, class_name);
}
/* Now that fields have been read we may resolve the class
* (and read annotation if needed). */
Class clazz = resolveClass(osc);
ClassLoader loader = clazz.getClassLoader();
for (int i = 0; i < field_count; i++)
{
fields[i].resolveType(loader);
}
boolean oldmode = setBlockDataMode(true);
osc.setClass(clazz, lookupClass(clazz.getSuperclass()));
classLookupTable.put(clazz, osc);
@@ -753,7 +762,7 @@ public class ObjectInputStream extends InputStream
+ "ObjectInputValidation object");
if (currentObjectValidators == null)
currentObjectValidators = new TreeSet();
currentObjectValidators = new TreeSet<ValidatorAndPriority>();
currentObjectValidators.add(new ValidatorAndPriority(validator, priority));
}
@@ -775,7 +784,7 @@ public class ObjectInputStream extends InputStream
*
* @see java.io.ObjectOutputStream#annotateClass (java.lang.Class)
*/
protected Class resolveClass(ObjectStreamClass osc)
protected Class<?> resolveClass(ObjectStreamClass osc)
throws ClassNotFoundException, IOException
{
String name = osc.getName();
@@ -814,7 +823,7 @@ public class ObjectInputStream extends InputStream
*/
private ClassLoader currentLoader()
{
return VMObjectInputStream.currentClassLoader();
return VMStackWalker.firstNonNullClassLoader();
}
/**
@@ -842,41 +851,20 @@ public class ObjectInputStream extends InputStream
}
/**
* Reconstruct class hierarchy the same way
* {@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.
* Reconstruct class hierarchy the same way {@link
* java.io.ObjectStreamClass#hierarchy} does but using lookupClass
* instead of ObjectStreamClass.lookup.
*
* @param clazz This is the class for which we want the hierarchy.
*
* @return An array of valid {@link java.io.ObjectStreamClass} instances which
* represent the class hierarchy for clazz.
*/
private ObjectStreamClass[] inputGetObjectStreamClasses(Class clazz)
{
private ObjectStreamClass[] hierarchy(Class clazz)
{
ObjectStreamClass osc = lookupClass(clazz);
if (osc == null)
return new ObjectStreamClass[0];
else
{
Vector oscs = new Vector();
while (osc != null)
{
oscs.addElement(osc);
osc = osc.getSuper();
}
int count = oscs.size();
ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[count];
for (int i = count - 1; i >= 0; i--)
sorted_oscs[count - i - 1] = (ObjectStreamClass) oscs.elementAt(i);
return sorted_oscs;
}
return osc == null ? new ObjectStreamClass[0] : osc.hierarchy();
}
/**
@@ -898,12 +886,12 @@ public class ObjectInputStream extends InputStream
}
protected Class resolveProxyClass(String[] intfs)
protected Class<?> resolveProxyClass(String[] intfs)
throws IOException, ClassNotFoundException
{
ClassLoader cl = currentLoader();
Class[] clss = new Class[intfs.length];
Class<?>[] clss = new Class<?>[intfs.length];
if(cl == null)
{
for (int i = 0; i < intfs.length; i++)
@@ -1560,9 +1548,47 @@ public class ObjectInputStream extends InputStream
*/
private int assignNewHandle(Object obj)
{
this.objectLookupTable.put(new Integer(this.nextOID),
new ObjectIdentityWrapper(obj));
return this.nextOID++;
int handle = this.nextOID;
this.nextOID = handle + 1;
rememberHandle(obj,handle);
return handle;
}
/**
* Remember the object associated with the given handle.
*
* @param obj an object
*
* @param handle a handle, must be >= baseWireHandle
*
* @see #lookupHandle
*/
private void rememberHandle(Object obj, int handle)
{
Vector olt = this.objectLookupTable;
handle = handle - baseWireHandle;
if (olt.size() <= handle)
olt.setSize(handle + 1);
olt.set(handle, obj);
}
/**
* Look up the object associated with a given handle.
*
* @param handle a handle, must be >= baseWireHandle
*
* @return the object remembered for handle or null if none.
*
* @see #rememberHandle
*/
private Object lookupHandle(int handle)
{
Vector olt = this.objectLookupTable;
handle = handle - baseWireHandle;
Object result = handle < olt.size() ? olt.get(handle) : null;
return result;
}
private Object processResolution(ObjectStreamClass osc, Object obj, int handle)
@@ -1596,9 +1622,7 @@ public class ObjectInputStream extends InputStream
if (this.resolveEnabled)
obj = resolveObject(obj);
this.objectLookupTable.put(new Integer(handle),
new ObjectIdentityWrapper(obj));
rememberHandle(obj, handle);
return obj;
}
@@ -1875,10 +1899,10 @@ public class ObjectInputStream extends InputStream
{
try
{
Iterator it = currentObjectValidators.iterator();
Iterator<ValidatorAndPriority> it = currentObjectValidators.iterator();
while(it.hasNext())
{
ValidatorAndPriority vap = (ValidatorAndPriority) it.next();
ValidatorAndPriority vap = it.next();
ObjectInputValidation validator = vap.validator;
validator.validateObject();
}
@@ -1931,13 +1955,13 @@ public class ObjectInputStream extends InputStream
private boolean useSubclassMethod;
private int nextOID;
private boolean resolveEnabled;
private Hashtable objectLookupTable;
private Vector<Object> objectLookupTable;
private Object currentObject;
private ObjectStreamClass currentObjectStreamClass;
private TreeSet currentObjectValidators;
private TreeSet<ValidatorAndPriority> currentObjectValidators;
private boolean readDataFromBlock;
private boolean fieldsAlreadyRead;
private Hashtable classLookupTable;
private Hashtable<Class,ObjectStreamClass> classLookupTable;
private GetField prereadFields;
private static boolean dump;
+78 -287
View File
@@ -39,7 +39,7 @@ exception statement from your version. */
package java.io;
import gnu.java.io.ObjectIdentityWrapper;
import gnu.java.io.ObjectIdentityMap2Int;
import gnu.java.lang.reflect.TypeSignature;
import gnu.java.security.action.SetAccessibleAction;
@@ -47,8 +47,7 @@ import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.util.Hashtable;
/**
* An <code>ObjectOutputStream</code> can be used to write objects
@@ -115,6 +114,11 @@ import java.util.Hashtable;
* @see java.io.Externalizable
* @see java.io.ObjectInputStream
* @see java.io.Serializable
* @author Tom Tromey (tromey@redhat.com)
* @author Jeroen Frijters (jeroen@frijters.net)
* @author Guilhem Lavaux (guilhem@kaffe.org)
* @author Michael Koch (konqueror@gmx.de)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
*/
public class ObjectOutputStream extends OutputStream
implements ObjectOutput, ObjectStreamConstants
@@ -140,7 +144,7 @@ public class ObjectOutputStream extends OutputStream
replacementEnabled = false;
isSerializing = false;
nextOID = baseWireHandle;
OIDLookupTable = new Hashtable();
OIDLookupTable = new ObjectIdentityMap2Int();
protocolVersion = defaultProtocolVersion;
useSubclassMethod = false;
writeStreamHeader();
@@ -207,11 +211,11 @@ public class ObjectOutputStream extends OutputStream
break;
}
Integer handle = findHandle(obj);
if (handle != null)
int handle = findHandle(obj);
if (handle >= 0)
{
realOutput.writeByte(TC_REFERENCE);
realOutput.writeInt(handle.intValue());
realOutput.writeInt(handle);
break;
}
@@ -225,7 +229,7 @@ public class ObjectOutputStream extends OutputStream
writeObject (osc);
}
else
{
{System.err.println("1");
realOutput.writeByte(TC_PROXYCLASSDESC);
Class[] intfs = cl.getInterfaces();
realOutput.writeInt(intfs.length);
@@ -338,8 +342,7 @@ public class ObjectOutputStream extends OutputStream
Object prevObject = this.currentObject;
ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
currentObject = obj;
ObjectStreamClass[] hierarchy =
ObjectStreamClass.getObjectStreamClasses(clazz);
ObjectStreamClass[] hierarchy = osc.hierarchy();
for (int i = 0; i < hierarchy.length; i++)
{
@@ -604,11 +607,11 @@ public class ObjectOutputStream extends OutputStream
*
* @see ObjectInputStream#resolveClass(java.io.ObjectStreamClass)
*/
protected void annotateClass(Class cl) throws IOException
protected void annotateClass(Class<?> cl) throws IOException
{
}
protected void annotateProxyClass(Class cl) throws IOException
protected void annotateProxyClass(Class<?> cl) throws IOException
{
}
@@ -1104,17 +1107,16 @@ public class ObjectOutputStream extends OutputStream
// lookup the handle for OBJ, return null if OBJ doesn't have a
// handle yet
private Integer findHandle(Object obj)
private int findHandle(Object obj)
{
return (Integer)OIDLookupTable.get(new ObjectIdentityWrapper(obj));
return OIDLookupTable.get(obj);
}
// assigns the next availible handle to OBJ
private int assignNewHandle(Object obj)
{
OIDLookupTable.put(new ObjectIdentityWrapper(obj),
new Integer(nextOID));
OIDLookupTable.put(obj, nextOID);
return nextOID++;
}
@@ -1216,38 +1218,69 @@ public class ObjectOutputStream extends OutputStream
{
ObjectStreamField[] fields = osc.fields;
boolean oldmode = setBlockDataMode(false);
String field_name;
Class type;
try
{
writeFields(obj,fields);
}
catch (IllegalArgumentException _)
{
InvalidClassException e = new InvalidClassException
("writing fields of class " + osc.forClass().getName());
e.initCause(_);
throw e;
}
catch (IOException e)
{
throw e;
}
catch (Exception _)
{
IOException e = new IOException("Unexpected exception " + _);
e.initCause(_);
throw(e);
}
setBlockDataMode(oldmode);
}
/**
* Helper function for writeFields(Object,ObjectStreamClass): write
* fields from given fields array. Pass exception on.
*
* @param obj the object to be written
*
* @param fields the fields of obj to be written.
*/
private void writeFields(Object obj, ObjectStreamField[] fields)
throws
IllegalArgumentException, IllegalAccessException, IOException
{
for (int i = 0; i < fields.length; i++)
{
field_name = fields[i].getName();
type = fields[i].getType();
if (dump)
dumpElementln ("WRITE FIELD: " + field_name + " type=" + type);
if (type == Boolean.TYPE)
realOutput.writeBoolean(getBooleanField(obj, osc.forClass(), field_name));
else if (type == Byte.TYPE)
realOutput.writeByte(getByteField(obj, osc.forClass(), field_name));
else if (type == Character.TYPE)
realOutput.writeChar(getCharField(obj, osc.forClass(), field_name));
else if (type == Double.TYPE)
realOutput.writeDouble(getDoubleField(obj, osc.forClass(), field_name));
else if (type == Float.TYPE)
realOutput.writeFloat(getFloatField(obj, osc.forClass(), field_name));
else if (type == Integer.TYPE)
realOutput.writeInt(getIntField(obj, osc.forClass(), field_name));
else if (type == Long.TYPE)
realOutput.writeLong(getLongField(obj, osc.forClass(), field_name));
else if (type == Short.TYPE)
realOutput.writeShort(getShortField(obj, osc.forClass(), field_name));
else
writeObject(getObjectField(obj, osc.forClass(), field_name,
fields[i].getTypeString ()));
ObjectStreamField osf = fields[i];
Field field = osf.field;
if (DEBUG && dump)
dumpElementln ("WRITE FIELD: " + osf.getName() + " type=" + osf.getType());
switch (osf.getTypeCode())
{
case 'Z': realOutput.writeBoolean(field.getBoolean(obj)); break;
case 'B': realOutput.writeByte (field.getByte (obj)); break;
case 'S': realOutput.writeShort (field.getShort (obj)); break;
case 'C': realOutput.writeChar (field.getChar (obj)); break;
case 'I': realOutput.writeInt (field.getInt (obj)); break;
case 'F': realOutput.writeFloat (field.getFloat (obj)); break;
case 'J': realOutput.writeLong (field.getLong (obj)); break;
case 'D': realOutput.writeDouble (field.getDouble (obj)); break;
case 'L':
case '[': writeObject (field.get (obj)); break;
default:
throw new IOException("Unexpected type code " + osf.getTypeCode());
}
}
setBlockDataMode(oldmode);
}
@@ -1307,248 +1340,6 @@ public class ObjectOutputStream extends OutputStream
}
}
private boolean getBooleanField(Object obj, Class klass, String field_name)
throws IOException
{
try
{
Field f = getField(klass, field_name);
boolean b = f.getBoolean(obj);
return b;
}
catch (IllegalArgumentException _)
{
throw new InvalidClassException
("invalid requested type for field " + field_name + " in class " + klass.getName());
}
catch (IOException e)
{
throw e;
}
catch (Exception _)
{
throw new IOException("Unexpected exception " + _);
}
}
private byte getByteField (Object obj, Class klass, String field_name)
throws IOException
{
try
{
Field f = getField (klass, field_name);
byte b = f.getByte (obj);
return b;
}
catch (IllegalArgumentException _)
{
throw new InvalidClassException
("invalid requested type for field " + field_name + " in class " + klass.getName());
}
catch (IOException e)
{
throw e;
}
catch (Exception _)
{
throw new IOException("Unexpected exception " + _);
}
}
private char getCharField (Object obj, Class klass, String field_name)
throws IOException
{
try
{
Field f = getField (klass, field_name);
char b = f.getChar (obj);
return b;
}
catch (IllegalArgumentException _)
{
throw new InvalidClassException
("invalid requested type for field " + field_name + " in class " + klass.getName());
}
catch (IOException e)
{
throw e;
}
catch (Exception _)
{
throw new IOException("Unexpected exception " + _);
}
}
private double getDoubleField (Object obj, Class klass, String field_name)
throws IOException
{
try
{
Field f = getField (klass, field_name);
double b = f.getDouble (obj);
return b;
}
catch (IllegalArgumentException _)
{
throw new InvalidClassException
("invalid requested type for field " + field_name + " in class " + klass.getName());
}
catch (IOException e)
{
throw e;
}
catch (Exception _)
{
throw new IOException("Unexpected exception " + _);
}
}
private float getFloatField (Object obj, Class klass, String field_name)
throws IOException
{
try
{
Field f = getField (klass, field_name);
float b = f.getFloat (obj);
return b;
}
catch (IllegalArgumentException _)
{
throw new InvalidClassException
("invalid requested type for field " + field_name + " in class " + klass.getName());
}
catch (IOException e)
{
throw e;
}
catch (Exception _)
{
throw new IOException("Unexpected exception " + _);
}
}
private int getIntField (Object obj, Class klass, String field_name)
throws IOException
{
try
{
Field f = getField (klass, field_name);
int b = f.getInt (obj);
return b;
}
catch (IllegalArgumentException _)
{
throw new InvalidClassException
("invalid requested type for field " + field_name + " in class " + klass.getName());
}
catch (IOException e)
{
throw e;
}
catch (Exception _)
{
throw new IOException("Unexpected exception " + _);
}
}
private long getLongField (Object obj, Class klass, String field_name)
throws IOException
{
try
{
Field f = getField (klass, field_name);
long b = f.getLong (obj);
return b;
}
catch (IllegalArgumentException _)
{
throw new InvalidClassException
("invalid requested type for field " + field_name + " in class " + klass.getName());
}
catch (IOException e)
{
throw e;
}
catch (Exception _)
{
throw new IOException("Unexpected exception " + _);
}
}
private short getShortField (Object obj, Class klass, String field_name)
throws IOException
{
try
{
Field f = getField (klass, field_name);
short b = f.getShort (obj);
return b;
}
catch (IllegalArgumentException _)
{
throw new InvalidClassException
("invalid requested type for field " + field_name + " in class " + klass.getName());
}
catch (IOException e)
{
throw e;
}
catch (Exception _)
{
throw new IOException("Unexpected exception " + _);
}
}
private Object getObjectField (Object obj, Class klass, String field_name,
String type_code) throws IOException
{
try
{
Field f = getField (klass, field_name);
ObjectStreamField of = new ObjectStreamField(f.getName(), f.getType());
/* if of is primitive something went wrong
* in the check for primitive classes in writeFields.
*/
if (of.isPrimitive())
throw new InvalidClassException
("invalid type code for " + field_name + " in class " + klass.getName() + " : object stream field is primitive");
if (!of.getTypeString().equals(type_code))
throw new InvalidClassException
("invalid type code for " + field_name + " in class " + klass.getName() + " : object stream field " + of + " has type string " + of.getTypeString() + " instead of " + type_code);
Object o = f.get (obj);
// FIXME: We should check the type_code here
return o;
}
catch (IOException e)
{
throw e;
}
catch (Exception e)
{
throw new IOException ();
}
}
private Field getField (Class klass, String name)
throws java.io.InvalidClassException
{
try
{
final Field f = klass.getDeclaredField(name);
setAccessible.setMember(f);
AccessController.doPrivileged(setAccessible);
return f;
}
catch (java.lang.NoSuchFieldException e)
{
throw new InvalidClassException
("no field called " + name + " in class " + klass.getName());
}
}
private void dumpElementln (String msg)
{
for (int i = 0; i < depth; i++)
@@ -1576,7 +1367,7 @@ public class ObjectOutputStream extends OutputStream
private boolean replacementEnabled;
private boolean isSerializing;
private int nextOID;
private Hashtable OIDLookupTable;
private ObjectIdentityMap2Int OIDLookupTable;
private int protocolVersion;
private boolean useSubclassMethod;
private SetAccessibleAction setAccessible = new SetAccessibleAction();
+289 -176
View File
@@ -1,6 +1,6 @@
/* ObjectStreamClass.java -- Class used to write class information
about serialized objects.
Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -59,8 +59,14 @@ import java.security.Security;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Vector;
/**
* @author Tom Tromey (tromey@redhat.com)
* @author Jeroen Frijters (jeroen@frijters.net)
* @author Guilhem Lavaux (guilhem@kaffe.org)
* @author Michael Koch (konqueror@gmx.de)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
*/
public class ObjectStreamClass implements Serializable
{
static final ObjectStreamField[] INVALID_FIELDS = new ObjectStreamField[0];
@@ -80,7 +86,7 @@ public class ObjectStreamClass implements Serializable
*
* @see java.io.Serializable
*/
public static ObjectStreamClass lookup(Class cl)
public static ObjectStreamClass lookup(Class<?> cl)
{
if (cl == null)
return null;
@@ -132,7 +138,7 @@ public class ObjectStreamClass implements Serializable
*
* @see java.io.ObjectInputStream
*/
public Class forClass()
public Class<?> forClass()
{
return clazz;
}
@@ -235,37 +241,45 @@ public class ObjectStreamClass implements Serializable
return superClass;
}
// returns an array of ObjectStreamClasses that represent the super
// classes of CLAZZ and CLAZZ itself in order from most super to
// CLAZZ. ObjectStreamClass[0] is the highest superclass of CLAZZ
// that is serializable.
static ObjectStreamClass[] getObjectStreamClasses(Class clazz)
/**
* returns an array of ObjectStreamClasses that represent the super
* classes of the class represented by this and the class
* represented by this itself in order from most super to this.
* ObjectStreamClass[0] is the highest superclass of this that is
* serializable.
*
* The result of consecutive calls this hierarchy() will be the same
* array instance.
*
* @return an array of ObjectStreamClass representing the
* super-class hierarchy of serializable classes.
*/
ObjectStreamClass[] hierarchy()
{
ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
if (osc == null)
return new ObjectStreamClass[0];
else
{
Vector oscs = new Vector();
while (osc != null)
{
oscs.addElement (osc);
osc = osc.getSuper();
}
int count = oscs.size();
ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[ count ];
for (int i = count - 1; i >= 0; i--)
sorted_oscs[ count - i - 1 ] = (ObjectStreamClass) oscs.elementAt(i);
return sorted_oscs;
ObjectStreamClass[] result = hierarchy;
if (result == null)
{
int d = 0;
for(ObjectStreamClass osc = this; osc != null; osc = osc.getSuper())
d++;
result = new ObjectStreamClass[d];
for (ObjectStreamClass osc = this; osc != null; osc = osc.getSuper())
{
result[--d] = osc;
}
hierarchy = result;
}
return result;
}
/**
* Cache for hierarchy() result.
*/
private ObjectStreamClass[] hierarchy = null;
// Returns an integer that consists of bit-flags that indicate
// properties of the class represented by this ObjectStreamClass.
@@ -298,7 +312,7 @@ public class ObjectStreamClass implements Serializable
* already set UID is found.
*/
void setClass(Class cl, ObjectStreamClass superClass) throws InvalidClassException
{
{hierarchy = null;
this.clazz = cl;
cacheMethods();
@@ -309,8 +323,8 @@ public class ObjectStreamClass implements Serializable
else
{
// Check that the actual UID of the resolved class matches the UID from
// the stream.
if (uid != class_uid)
// the stream. Mismatches for array classes are ignored.
if (!cl.isArray() && uid != class_uid)
{
String msg = cl +
": Local class not compatible: stream serialVersionUID="
@@ -425,6 +439,7 @@ public class ObjectStreamClass implements Serializable
void setSuperclass (ObjectStreamClass osc)
{
superClass = osc;
hierarchy = null;
}
void calculateOffsets()
@@ -547,21 +562,62 @@ outer:
return null;
}
/**
* Helper routine to check if a class was loaded by boot or
* application class loader. Classes for which this is not the case
* should not be cached since caching prevent class file garbage
* collection.
*
* @param cl a class
*
* @return true if cl was loaded by boot or application class loader,
* false if cl was loaded by a user class loader.
*/
private static boolean loadedByBootOrApplicationClassLoader(Class cl)
{
ClassLoader l = cl.getClassLoader();
return
( l == null /* boot loader */ )
|| (l == ClassLoader.getSystemClassLoader() /* application loader */);
}
static Hashtable methodCache = new Hashtable();
static final Class[] readObjectSignature = { ObjectInputStream.class };
static final Class[] writeObjectSignature = { ObjectOutputStream.class };
private void cacheMethods()
{
Method[] methods = forClass().getDeclaredMethods();
Class cl = forClass();
Method[] cached = (Method[]) methodCache.get(cl);
if (cached == null)
{
cached = new Method[4];
Method[] methods = cl.getDeclaredMethods();
cached[0] = findMethod(methods, "readObject",
readObjectSignature,
Void.TYPE, true);
cached[1] = findMethod(methods, "writeObject",
writeObjectSignature,
Void.TYPE, true);
readObjectMethod = findMethod(methods, "readObject",
new Class[] { ObjectInputStream.class },
Void.TYPE, true);
writeObjectMethod = findMethod(methods, "writeObject",
new Class[] { ObjectOutputStream.class },
Void.TYPE, true);
// readResolve and writeReplace can be in parent classes, as long as they
// are accessible from this class.
readResolveMethod = findAccessibleMethod("readResolve", forClass());
writeReplaceMethod = findAccessibleMethod("writeReplace", forClass());
// readResolve and writeReplace can be in parent classes, as long as they
// are accessible from this class.
cached[2] = findAccessibleMethod("readResolve", cl);
cached[3] = findAccessibleMethod("writeReplace", cl);
/* put in cache if classes not loaded by user class loader.
* For a user class loader, the cache may otherwise grow
* without limit.
*/
if (loadedByBootOrApplicationClassLoader(cl))
methodCache.put(cl,cached);
}
readObjectMethod = cached[0];
writeObjectMethod = cached[1];
readResolveMethod = cached[2];
writeReplaceMethod = cached[3];
}
private ObjectStreamClass(Class cl)
@@ -713,152 +769,208 @@ outer:
calculateOffsets();
}
static Hashtable uidCache = new Hashtable();
// Returns the serial version UID defined by class, or if that
// isn't present, calculates value of serial version UID.
private long getClassUID(Class cl)
{
long result = 0;
Long cache = (Long) uidCache.get(cl);
if (cache != null)
result = cache.longValue();
else
{
try
{
result = getClassUIDFromField(cl);
}
catch (NoSuchFieldException ignore)
{
try
{
result = calculateClassUID(cl);
}
catch (NoSuchAlgorithmException e)
{
throw new RuntimeException
("The SHA algorithm was not found to use in computing the Serial Version UID for class "
+ cl.getName(), e);
}
catch (IOException ioe)
{
throw new RuntimeException(ioe);
}
}
if (loadedByBootOrApplicationClassLoader(cl))
uidCache.put(cl,new Long(result));
}
return result;
}
/**
* Search for a serialVersionUID field in the given class and read
* its value.
*
* @return the contents of the serialVersionUID field
*
* @throws NoSuchFieldException if such a field does not exist or is
* not static, not final, not of type Long or not accessible.
*/
long getClassUIDFromField(Class cl)
throws NoSuchFieldException
{
long result;
try
{
// Use getDeclaredField rather than getField, since serialVersionUID
// may not be public AND we only want the serialVersionUID of this
// class, not a superclass or interface.
final Field suid = cl.getDeclaredField("serialVersionUID");
SetAccessibleAction setAccessible = new SetAccessibleAction(suid);
AccessController.doPrivileged(setAccessible);
int modifiers = suid.getModifiers();
if (Modifier.isStatic(modifiers)
&& Modifier.isFinal(modifiers)
&& suid.getType() == Long.TYPE)
return suid.getLong(null);
}
catch (NoSuchFieldException ignore)
{
// Use getDeclaredField rather than getField, since serialVersionUID
// may not be public AND we only want the serialVersionUID of this
// class, not a superclass or interface.
final Field suid = cl.getDeclaredField("serialVersionUID");
SetAccessibleAction setAccessible = new SetAccessibleAction(suid);
AccessController.doPrivileged(setAccessible);
int modifiers = suid.getModifiers();
if (Modifier.isStatic(modifiers)
&& Modifier.isFinal(modifiers)
&& suid.getType() == Long.TYPE)
result = suid.getLong(null);
else
throw new NoSuchFieldException();
}
catch (IllegalAccessException ignore)
{
throw new NoSuchFieldException();
}
// cl didn't define serialVersionUID, so we have to compute it
try
return result;
}
/**
* Calculate class serial version UID for a class that does not
* define serialVersionUID:
*
* @param cl a class
*
* @return the calculated serial varsion UID.
*
* @throws NoSuchAlgorithmException if SHA algorithm not found
*
* @throws IOException if writing to the DigestOutputStream causes
* an IOException.
*/
long calculateClassUID(Class cl)
throws NoSuchAlgorithmException, IOException
{
long result;
MessageDigest md;
try
{
MessageDigest md;
try
{
md = MessageDigest.getInstance("SHA");
}
catch (NoSuchAlgorithmException e)
{
// If a provider already provides SHA, use it; otherwise, use this.
Gnu gnuProvider = new Gnu();
Security.addProvider(gnuProvider);
md = MessageDigest.getInstance("SHA");
}
DigestOutputStream digest_out =
new DigestOutputStream(nullOutputStream, md);
DataOutputStream data_out = new DataOutputStream(digest_out);
data_out.writeUTF(cl.getName());
int modifiers = cl.getModifiers();
// just look at interesting bits
modifiers = modifiers & (Modifier.ABSTRACT | Modifier.FINAL
| Modifier.INTERFACE | Modifier.PUBLIC);
data_out.writeInt(modifiers);
// Pretend that an array has no interfaces, because when array
// serialization was defined (JDK 1.1), arrays didn't have it.
if (! cl.isArray())
{
Class[] interfaces = cl.getInterfaces();
Arrays.sort(interfaces, interfaceComparator);
for (int i = 0; i < interfaces.length; i++)
data_out.writeUTF(interfaces[i].getName());
}
Field field;
Field[] fields = cl.getDeclaredFields();
Arrays.sort(fields, memberComparator);
for (int i = 0; i < fields.length; i++)
{
field = fields[i];
modifiers = field.getModifiers();
if (Modifier.isPrivate(modifiers)
&& (Modifier.isStatic(modifiers)
|| Modifier.isTransient(modifiers)))
continue;
data_out.writeUTF(field.getName());
data_out.writeInt(modifiers);
data_out.writeUTF(TypeSignature.getEncodingOfClass (field.getType()));
}
// write class initializer method if present
if (VMObjectStreamClass.hasClassInitializer(cl))
{
data_out.writeUTF("<clinit>");
data_out.writeInt(Modifier.STATIC);
data_out.writeUTF("()V");
}
Constructor constructor;
Constructor[] constructors = cl.getDeclaredConstructors();
Arrays.sort (constructors, memberComparator);
for (int i = 0; i < constructors.length; i++)
{
constructor = constructors[i];
modifiers = constructor.getModifiers();
if (Modifier.isPrivate(modifiers))
continue;
data_out.writeUTF("<init>");
data_out.writeInt(modifiers);
// the replacement of '/' with '.' was needed to make computed
// SUID's agree with those computed by JDK
data_out.writeUTF
(TypeSignature.getEncodingOfConstructor(constructor).replace('/','.'));
}
Method method;
Method[] methods = cl.getDeclaredMethods();
Arrays.sort(methods, memberComparator);
for (int i = 0; i < methods.length; i++)
{
method = methods[i];
modifiers = method.getModifiers();
if (Modifier.isPrivate(modifiers))
continue;
data_out.writeUTF(method.getName());
data_out.writeInt(modifiers);
// the replacement of '/' with '.' was needed to make computed
// SUID's agree with those computed by JDK
data_out.writeUTF
(TypeSignature.getEncodingOfMethod(method).replace('/', '.'));
}
data_out.close();
byte[] sha = md.digest();
long result = 0;
int len = sha.length < 8 ? sha.length : 8;
for (int i = 0; i < len; i++)
result += (long) (sha[i] & 0xFF) << (8 * i);
return result;
md = MessageDigest.getInstance("SHA");
}
catch (NoSuchAlgorithmException e)
{
throw new RuntimeException
("The SHA algorithm was not found to use in computing the Serial Version UID for class "
+ cl.getName(), e);
// If a provider already provides SHA, use it; otherwise, use this.
Gnu gnuProvider = new Gnu();
Security.addProvider(gnuProvider);
md = MessageDigest.getInstance("SHA");
}
catch (IOException ioe)
DigestOutputStream digest_out =
new DigestOutputStream(nullOutputStream, md);
DataOutputStream data_out = new DataOutputStream(digest_out);
data_out.writeUTF(cl.getName());
int modifiers = cl.getModifiers();
// just look at interesting bits
modifiers = modifiers & (Modifier.ABSTRACT | Modifier.FINAL
| Modifier.INTERFACE | Modifier.PUBLIC);
data_out.writeInt(modifiers);
// Pretend that an array has no interfaces, because when array
// serialization was defined (JDK 1.1), arrays didn't have it.
if (! cl.isArray())
{
throw new RuntimeException(ioe);
Class[] interfaces = cl.getInterfaces();
Arrays.sort(interfaces, interfaceComparator);
for (int i = 0; i < interfaces.length; i++)
data_out.writeUTF(interfaces[i].getName());
}
Field field;
Field[] fields = cl.getDeclaredFields();
Arrays.sort(fields, memberComparator);
for (int i = 0; i < fields.length; i++)
{
field = fields[i];
modifiers = field.getModifiers();
if (Modifier.isPrivate(modifiers)
&& (Modifier.isStatic(modifiers)
|| Modifier.isTransient(modifiers)))
continue;
data_out.writeUTF(field.getName());
data_out.writeInt(modifiers);
data_out.writeUTF(TypeSignature.getEncodingOfClass (field.getType()));
}
// write class initializer method if present
if (VMObjectStreamClass.hasClassInitializer(cl))
{
data_out.writeUTF("<clinit>");
data_out.writeInt(Modifier.STATIC);
data_out.writeUTF("()V");
}
Constructor constructor;
Constructor[] constructors = cl.getDeclaredConstructors();
Arrays.sort (constructors, memberComparator);
for (int i = 0; i < constructors.length; i++)
{
constructor = constructors[i];
modifiers = constructor.getModifiers();
if (Modifier.isPrivate(modifiers))
continue;
data_out.writeUTF("<init>");
data_out.writeInt(modifiers);
// the replacement of '/' with '.' was needed to make computed
// SUID's agree with those computed by JDK
data_out.writeUTF
(TypeSignature.getEncodingOfConstructor(constructor).replace('/','.'));
}
Method method;
Method[] methods = cl.getDeclaredMethods();
Arrays.sort(methods, memberComparator);
for (int i = 0; i < methods.length; i++)
{
method = methods[i];
modifiers = method.getModifiers();
if (Modifier.isPrivate(modifiers))
continue;
data_out.writeUTF(method.getName());
data_out.writeInt(modifiers);
// the replacement of '/' with '.' was needed to make computed
// SUID's agree with those computed by JDK
data_out.writeUTF
(TypeSignature.getEncodingOfMethod(method).replace('/', '.'));
}
data_out.close();
byte[] sha = md.digest();
result = 0;
int len = sha.length < 8 ? sha.length : 8;
for (int i = 0; i < len; i++)
result += (long) (sha[i] & 0xFF) << (8 * i);
return result;
}
/**
@@ -948,7 +1060,8 @@ outer:
public static final ObjectStreamField[] NO_FIELDS = {};
private static Hashtable classLookupTable = new Hashtable();
private static Hashtable<Class,ObjectStreamClass> classLookupTable
= new Hashtable<Class,ObjectStreamClass>();
private static final NullOutputStream nullOutputStream = new NullOutputStream();
private static final Comparator interfaceComparator = new InterfaceComparator();
private static final Comparator memberComparator = new MemberComparator();
@@ -956,7 +1069,7 @@ outer:
Class[] writeMethodArgTypes = { java.io.ObjectOutputStream.class };
private ObjectStreamClass superClass;
private Class clazz;
private Class<?> clazz;
private String name;
private long uid;
private byte flags;
@@ -1,5 +1,5 @@
/* ObjectStreamField.java -- Class used to store name and class of fields
Copyright (C) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,17 +48,24 @@ import java.security.PrivilegedAction;
* This class intends to describe the field of a class for the serialization
* subsystem. Serializable fields in a serializable class can be explicitly
* exported using an array of ObjectStreamFields.
*
* @author Tom Tromey (tromey@redhat.com)
* @author Jeroen Frijters (jeroen@frijters.net)
* @author Guilhem Lavaux (guilhem@kaffe.org)
* @author Michael Koch (konqueror@gmx.de)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
*/
public class ObjectStreamField implements Comparable
public class ObjectStreamField
implements Comparable<Object>
{
private String name;
private Class type;
private Class<?> type;
private String typename;
private int offset = -1; // XXX make sure this is correct
private boolean unshared;
private boolean persistent = false;
private boolean toset = true;
private Field field;
Field field;
ObjectStreamField (Field field)
{
@@ -74,7 +81,7 @@ public class ObjectStreamField implements Comparable
* @param name Name of the field to export.
* @param type Type of the field in the concerned class.
*/
public ObjectStreamField (String name, Class type)
public ObjectStreamField (String name, Class<?> type)
{
this (name, type, false);
}
@@ -88,7 +95,7 @@ public class ObjectStreamField implements Comparable
* @param type Type of the field in the concerned class.
* @param unshared true if field will be unshared, false otherwise.
*/
public ObjectStreamField (String name, Class type, boolean unshared)
public ObjectStreamField (String name, Class<?> type, boolean unshared)
{
if (name == null)
throw new NullPointerException();
@@ -111,28 +118,10 @@ public class ObjectStreamField implements Comparable
{
this.name = name;
this.typename = typename;
try
{
type = TypeSignature.getClassForEncoding(typename);
}
catch(ClassNotFoundException e)
{
}
}
/**
* There are many cases you can not get java.lang.Class from typename
* if your context class loader cann not load it, then use typename to
* construct the field.
*
* @param name Name of the field to export.
* @param typename The coded name of the type for this field.
* @param loader The class loader to use to resolve class names.
*/
ObjectStreamField (String name, String typename, ClassLoader loader)
void resolveType(ClassLoader loader)
{
this.name = name;
this.typename = typename;
try
{
type = TypeSignature.getClassForEncoding(typename, true, loader);
@@ -141,7 +130,7 @@ public class ObjectStreamField implements Comparable
{
}
}
/**
* This method returns the name of the field represented by the
* ObjectStreamField instance.
@@ -159,7 +148,7 @@ public class ObjectStreamField implements Comparable
*
* @return A class representing the type of the field.
*/
public Class getType ()
public Class<?> getType ()
{
return type;
}
@@ -347,7 +336,7 @@ public class ObjectStreamField implements Comparable
*/
void checkFieldType() throws InvalidClassException
{
Class ftype = field.getType();
Class<?> ftype = field.getType();
if (!ftype.isAssignableFrom(type))
throw new InvalidClassException
@@ -223,6 +223,7 @@ public class OutputStreamWriter extends Writer
encoder.onMalformedInput(CodingErrorAction.REPLACE);
encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
encodingName = EncodingHelper.getOldCanonical(cs.name());
}
/**
@@ -240,6 +241,11 @@ public class OutputStreamWriter extends Writer
this.out = out;
encoder = enc;
outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
Charset cs = enc.charset();
if (cs == null)
encodingName = "US-ASCII";
else
encodingName = EncodingHelper.getOldCanonical(cs.name());
}
/**
@@ -279,6 +279,10 @@ public class PipedInputStream extends InputStream
if (closed)
throw new IOException ("Pipe closed");
// Don't block if nothing was requested.
if (len == 0)
return 0;
// If the buffer is empty, wait until there is something in the pipe
// to read.
try
@@ -261,6 +261,10 @@ public class PipedReader extends Reader
if (closed)
throw new IOException ("Pipe closed");
// Don't block if nothing was requested.
if (len == 0)
return 0;
// If the buffer is empty, wait until there is something in the pipe
// to read.
try
+53 -3
View File
@@ -39,6 +39,9 @@ exception statement from your version. */
package java.io;
import java.util.Locale;
import java.util.Formatter;
import gnu.classpath.SystemProperties;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
@@ -58,8 +61,9 @@ import gnu.classpath.SystemProperties;
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
*/
public class PrintStream extends FilterOutputStream
public class PrintStream extends FilterOutputStream implements Appendable
{
/* Notice the implementation is quite similar to OutputStreamWriter.
* This leads to some minor duplication, because neither inherits
@@ -67,7 +71,7 @@ public class PrintStream extends FilterOutputStream
// Line separator string.
private static final char[] line_separator
= SystemProperties.getProperty("line.separator").toCharArray();
= SystemProperties.getProperty("line.separator", "\n").toCharArray();
/**
* Encoding name
@@ -620,5 +624,51 @@ public class PrintStream extends FilterOutputStream
setError ();
}
}
} // class PrintStream
/** @since 1.5 */
public PrintStream append(char c)
{
print(c);
return this;
}
/** @since 1.5 */
public PrintStream append(CharSequence cs)
{
print(cs == null ? "null" : cs.toString());
return this;
}
/** @since 1.5 */
public PrintStream append(CharSequence cs, int start, int end)
{
print(cs == null ? "null" : cs.subSequence(start, end).toString());
return this;
}
/** @since 1.5 */
public PrintStream printf(String format, Object... args)
{
return format(format, args);
}
/** @since 1.5 */
public PrintStream printf(Locale locale, String format, Object... args)
{
return format(locale, format, args);
}
/** @since 1.5 */
public PrintStream format(String format, Object... args)
{
return format(Locale.getDefault(), format, args);
}
/** @since 1.5 */
public PrintStream format(Locale locale, String format, Object... args)
{
Formatter f = new Formatter(this, locale);
f.format(format, args);
return this;
}
} // class PrintStream
+51 -1
View File
@@ -1,5 +1,5 @@
/* PrintWriter.java -- prints primitive values and objects to a stream as text
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
Copyright (C) 1998, 1999, 2000, 2001, 2005 Free Software Foundation
This file is part of GNU Classpath.
@@ -37,6 +37,9 @@ exception statement from your version. */
package java.io;
import java.util.Locale;
import java.util.Formatter;
/* Written using "Java Class Libraries", 2nd edition, plus online
* API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
@@ -636,5 +639,52 @@ public class PrintWriter extends Writer
{
write(str, 0, str.length());
}
/** @since 1.5 */
public PrintWriter append(char c)
{
write(c);
return this;
}
/** @since 1.5 */
public PrintWriter append(CharSequence cs)
{
write(cs == null ? "null" : cs.toString());
return this;
}
/** @since 1.5 */
public PrintWriter append(CharSequence cs, int start, int end)
{
write(cs == null ? "null" : cs.subSequence(start, end).toString());
return this;
}
/** @since 1.5 */
public PrintWriter printf(String format, Object... args)
{
return format(format, args);
}
/** @since 1.5 */
public PrintWriter printf(Locale locale, String format, Object... args)
{
return format(locale, format, args);
}
/** @since 1.5 */
public PrintWriter format(String format, Object... args)
{
return format(Locale.getDefault(), format, args);
}
/** @since 1.5 */
public PrintWriter format(Locale locale, String format, Object... args)
{
Formatter f = new Formatter(this, locale);
f.format(format, args);
return this;
}
}
@@ -38,7 +38,7 @@ exception statement from your version. */
package java.io;
import gnu.java.nio.channels.FileChannelImpl;
import gnu.java.nio.FileChannelImpl;
import java.nio.channels.FileChannel;
@@ -58,7 +58,7 @@ import java.nio.channels.FileChannel;
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class RandomAccessFile implements DataOutput, DataInput
public class RandomAccessFile implements DataOutput, DataInput, Closeable
{
// The underlying file.
@@ -122,7 +122,20 @@ public class RandomAccessFile implements DataOutput, DataInput
s.checkWrite(fileName);
}
ch = FileChannelImpl.create(file, fdmode);
try
{
ch = FileChannelImpl.create(file, fdmode);
}
catch (FileNotFoundException fnfe)
{
throw fnfe;
}
catch (IOException ioe)
{
FileNotFoundException fnfe = new FileNotFoundException(file.getPath());
fnfe.initCause(ioe);
throw fnfe;
}
fd = new FileDescriptor(ch);
if ((fdmode & FileChannelImpl.WRITE) != 0)
out = new DataOutputStream (new FileOutputStream (fd));
+17 -2
View File
@@ -1,5 +1,5 @@
/* Reader.java -- base class of classes that read input as a stream of chars
Copyright (C) 1998, 1999, 2000, 2003 Free Software Foundation
Copyright (C) 1998, 1999, 2000, 2003, 2004, 2005 Free Software Foundation
This file is part of GNU Classpath.
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.io;
import java.nio.CharBuffer;
/* Written using "Java Class Libraries", 2nd edition, plus online
* API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
@@ -53,7 +55,7 @@ package java.io;
* @date April 21, 1998.
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public abstract class Reader
public abstract class Reader implements Closeable, Readable
{
/**
* This is the <code>Object</code> used for synchronizing critical code
@@ -152,6 +154,19 @@ public abstract class Reader
return count > 0 ? buf[0] : -1;
}
/** @since 1.5 */
public int read(CharBuffer buffer) throws IOException
{
// We want to call put(), so we don't manipulate the CharBuffer
// directly.
int rem = buffer.remaining();
char[] buf = new char[rem];
int result = read(buf, 0, rem);
if (result != -1)
buffer.put(buf, 0, result);
return result;
}
/**
* Closes the stream. Any futher attempts to read from the
* stream may generate an <code>IOException</code>.
@@ -1,5 +1,5 @@
/* SequenceInputStream.java -- Reads multiple input streams in sequence
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2001, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -71,8 +71,11 @@ public class SequenceInputStream extends InputStream
/** Secondary input stream; not used if constructed w/ enumeration. */
private InputStream in2;
/** The enumeration handle; not used if constructed w/ 2 explicit input streams. */
private Enumeration e;
/**
* The enumeration handle; not used if constructed w/ 2 explicit
* input streams.
*/
private Enumeration<? extends InputStream> e;
/**
* This method creates a new <code>SequenceInputStream</code> that obtains
@@ -82,10 +85,10 @@ public class SequenceInputStream extends InputStream
* @param e An <code>Enumeration</code> that will return a list of
* <code>InputStream</code>s to read in sequence
*/
public SequenceInputStream(Enumeration e)
public SequenceInputStream(Enumeration<? extends InputStream> e)
{
this.e = e;
in = (InputStream) e.nextElement();
in = e.nextElement();
in2 = null;
}
@@ -207,14 +210,13 @@ public class SequenceInputStream extends InputStream
if (e != null)
{
if (e.hasMoreElements())
nextIn = (InputStream) e.nextElement();
nextIn = e.nextElement();
}
else if (in2 != null)
{
nextIn = in2;
in2 = null;
}
else
if (in2 != null)
{
nextIn = in2;
in2 = null;
}
return nextIn;
}
@@ -183,6 +183,27 @@ public class StringWriter extends Writer
buffer.append(str.substring(offset, offset + len));
}
/** @since 1.5 */
public StringWriter append(char c)
{
write(c);
return this;
}
/** @since 1.5 */
public StringWriter append(CharSequence cs)
{
write(cs == null ? "null" : cs.toString());
return this;
}
/** @since 1.5 */
public StringWriter append(CharSequence cs, int start, int end)
{
write(cs == null ? "null" : cs.subSequence(start, end).toString());
return this;
}
/**
* This is the <code>StringBuffer</code> that we use to store bytes that
* are written.
+21 -2
View File
@@ -53,7 +53,7 @@ package java.io;
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Per Bothner (bothner@cygnus.com)
*/
public abstract class Writer
public abstract class Writer implements Appendable, Closeable, Flushable
{
/**
* This is the object used to synchronize criticial code sections for
@@ -188,5 +188,24 @@ public abstract class Writer
write(buf, 0, len);
}
} // class Writer
/** @since 1.5 */
public Writer append(char c) throws IOException
{
write(c);
return this;
}
/** @since 1.5 */
public Writer append(CharSequence cs) throws IOException
{
write(cs == null ? "null" : cs.toString());
return this;
}
/** @since 1.5 */
public Writer append(CharSequence cs, int start, int end) throws IOException
{
write(cs == null ? "null" : cs.subSequence(start, end).toString());
return this;
}
}
@@ -0,0 +1,100 @@
# This property file contains dependencies of classes, methods, and
# field on other methods or classes.
#
# Syntax:
#
# <used>: <needed 1> [... <needed N>]
#
# means that when <used> is included, <needed 1> (... <needed N>) must
# be included as well.
#
# <needed X> and <used> are of the form
#
# <class.methodOrField(signature)>
#
# or just
#
# <class>
#
# Within dependencies, variables can be used. A variable is defined as
# follows:
#
# {variable}: value1 value2 ... value<n>
#
# variables can be used on the right side of dependencies as follows:
#
# <used>: com.bla.blu.{variable}.Class.m()V
#
# The use of the variable will expand to <n> dependencies of the form
#
# <used>: com.bla.blu.value1.Class.m()V
# <used>: com.bla.blu.value2.Class.m()V
# ...
# <used>: com.bla.blu.value<n>.Class.m()V
#
# Variables can be redefined when building a system to select the
# required support for features like encodings, protocols, etc.
#
# Hints:
#
# - For methods and fields, the signature is mandatory. For
# specification, please see the Java Virtual Machine Specification by
# SUN. Unlike in the spec, field signatures (types) are in brackets.
#
# - Package names must be separated by '/' (and not '.'). E.g.,
# java/lang/Class (this is necessary, because the '.' is used to
# separate method or field names from classes)
#
# - In case <needed> refers to a class, only the class itself will be
# included in the resulting binary, NOT necessarily all its methods
# and fields. If you want to refer to all methods and fields, you can
# write class.* as an abbreviation.
#
# - Abbreviations for packages are also possible: my/package/* means all
# methods and fields of all classes in my/package.
#
# - A line with a trailing '\' continues in the next line.
java/io/File: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V \
java/lang/IllegalArgumentException.<init>(Ljava/lang/String;)V
java/io/FileDescriptor: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/lang/IllegalArgumentException.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V
java/io/FileInputStream: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V \
java/io/FileNotFoundException.<init>(Ljava/lang/String;)V
java/io/FileOutputStream: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/io/FileNotFoundException.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V
java/io/ObjectInputStream: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/lang/SecurityManager.currentClassLoader()Ljava/lang/ClassLoader; \
java/lang/IllegalArgumentException.<init>(Ljava/lang/String;)V
java/io/ObjectOutputStream: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/lang/SecurityManager.currentClassLoader()Ljava/lang/ClassLoader; \
java/lang/IllegalArgumentException.<init>(Ljava/lang/String;)V
java/io/RandomAccessFile: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/io/FileNotFoundException.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V
# end of file