Initial revision

From-SVN: r102075
This commit is contained in:
Tom Tromey 2005-07-16 00:31:27 +00:00
parent f911ba985a
commit 37d375fdc5
32 changed files with 5340 additions and 0 deletions

View file

@ -0,0 +1,2 @@
Makefile
Makefile.in

View file

@ -0,0 +1,4 @@
# used by automake to generate Makefile.in
SUBDIRS = reference

View file

@ -0,0 +1,2 @@
Makefile
Makefile.in

View file

@ -0,0 +1,3 @@
# used by automake to generate Makefile.in
SUBDIRS = java gnu

View file

@ -0,0 +1,108 @@
/* VMStackWalker.java -- Reference implementation of VM hooks for stack access
Copyright (C) 2005 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.classpath;
/**
* This class provides access to the classes on the Java stack
* for reflection and security purposes.
*
* <p>
* This class is only available to privileged code (i.e., code loaded
* by the bootstrap loader).
*
* @author John Keiser
* @author Eric Blake <ebb9@email.byu.edu>
* @author Archie Cobbs
*/
public final class VMStackWalker
{
/**
* Get a list of all the classes currently executing methods on the
* Java stack. <code>getClassContext()[0]</code> is the class associated
* with the currently executing method, i.e., the method that called
* <code>VMStackWalker.getClassContext()</code> (possibly through
* reflection). So you may need to pop off these stack frames from
* the top of the stack:
* <ul>
* <li><code>VMStackWalker.getClassContext()</code>
* <li><code>Method.invoke()</code>
* </ul>
*
* @return an array of the declaring classes of each stack frame
*/
public static native Class[] getClassContext();
/**
* Get the class associated with the method invoking the method
* invoking this method, or <code>null</code> if the stack is not
* that deep (e.g., invoked via JNI invocation API). This method
* is an optimization for the expression <code>getClassContext()[1]</code>
* and should return the same result.
*
* <p>
* VM implementers are encouraged to provide a more efficient
* version of this method.
*/
public static Class getCallingClass()
{
Class[] ctx = getClassContext();
if (ctx.length < 3)
return null;
return ctx[2];
}
/**
* Get the class loader associated with the Class returned by
* <code>getCallingClass()</code>, or <code>null</code> if no
* such class exists or it is the boot loader. This method is an optimization
* for the expression <code>getClassContext()[1].getClassLoader()</code>
* and should return the same result.
*
* <p>
* VM implementers are encouraged to provide a more efficient
* version of this method.
*/
public static ClassLoader getCallingClassLoader()
{
Class[] ctx = getClassContext();
if (ctx.length < 3)
return null;
return ctx[2].getClassLoader();
}
}

View file

@ -0,0 +1,97 @@
/* VMSystemProperties.java -- Allow the VM to set System properties.
Copyright (C) 2004 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.classpath;
import java.util.Properties;
class VMSystemProperties
{
/**
* Get the system properties. This is done here, instead of in System,
* because of the bootstrap sequence. Note that the native code should
* not try to use the Java I/O classes yet, as they rely on the properties
* already existing. The only safe method to use to insert these default
* system properties is {@link Properties#setProperty(String, String)}.
*
* <p>These properties MUST include:
* <dl>
* <dt>java.version <dd>Java version number
* <dt>java.vendor <dd>Java vendor specific string
* <dt>java.vendor.url <dd>Java vendor URL
* <dt>java.home <dd>Java installation directory
* <dt>java.vm.specification.version <dd>VM Spec version
* <dt>java.vm.specification.vendor <dd>VM Spec vendor
* <dt>java.vm.specification.name <dd>VM Spec name
* <dt>java.vm.version <dd>VM implementation version
* <dt>java.vm.vendor <dd>VM implementation vendor
* <dt>java.vm.name <dd>VM implementation name
* <dt>java.specification.version <dd>Java Runtime Environment version
* <dt>java.specification.vendor <dd>Java Runtime Environment vendor
* <dt>java.specification.name <dd>Java Runtime Environment name
* <dt>java.class.version <dd>Java class version number
* <dt>java.class.path <dd>Java classpath
* <dt>java.library.path <dd>Path for finding Java libraries
* <dt>java.io.tmpdir <dd>Default temp file path
* <dt>java.compiler <dd>Name of JIT to use
* <dt>java.ext.dirs <dd>Java extension path
* <dt>os.name <dd>Operating System Name
* <dt>os.arch <dd>Operating System Architecture
* <dt>os.version <dd>Operating System Version
* <dt>file.separator <dd>File separator ("/" on Unix)
* <dt>path.separator <dd>Path separator (":" on Unix)
* <dt>line.separator <dd>Line separator ("\n" on Unix)
* <dt>user.name <dd>User account name
* <dt>user.home <dd>User home directory
* <dt>user.dir <dd>User's current working directory
* <dt>gnu.cpu.endian <dd>"big" or "little"
* </dl>
*
* @param p the Properties object to insert the system properties into
*/
static native void preInit(Properties properties);
/**
* Here you get a chance to overwrite some of the properties set by
* the common SystemProperties code. For example, it might be
* a good idea to process the properties specified on the command
* line here.
*/
static void postInit(Properties properties)
{
}
}

View file

@ -0,0 +1,64 @@
/* VMPipe.java -- Reference implementation for VM hooks used by PipeImpl
Copyright (C) 2004 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.nio;
import java.io.IOException;
import java.nio.channels.spi.SelectorProvider;
import gnu.classpath.Configuration;
/**
* This class contains the native methods for gnu.java.nio.PipeImpl
* As such, it needs help from the VM.
*
* @author Patrik Reali
*/
final class VMPipe
{
static
{
// load the shared library needed for native methods.
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary ("javanio");
}
}
static native void init(PipeImpl self, SelectorProvider provider)
throws IOException;
}

View file

@ -0,0 +1,59 @@
/* VMSelector.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.nio;
import gnu.classpath.Configuration;
import java.io.IOException;
public final class VMSelector
{
static
{
// load the shared library needed for native methods.
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary ("javanio");
}
}
// A timeout value of 0 means block forever.
static native int select (int[] read, int[] write,
int[] except, long timeout)
throws IOException;
}

View file

@ -0,0 +1,229 @@
/* VMFile.java -- Class for methods natively accessing files
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import gnu.classpath.Configuration;
import gnu.java.io.PlatformHelper;
/**
* @author Michael Koch (konqueror@gmx.de)
*/
final class VMFile
{
// FIXME: We support only case sensitive filesystems currently.
static final boolean IS_CASE_SENSITIVE = true;
static final boolean IS_DOS_8_3 = false;
static
{
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary("javaio");
}
}
/*
* This native method does the actual work of getting the last file
* modification time. It also does the existence check to avoid the
* overhead of a call to exists()
*/
static native long lastModified(String path);
/*
* This native method sets the permissions to make the file read only.
*/
static native boolean setReadOnly(String path);
/**
* This method is used to create a temporary file
*/
static native boolean create(String path) throws IOException;
/*
* This native function actually produces the list of file in this
* directory
*/
static native String[] list(String dirpath);
/*
* This native method actually performs the rename.
*/
static native boolean renameTo(String targetpath, String destpath);
/*
* This native method actually determines the length of the file and
* handles the existence check
*/
static native long length(String path);
/*
* This native method does the actual checking of file existence.
*/
static native boolean exists(String path);
/*
* This native method handles the actual deleting of the file
*/
static native boolean delete(String path);
/*
* This method does the actual setting of the modification time.
*/
static native boolean setLastModified(String path, long time);
/*
* This native method actually creates the directory
*/
static native boolean mkdir(String dirpath);
/*
* This native method does the actual check of whether or not a file
* is a plain file or not. It also handles the existence check to
* eliminate the overhead of a call to exists()
*/
static native boolean isFile(String path);
/**
* This native method checks file permissions for writing
*/
static synchronized native boolean canWrite(String path);
/**
* This methods checks if a directory can be written to.
*/
static boolean canWriteDirectory(File dir)
{
try
{
String filename = IS_DOS_8_3 ? "tst" : "test-dir-write";
File test = File.createTempFile(filename, null, dir);
return (test != null && test.delete());
}
catch (IOException ioe)
{
return false;
}
}
/**
* This native method checks file permissions for reading
*/
static synchronized native boolean canRead(String path);
/*
* This method does the actual check of whether or not a file is a
* directory or not. It also handle the existence check to eliminate
* the overhead of a call to exists()
*/
static native boolean isDirectory(String dirpath);
/**
* This method returns an array of filesystem roots. Some operating systems
* have volume oriented filesystem. This method provides a mechanism for
* determining which volumes exist. GNU systems use a single hierarchical
* filesystem, so will have only one "/" filesystem root.
*
* @return An array of <code>File</code> objects for each filesystem root
* available.
*
* @since 1.2
*/
static File[] listRoots()
{
File[] roots = new File[1];
roots[0] = new File("/");
return roots;
}
/**
* This method tests whether or not this file represents a "hidden" file.
* On GNU systems, a file is hidden if its name begins with a "."
* character. Files with these names are traditionally not shown with
* directory listing tools.
*
* @return <code>true</code> if the file is hidden, <code>false</code>
* otherwise.
*
* @since 1.2
*/
static boolean isHidden(String path)
{
// FIXME: this only works on UNIX
return getName(path).startsWith(".");
}
/**
* This method returns the name of the file. This is everything in the
* complete path of the file after the last instance of the separator
* string.
*
* @return The file name
*/
static String getName(String path)
{
int pos = PlatformHelper.lastIndexOfSeparator(path);
if (pos == -1)
return path;
if (PlatformHelper.endWithSeparator(path))
return "";
return path.substring(pos + File.separator.length());
}
/**
* This method returns a canonical representation of the pathname of
* the given path. The actual form of the canonical representation is
* different. On the GNU system, the canonical form differs from the
* absolute form in that all relative file references to "." and ".."
* are resolved and removed.
* <p>
* Note that this method, unlike the other methods which return path
* names, can throw an IOException. This is because native method
* might be required in order to resolve the canonical path
*
* @exception IOException If an error occurs
*/
public static String toCanonicalForm(String path) throws IOException
{
// FIXME: this only works on UNIX
return PlatformHelper.toCanonicalForm(path);
}
}

View file

@ -0,0 +1,86 @@
/* ObjectInputStream.java -- Class used to read serialized objects
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import gnu.classpath.VMStackWalker;
import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedAction;
final class VMObjectInputStream
{
private static Class oisClass = ObjectInputStream.class;
private static Class vmoisClass = VMObjectInputStream.class;
// PrivilegedAction needed for Class.getClassLoader()
private static PrivilegedAction loaderAction = new PrivilegedAction()
{
public Object run()
{
Class[] ctx = VMStackWalker.getClassContext();
for (int i = 0; i < ctx.length; i++)
{
ClassLoader cl = ctx[i].getClassLoader();
if (cl != null)
return cl;
}
return null;
}
};
/**
* Returns the first user defined class loader on the call stack, or
* null when no non-null class loader was found.
*/
static ClassLoader currentClassLoader()
{
return (ClassLoader) AccessController.doPrivileged(loaderAction);
}
/**
* Allocates a new Object of type clazz but without running the
* default constructor on it. It then calls the given constructor on
* it. The given constructor method comes from the constr_clazz
* which is a super class of the given clazz.
*/
static native Object allocateObject(Class clazz, Class constr_clazz,
Constructor constructor)
throws InstantiationException;
}

View file

@ -0,0 +1,160 @@
/* VMObjectStreamClass.java -- VM helper functions for ObjectStreamClass
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import java.lang.reflect.Field;
final class VMObjectStreamClass
{
/**
* Returns true if CLAZZ has a static class initializer
* (a.k.a. <clinit>).
*/
static native boolean hasClassInitializer (Class clazz);
/**
* Sets the value of the specified field. This method handles "double".
* Warning ! The types are not truely checked here and final values may be
* assigned.
*
* @param field Field to set the value.
* @param obj Instance which will have its field set.
* @param val Value to put in the field.
*/
static native void setDoubleNative(Field field, Object obj, double val)
throws InternalError;
/**
* Sets the value of the specified field. This method handles "float".
* Warning ! The types are not truely checked here and final values may be
* assigned.
*
* @param field Field to set the value.
* @param obj Instance which will have its field set.
* @param val Value to put in the field.
*/
static native void setFloatNative(Field field, Object obj, float val)
throws InternalError;
/**
* Sets the value of the specified field. This method handles "long".
* Warning ! The types are not truely checked here and final values may be
* assigned.
*
* @param field Field to set the value.
* @param obj Instance which will have its field set.
* @param val Value to put in the field.
*/
static native void setLongNative(Field field, Object obj, long val)
throws InternalError;
/**
* Sets the value of the specified field. This method handles "int".
* Warning ! The types are not truely checked here and final values may be
* assigned.
*
* @param field Field to set the value.
* @param obj Instance which will have its field set.
* @param val Value to put in the field.
*/
static native void setIntNative(Field field, Object obj, int val)
throws InternalError;
/**
* Sets the value of the specified field. This method handles "short".
* Warning ! The types are not truely checked here and final values may be
* assigned.
*
* @param field Field to set the value.
* @param obj Instance which will have its field set.
* @param val Value to put in the field.
*/
static native void setShortNative(Field field, Object obj, short val)
throws InternalError;
/**
* Sets the value of the specified field. This method handles "char".
* Warning ! The types are not truely checked here and final values may be
* assigned.
*
* @param field Field to set the value.
* @param obj Instance which will have its field set.
* @param val Value to put in the field.
*/
static native void setCharNative(Field field, Object obj, char val)
throws InternalError;
/**
* Sets the value of the specified field. This method handles "byte".
* Warning ! The types are not truely checked here and final values may be
* assigned.
*
* @param field Field to set the value.
* @param obj Instance which will have its field set.
* @param val Value to put in the field.
*/
static native void setByteNative(Field field, Object obj, byte val)
throws InternalError;
/**
* Sets the value of the specified field. This method handles "boolean".
* Warning ! The types are not truely checked here and final values may be
* assigned.
*
* @param field Field to set the value.
* @param obj Instance which will have its field set.
* @param val Value to put in the field.
*/
static native void setBooleanNative(Field field, Object obj, boolean val)
throws InternalError;
/**
* Sets the value of the specified field. This method handles "object".
* Warning ! The types are not truely checked here and final values may be
* assigned.
*
* @param field Field to set the value.
* @param obj Instance which will have its field set.
* @param val Value to put in the field.
*/
static native void setObjectNative(Field field, Object obj, Object val)
throws InternalError;
}

View file

@ -0,0 +1,295 @@
/* VMClass.java -- VM Specific Class methods
Copyright (C) 2003, 2004 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/*
* This class is a reference version, mainly for compiling a class library
* jar. It is likely that VM implementers replace this with their own
* version that can communicate effectively with the VM.
*/
/**
*
* @author Etienne Gagnon <etienne.gagnon@uqam.ca>
* @author Archie Cobbs <archie@dellroad.org>
* @author C. Brian Jones <cbj@gnu.org>
*/
final class VMClass
{
// Only static methods. Cannot be instantiated.
private VMClass()
{
}
/**
* Discover whether an Object is an instance of this Class. Think of it
* as almost like <code>o instanceof (this class)</code>.
*
* @param klass the Class object that's calling us
* @param o the Object to check
* @return whether o is an instance of this class
* @since 1.1
*/
static native boolean isInstance(Class klass, Object o);
/**
* Discover whether an instance of the Class parameter would be an
* instance of this Class as well. Think of doing
* <code>isInstance(c.newInstance())</code> or even
* <code>c.newInstance() instanceof (this class)</code>. While this
* checks widening conversions for objects, it must be exact for primitive
* types.
*
* @param klass the Class object that's calling us
* @param c the class to check
* @return whether an instance of c would be an instance of this class
* as well
* @throws NullPointerException if c is null
* @since 1.1
*/
static native boolean isAssignableFrom(Class klass, Class c);
/**
* Check whether this class is an interface or not. Array types are not
* interfaces.
*
* @param klass the Class object that's calling us
* @return whether this class is an interface or not
*/
static native boolean isInterface(Class klass);
/**
* Return whether this class is a primitive type. A primitive type class
* is a class representing a kind of "placeholder" for the various
* primitive types, or void. You can access the various primitive type
* classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc.,
* or through boolean.class, int.class, etc.
*
* @param klass the Class object that's calling us
* @return whether this class is a primitive type
* @see Boolean#TYPE
* @see Byte#TYPE
* @see Character#TYPE
* @see Short#TYPE
* @see Integer#TYPE
* @see Long#TYPE
* @see Float#TYPE
* @see Double#TYPE
* @see Void#TYPE
* @since 1.1
*/
static native boolean isPrimitive(Class klass);
/**
* Get the name of this class, separated by dots for package separators.
* Primitive types and arrays are encoded as:
* <pre>
* boolean Z
* byte B
* char C
* short S
* int I
* long J
* float F
* double D
* void V
* array type [<em>element type</em>
* class or interface, alone: &lt;dotted name&gt;
* class or interface, as element type: L&lt;dotted name&gt;;
*
* @param klass the Class object that's calling us
* @return the name of this class
*/
static native String getName(Class klass);
/**
* Get the direct superclass of this class. If this is an interface,
* Object, a primitive type, or void, it will return null. If this is an
* array type, it will return Object.
*
* @param klass the Class object that's calling us
* @return the direct superclass of this class
*/
static native Class getSuperclass(Class klass);
/**
* Get the interfaces this class <EM>directly</EM> implements, in the
* order that they were declared. This returns an empty array, not null,
* for Object, primitives, void, and classes or interfaces with no direct
* superinterface. Array types return Cloneable and Serializable.
*
* @param klass the Class object that's calling us
* @return the interfaces this class directly implements
*/
static native Class[] getInterfaces(Class klass);
/**
* If this is an array, get the Class representing the type of array.
* Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
* calling getComponentType on that would give "java.lang.String". If
* this is not an array, returns null.
*
* @param klass the Class object that's calling us
* @return the array type of this class, or null
* @see Array
* @since 1.1
*/
static native Class getComponentType(Class klass);
/**
* Get the modifiers of this class. These can be decoded using Modifier,
* and is limited to one of public, protected, or private, and any of
* final, static, abstract, or interface. An array class has the same
* public, protected, or private modifier as its component type, and is
* marked final but not an interface. Primitive types and void are marked
* public and final, but not an interface.
*
* @param klass the Class object that's calling us
* @param ignoreInnerClassesAttrib if set, return the real modifiers, not
* the ones specified in the InnerClasses attribute.
* @return the modifiers of this class
* @see Modifer
* @since 1.1
*/
static native int getModifiers(Class klass, boolean ignoreInnerClassesAttrib);
/**
* If this is a nested or inner class, return the class that declared it.
* If not, return null.
*
* @param klass the Class object that's calling us
* @return the declaring class of this class
* @since 1.1
*/
static native Class getDeclaringClass(Class klass);
/**
* Like <code>getDeclaredClasses()</code> but without the security checks.
*
* @param klass the Class object that's calling us
* @param pulicOnly Only public classes should be returned
*/
static native Class[] getDeclaredClasses(Class klass, boolean publicOnly);
/**
* Like <code>getDeclaredFields()</code> but without the security checks.
*
* @param klass the Class object that's calling us
* @param pulicOnly Only public fields should be returned
*/
static native Field[] getDeclaredFields(Class klass, boolean publicOnly);
/**
* Like <code>getDeclaredMethods()</code> but without the security checks.
*
* @param klass the Class object that's calling us
* @param pulicOnly Only public methods should be returned
*/
static native Method[] getDeclaredMethods(Class klass, boolean publicOnly);
/**
* Like <code>getDeclaredConstructors()</code> but without
* the security checks.
*
* @param klass the Class object that's calling us
* @param pulicOnly Only public constructors should be returned
*/
static native Constructor[] getDeclaredConstructors(Class klass, boolean publicOnly);
/**
* Return the class loader of this class.
*
* @param klass the Class object that's calling us
* @return the class loader
*/
static native ClassLoader getClassLoader(Class klass);
/**
* VM implementors are free to make this method a noop if
* the default implementation is acceptable.
*
* @param name the name of the class to find
* @return the Class object representing the class or null for noop
* @throws ClassNotFoundException if the class was not found by the
* classloader
* @throws LinkageError if linking the class fails
* @throws ExceptionInInitializerError if the class loads, but an exception
* occurs during initialization
*/
static native Class forName(String name) throws ClassNotFoundException;
/**
* Return whether this class is an array type.
*
* @param klass the Class object that's calling us
* @return true if this class is an array type
* operation
*/
static native boolean isArray(Class klass);
/**
* This method should trigger class initialization (if the
* class hasn't already been initialized)
*
* @param klass the Class object that's calling us
* @throws ExceptionInInitializerError if an exception
* occurs during initialization
*/
static native void initialize(Class klass);
/**
* Load an array class.
*
* @return the Class object representing the class
* @throws ClassNotFoundException if the class was not found by the
* classloader
*/
static native Class loadArrayClass(String name, ClassLoader classloader)
throws ClassNotFoundException;
/**
* Throw a checked exception without declaring it.
*/
static native void throwException(Throwable t);
} // class VMClass

View file

@ -0,0 +1,285 @@
/* VMClassLoader.java -- Reference implementation of native interface
required by ClassLoader
Copyright (C) 1998, 2001, 2002, 2004, 2005 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
import gnu.classpath.SystemProperties;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.zip.ZipFile;
/**
* java.lang.VMClassLoader is a package-private helper for VMs to implement
* on behalf of java.lang.ClassLoader.
*
* @author John Keiser
* @author Mark Wielaard (mark@klomp.org)
* @author Eric Blake (ebb9@email.byu.edu)
*/
final class VMClassLoader
{
/**
* Helper to define a class using a string of bytes. This assumes that
* the security checks have already been performed, if necessary.
*
* Implementations of this method are advised to consider the
* situation where user code modifies the byte array after it has
* been passed to defineClass. This can be handled by making a
* private copy of the array, or arranging to only read any given
* byte a single time.
*
* @param name the name to give the class, or null if unknown
* @param data the data representing the classfile, in classfile format
* @param offset the offset into the data where the classfile starts
* @param len the length of the classfile data in the array
* @param pd the protection domain
* @return the class that was defined
* @throws ClassFormatError if data is not in proper classfile format
*/
static final native Class defineClass(ClassLoader cl, String name,
byte[] data, int offset, int len,
ProtectionDomain pd)
throws ClassFormatError;
/**
* Helper to resolve all references to other classes from this class.
*
* @param c the class to resolve
*/
static final native void resolveClass(Class c);
/**
* Helper to load a class from the bootstrap class loader.
*
* @param name the class name to load
* @param resolve whether to resolve it
* @return the class, loaded by the bootstrap classloader or null
* if the class wasn't found. Returning null is equivalent to throwing
* a ClassNotFoundException (but a possible performance optimization).
*/
static final native Class loadClass(String name, boolean resolve)
throws ClassNotFoundException;
/**
* Helper to load a resource from the bootstrap class loader.
*
* @param name the resource to find
* @return the URL to the resource
*/
static URL getResource(String name)
{
Enumeration e = getResources(name);
if (e.hasMoreElements())
return (URL)e.nextElement();
return null;
}
/**
* Helper to get a list of resources from the bootstrap class loader.
*
* @param name the resource to find
* @return an enumeration of resources
* @throws IOException if one occurs
*/
static Enumeration getResources(String name)
{
StringTokenizer st = new StringTokenizer(
SystemProperties.getProperty("java.boot.class.path", "."),
File.pathSeparator);
Vector v = new Vector();
while (st.hasMoreTokens())
{
File file = new File(st.nextToken());
if (file.isDirectory())
{
try
{
v.add(new URL("file://"
+ new File(file, name).getAbsolutePath()));
}
catch (MalformedURLException e)
{
throw new Error(e);
}
}
else if (file.isFile())
{
ZipFile zip;
try
{
zip = new ZipFile(file);
}
catch (IOException e)
{
continue;
}
String zname = name.startsWith("/") ? name.substring(1) : name;
try
{
if (zip.getEntry(zname) == null)
continue;
}
finally
{
try
{
zip.close();
}
catch (IOException e)
{
}
}
try
{
v.add(new URL("jar:file://"
+ file.getAbsolutePath() + "!/" + zname));
}
catch (MalformedURLException e)
{
throw new Error(e);
}
}
}
return v.elements();
}
/**
* Helper to get a package from the bootstrap class loader. The default
* implementation of returning null may be adequate, or you may decide
* that this needs some native help.
*
* @param name the name to find
* @return the named package, if it exists
*/
static Package getPackage(String name)
{
return null;
}
/**
* Helper to get all packages from the bootstrap class loader. The default
* implementation of returning an empty array may be adequate, or you may
* decide that this needs some native help.
*
* @return all named packages, if any exist
*/
static Package[] getPackages()
{
return new Package[0];
}
/**
* Helper for java.lang.Integer, Byte, etc to get the TYPE class
* at initialization time. The type code is one of the chars that
* represents the primitive type as in JNI.
*
* <ul>
* <li>'Z' - boolean</li>
* <li>'B' - byte</li>
* <li>'C' - char</li>
* <li>'D' - double</li>
* <li>'F' - float</li>
* <li>'I' - int</li>
* <li>'J' - long</li>
* <li>'S' - short</li>
* <li>'V' - void</li>
* </ul>
*
* @param type the primitive type
* @return a "bogus" class representing the primitive type
*/
static final native Class getPrimitiveClass(char type);
/**
* The system default for assertion status. This is used for all system
* classes (those with a null ClassLoader), as well as the initial value for
* every ClassLoader's default assertion status.
*
* XXX - Not implemented yet; this requires native help.
*
* @return the system-wide default assertion status
*/
static final boolean defaultAssertionStatus()
{
return true;
}
/**
* The system default for package assertion status. This is used for all
* ClassLoader's packageAssertionStatus defaults. It must be a map of
* package names to Boolean.TRUE or Boolean.FALSE, with the unnamed package
* represented as a null key.
*
* XXX - Not implemented yet; this requires native help.
*
* @return a (read-only) map for the default packageAssertionStatus
*/
static final Map packageAssertionStatus()
{
return new HashMap();
}
/**
* The system default for class assertion status. This is used for all
* ClassLoader's classAssertionStatus defaults. It must be a map of
* class names to Boolean.TRUE or Boolean.FALSE
*
* XXX - Not implemented yet; this requires native help.
*
* @return a (read-only) map for the default classAssertionStatus
*/
static final Map classAssertionStatus()
{
return new HashMap();
}
static ClassLoader getSystemClassLoader()
{
return ClassLoader.defaultGetSystemClassLoader();
}
}

View file

@ -0,0 +1,112 @@
/* VMClassLoader.java -- Reference implementation of compiler interface
Copyright (C) 2004 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
/**
* This class is just a per-VM reflection of java.lang.Compiler.
* All methods are defined identically.
*/
final class VMCompiler
{
/**
* Don't allow new `Compiler's to be made.
*/
private VMCompiler()
{
}
/**
* Compile the class named by <code>oneClass</code>.
*
* @param oneClass the class to compile
* @return <code>false</code> if no compiler is available or
* compilation failed, <code>true</code> if compilation succeeded
* @throws NullPointerException if oneClass is null
*/
public static boolean compileClass(Class oneClass)
{
// Never succeed.
return false;
}
/**
* Compile the classes whose name matches <code>classNames</code>.
*
* @param classNames the name of classes to compile
* @return <code>false</code> if no compiler is available or
* compilation failed, <code>true</code> if compilation succeeded
* @throws NullPointerException if classNames is null
*/
public static boolean compileClasses(String classNames)
{
// Note the incredibly lame interface. Always fail.
return false;
}
/**
* This method examines the argument and performs an operation
* according to the compilers documentation. No specific operation
* is required.
*
* @param arg a compiler-specific argument
* @return a compiler-specific value, including null
* @throws NullPointerException if the compiler doesn't like a null arg
*/
public static Object command(Object arg)
{
// Our implementation defines this to a no-op.
return null;
}
/**
* Calling <code>Compiler.enable()</code> will cause the compiler
* to resume operation if it was previously disabled; provided that a
* compiler even exists.
*/
public static void enable()
{
}
/**
* Calling <code>Compiler.disable()</code> will cause the compiler
* to be suspended; provided that a compiler even exists.
*/
public static void disable()
{
}
}

View file

@ -0,0 +1,131 @@
/* VMDouble.java -- VM Specific Double methods
Copyright (C) 2003, 2005 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
import gnu.classpath.Configuration;
/*
* This class is a reference version, mainly for compiling a class library
* jar. It is likely that VM implementers replace this with their own
* version that can communicate effectively with the VM.
*/
/**
* Code relocated from java.lang.Double by
* @author Dave Grove (groved@us.ibm.com)
*/
final class VMDouble
{
/**
* Load native routines necessary for this class.
*/
static
{
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary("javalang");
}
initIDs();
}
/**
* Convert the double to the IEEE 754 floating-point "double format" bit
* layout. Bit 63 (the most significant) is the sign bit, bits 62-52
* (masked by 0x7ff0000000000000L) represent the exponent, and bits 51-0
* (masked by 0x000fffffffffffffL) are the mantissa. This function
* collapses all versions of NaN to 0x7ff8000000000000L. The result of this
* function can be used as the argument to
* <code>Double.longBitsToDouble(long)</code> to obtain the original
* <code>double</code> value.
*
* @param value the <code>double</code> to convert
* @return the bits of the <code>double</code>
* @see #longBitsToDouble(long)
*/
public static native long doubleToLongBits(double value);
/**
* Convert the double to the IEEE 754 floating-point "double format" bit
* layout. Bit 63 (the most significant) is the sign bit, bits 62-52
* (masked by 0x7ff0000000000000L) represent the exponent, and bits 51-0
* (masked by 0x000fffffffffffffL) are the mantissa. This function
* leaves NaN alone, rather than collapsing to a canonical value. The
* result of this function can be used as the argument to
* <code>Double.longBitsToDouble(long)</code> to obtain the original
* <code>double</code> value.
*
* @param value the <code>double</code> to convert
* @return the bits of the <code>double</code>
* @see #longBitsToDouble(long)
*/
public static native long doubleToRawLongBits(double value);
/**
* Convert the argument in IEEE 754 floating-point "double format" bit
* layout to the corresponding float. Bit 63 (the most significant) is the
* sign bit, bits 62-52 (masked by 0x7ff0000000000000L) represent the
* exponent, and bits 51-0 (masked by 0x000fffffffffffffL) are the mantissa.
* This function leaves NaN alone, so that you can recover the bit pattern
* with <code>Double.doubleToRawLongBits(double)</code>.
*
* @param bits the bits to convert
* @return the <code>double</code> represented by the bits
* @see #doubleToLongBits(double)
* @see #doubleToRawLongBits(double)
*/
public static native double longBitsToDouble(long bits);
/**
* Helper method to convert to string.
*
* @param d the double to convert
* @param isFloat true if the conversion is requested by Float (results in
* fewer digits)
*/
public static native String toString(double d, boolean isFloat);
/**
* Initialize JNI cache. This method is called only by the
* static initializer when using JNI.
*/
public static native void initIDs();
public static native double parseDouble(String str);
}

View file

@ -0,0 +1,111 @@
/* VMFloat.java -- VM Specific Float methods
Copyright (C) 2003 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
import gnu.classpath.Configuration;
/*
* This class is a reference version, mainly for compiling a class library
* jar. It is likely that VM implementers replace this with their own
* version that can communicate effectively with the VM.
*/
/**
* Code relocated from java.lang.Float by
* @author Dave Grove <groved@us.ibm.com>
*/
final class VMFloat
{
/**
* Load native routines necessary for this class.
*/
static
{
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary("javalang");
}
}
/**
* Convert the float to the IEEE 754 floating-point "single format" bit
* layout. Bit 31 (the most significant) is the sign bit, bits 30-23
* (masked by 0x7f800000) represent the exponent, and bits 22-0
* (masked by 0x007fffff) are the mantissa. This function collapses all
* versions of NaN to 0x7fc00000. The result of this function can be used
* as the argument to <code>Float.intBitsToFloat(int)</code> to obtain the
* original <code>float</code> value.
*
* @param value the <code>float</code> to convert
* @return the bits of the <code>float</code>
* @see #intBitsToFloat(int)
*/
static native int floatToIntBits(float value);
/**
* Convert the float to the IEEE 754 floating-point "single format" bit
* layout. Bit 31 (the most significant) is the sign bit, bits 30-23
* (masked by 0x7f800000) represent the exponent, and bits 22-0
* (masked by 0x007fffff) are the mantissa. This function leaves NaN alone,
* rather than collapsing to a canonical value. The result of this function
* can be used as the argument to <code>Float.intBitsToFloat(int)</code> to
* obtain the original <code>float</code> value.
*
* @param value the <code>float</code> to convert
* @return the bits of the <code>float</code>
* @see #intBitsToFloat(int)
*/
static native int floatToRawIntBits(float value);
/**
* Convert the argument in IEEE 754 floating-point "single format" bit
* layout to the corresponding float. Bit 31 (the most significant) is the
* sign bit, bits 30-23 (masked by 0x7f800000) represent the exponent, and
* bits 22-0 (masked by 0x007fffff) are the mantissa. This function leaves
* NaN alone, so that you can recover the bit pattern with
* <code>Float.floatToRawIntBits(float)</code>.
*
* @param bits the bits to convert
* @return the <code>float</code> represented by the bits
* @see #floatToIntBits(float)
* @see #floatToRawIntBits(float)
*/
static native float intBitsToFloat(int bits);
} // class VMFloat

View file

@ -0,0 +1,105 @@
/* VMObject.java -- Reference implementation for VM hooks used by Object
Copyright (C) 1998, 2002, 2005 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
/**
* Object is the ultimate superclass of every class (excepting interfaces).
* As such, it needs help from the VM.
*
* @author John Keiser
* @author Eric Blake (ebb9@email.byu.edu)
*/
final class VMObject
{
/**
* Returns the runtime {@link Class} of a given Object.
*
* @param obj the object to return the class for.
*
* @return the class of the Object.
*/
static native Class getClass(Object obj);
/**
* The VM is expected to make a field-for-field shallow copy of the
* argument. Thus, the copy has the same runtime type as the argument.
* Note, however, that the cloned object must still be finalizable, even
* if the original has already had finalize() invoked on it.
*
* @param c the Cloneable to clone
* @return the clone
*/
static native Object clone(Cloneable c);
/**
* Wakes up one of the threads that is waiting on this Object's monitor.
* Only the owner of a lock on the Object may call this method. The Thread
* to wake up is chosen arbitrarily.
*
* @param o the object doing the notify
* @throw IllegalMonitorStateException if this Thread does not own the
* lock on the Object
*/
static native void notify(Object o) throws IllegalMonitorStateException;
/**
* Wakes up all of the threads waiting on this Object's monitor. Only
* the owner of the lock on this Object may call this method.
*
* @param o the object doing the notifyAll
* @throws IllegalMonitorStateException if this Thread does not own the
* lock on the Object
*/
static native void notifyAll(Object o) throws IllegalMonitorStateException;
/**
* Waits a specified amount of time for notify() or notifyAll() to be
* called on this Object. The VM does not have to pay attention to the
* ns argument, if it does not have that much granularity.
*
* @param o the object to suspend on
* @param ms milliseconds to wait (1,000 milliseconds = 1 second)
* @param ns nanoseconds to wait beyond ms (1,000,000 nanoseconds
* == 1 millisecond)
* @throws IllegalMonitorStateException if this Thread does not own the
* lock on the Object
* @throws InterruptedException if some other Thread interrupts this Thread
*/
static native void wait(Object o, long ms, int ns)
throws IllegalMonitorStateException, InterruptedException;
}

View file

@ -0,0 +1,368 @@
/* java.lang.VMProcess -- VM implementation of java.lang.Process
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.LinkedList;
/**
* Represents one external process. Each instance of this class is in
* one of three states: INITIAL, RUNNING, or TERMINATED. The instance
* is {@link Object#notifyAll notifyAll()}'d each time the state changes.
* The state of all instances is managed by a single dedicated thread
* which does the actual fork()/exec() and wait() system calls. User
* threads {@link Object#wait wait()} on the instance when creating the
* process or waiting for it to terminate.
*
* <p>
* See
* <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11801">GCC bug
* #11801</a> for the motivation behind the design of this class.
*
* @author Archie Cobbs
* @see Process
* @see Runtime#exec
*/
final class VMProcess extends Process
{
// Possible states for a VMProcess
private static final int INITIAL = 0;
private static final int RUNNING = 1;
private static final int TERMINATED = 2;
// Dedicated thread that does all the fork()'ing and wait()'ing.
static Thread processThread;
// New processes waiting to be spawned by processThread.
static final LinkedList workList = new LinkedList();
// Return values set by nativeReap() when a child is reaped.
// These are only accessed by processThread so no locking required.
static long reapedPid;
static int reapedExitValue;
// Information about this process
int state; // current state of process
final String[] cmd; // copied from Runtime.exec()
final String[] env; // copied from Runtime.exec()
final File dir; // copied from Runtime.exec()
Throwable exception; // if process failed to start
long pid; // process id
OutputStream stdin; // process input stream
InputStream stdout; // process output stream
InputStream stderr; // process error stream
int exitValue; // process exit value
//
// Dedicated thread that does all the fork()'ing and wait()'ing
// for external processes. This is needed because some systems like
// Linux use a process-per-thread model, which means the same thread
// that did the fork()/exec() must also do the wait().
//
private static class ProcessThread extends Thread
{
// Max time (in ms) we'll delay before trying to reap another child.
private static final int MAX_REAP_DELAY = 1000;
// Processes created but not yet terminated; maps Long(pid) -> VMProcess
// Only used in run() and spawn() method from this Thread, so no locking.
private final HashMap activeMap = new HashMap();
// We have an explicit constructor, because the default
// constructor will be private, which means the compiler will have
// to generate a second package-private constructor, which is
// bogus.
ProcessThread ()
{
}
public void run()
{
final LinkedList workList = VMProcess.workList;
while (true)
{
// Get the next process to spawn (if any) and spawn it. Spawn
// at most one at a time before checking for reapable children.
VMProcess process = null;
synchronized (workList)
{
if (!workList.isEmpty())
process = (VMProcess)workList.removeFirst();
}
if (process != null)
spawn(process);
// Check for termination of active child processes
while (!activeMap.isEmpty() && VMProcess.nativeReap())
{
long pid = VMProcess.reapedPid;
int exitValue = VMProcess.reapedExitValue;
process = (VMProcess)activeMap.remove(new Long(pid));
if (process != null)
{
synchronized (process)
{
process.exitValue = exitValue;
process.state = TERMINATED;
process.notify();
}
}
else
System.err.println("VMProcess WARNING reaped unknown process: "
+ pid);
}
// If there are more new processes to create, go do that now.
// If there is nothing left to do, exit this thread. Otherwise,
// sleep a little while, and then check again for reapable children.
// We will get woken up immediately if there are new processes to
// spawn, but not if there are new children to reap. So we only
// sleep a short time, in effect polling while processes are active.
synchronized (workList)
{
if (!workList.isEmpty())
continue;
if (activeMap.isEmpty())
{
processThread = null;
break;
}
try
{
workList.wait(MAX_REAP_DELAY);
}
catch (InterruptedException e)
{
/* ignore */
}
}
}
}
// Spawn a process
private void spawn(VMProcess process)
{
// Spawn the process and put it in our active map indexed by pid.
// If the spawn operation fails, store the exception with the process.
// In either case, wake up thread that created the process.
synchronized (process)
{
try
{
process.nativeSpawn(process.cmd, process.env, process.dir);
process.state = RUNNING;
activeMap.put(new Long(process.pid), process);
}
catch (ThreadDeath death)
{
throw death;
}
catch (Throwable t)
{
process.state = TERMINATED;
process.exception = t;
}
process.notify();
}
}
}
// Constructor
private VMProcess(String[] cmd, String[] env, File dir) throws IOException
{
// Initialize this process
this.state = INITIAL;
this.cmd = cmd;
this.env = env;
this.dir = dir;
// Add process to the new process work list and wakeup processThread
synchronized (workList)
{
workList.add(this);
if (processThread == null)
{
processThread = new ProcessThread();
processThread.setDaemon(true);
processThread.start();
}
else
{
workList.notify();
}
}
// Wait for processThread to spawn this process and update its state
synchronized (this)
{
while (state == INITIAL)
{
try
{
wait();
}
catch (InterruptedException e)
{
/* ignore */
}
}
}
// If spawning failed, rethrow the exception in this thread
if (exception != null)
{
exception.fillInStackTrace();
if (exception instanceof IOException)
throw (IOException)exception;
if (exception instanceof Error)
throw (Error)exception;
if (exception instanceof RuntimeException)
throw (RuntimeException)exception;
throw new RuntimeException(exception);
}
}
// Invoked by native code (from nativeSpawn()) to record process info.
private void setProcessInfo(OutputStream stdin,
InputStream stdout, InputStream stderr, long pid)
{
this.stdin = stdin;
this.stdout = stdout;
this.stderr = stderr;
this.pid = pid;
}
/**
* Entry point from Runtime.exec().
*/
static Process exec(String[] cmd, String[] env, File dir) throws IOException
{
return new VMProcess(cmd, env, dir);
}
public OutputStream getOutputStream()
{
return stdin;
}
public InputStream getInputStream()
{
return stdout;
}
public InputStream getErrorStream()
{
return stderr;
}
public synchronized int waitFor() throws InterruptedException
{
while (state != TERMINATED)
wait();
return exitValue;
}
public synchronized int exitValue()
{
if (state != TERMINATED)
throw new IllegalThreadStateException();
return exitValue;
}
public synchronized void destroy()
{
if (state == TERMINATED)
return;
nativeKill(pid);
while (state != TERMINATED)
{
try
{
wait();
}
catch (InterruptedException e)
{
/* ignore */
}
}
}
/**
* Does the fork()/exec() thing to create the O/S process.
* Must invoke setProcessInfo() before returning successfully.
* This method is only invoked by processThread.
*
* @throws IOException if the O/S process could not be created.
*/
native void nativeSpawn(String[] cmd, String[] env, File dir)
throws IOException;
/**
* Test for a reapable child process, and reap if so. Does not block.
* If a child was reaped, this method must set reapedPid and
* reapedExitValue appropriately before returning.
* This method is only invoked by processThread.
*
* @return true if a child was reaped, otherwise false
*/
// This is not private as it is called from an inner class.
static native boolean nativeReap();
/**
* Kill a process. This sends it a fatal signal but does not reap it.
*/
private static native void nativeKill(long pid);
}

View file

@ -0,0 +1,192 @@
/* VMRuntime.java -- VM interface to Runtime
Copyright (C) 2003 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
import java.io.File;
import java.io.IOException;
/**
* VMRuntime represents the interface to the Virtual Machine.
*
* @author Jeroen Frijters
*/
final class VMRuntime
{
/**
* No instance is ever created.
*/
private VMRuntime()
{
}
/**
* Returns the number of available processors currently available to the
* virtual machine. This number may change over time; so a multi-processor
* program want to poll this to determine maximal resource usage.
*
* @return the number of processors available, at least 1
*/
static native int availableProcessors();
/**
* Find out how much memory is still free for allocating Objects on the heap.
*
* @return the number of bytes of free memory for more Objects
*/
static native long freeMemory();
/**
* Find out how much memory total is available on the heap for allocating
* Objects.
*
* @return the total number of bytes of memory for Objects
*/
static native long totalMemory();
/**
* Returns the maximum amount of memory the virtual machine can attempt to
* use. This may be <code>Long.MAX_VALUE</code> if there is no inherent
* limit (or if you really do have a 8 exabyte memory!).
*
* @return the maximum number of bytes the virtual machine will attempt
* to allocate
*/
static native long maxMemory();
/**
* Run the garbage collector. This method is more of a suggestion than
* anything. All this method guarantees is that the garbage collector will
* have "done its best" by the time it returns. Notice that garbage
* collection takes place even without calling this method.
*/
static native void gc();
/**
* Run finalization on all Objects that are waiting to be finalized. Again,
* a suggestion, though a stronger one than {@link #gc()}. This calls the
* <code>finalize</code> method of all objects waiting to be collected.
*
* @see #finalize()
*/
static native void runFinalization();
/**
* Run finalization on all finalizable Objects (even live ones). This
* should only be called immediately prior to VM termination.
*
* @see #finalize()
*/
static native void runFinalizationForExit();
/**
* Tell the VM to trace every bytecode instruction that executes (print out
* a trace of it). No guarantees are made as to where it will be printed,
* and the VM is allowed to ignore this request.
*
* @param on whether to turn instruction tracing on
*/
static native void traceInstructions(boolean on);
/**
* Tell the VM to trace every method call that executes (print out a trace
* of it). No guarantees are made as to where it will be printed, and the
* VM is allowed to ignore this request.
*
* @param on whether to turn method tracing on
*/
static native void traceMethodCalls(boolean on);
/**
* Native method that actually sets the finalizer setting.
*
* @param value whether to run finalizers on exit
*/
static native void runFinalizersOnExit(boolean value);
/**
* Native method that actually shuts down the virtual machine.
*
* @param status the status to end the process with
*/
static native void exit(int status);
/**
* Load a file. If it has already been loaded, do nothing. The name has
* already been mapped to a true filename.
*
* @param filename the file to load
* @param loader class loader, or <code>null</code> for the boot loader
* @return 0 on failure, nonzero on success
*/
static native int nativeLoad(String filename, ClassLoader loader);
/**
* Map a system-independent "short name" to the full file name.
*
* @param libname the short version of the library name
* @return the full filename
*/
static native String mapLibraryName(String libname);
/**
* Execute a process. The command line has already been tokenized, and
* the environment should contain name=value mappings. If directory is null,
* use the current working directory; otherwise start the process in that
* directory. If env is null, then the new process should inherit
* the environment of this process.
*
* @param cmd the non-null command tokens
* @param env the environment setup
* @param dir the directory to use, may be null
* @return the newly created process
* @throws NullPointerException if cmd or env have null elements
*/
static Process exec(String[] cmd, String[] env, File dir)
throws IOException {
return VMProcess.exec(cmd, env, dir);
}
/**
* This method is called by Runtime.addShutdownHook() when it is
* called for the first time. It enables the VM to lazily setup
* an exit handler, should it so desire.
*/
static void enableShutdownHooks()
{
}
} // class VMRuntime

View file

@ -0,0 +1,91 @@
/* VMString.java -- VM Specific String methods
Copyright (C) 2003 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
/*
* This class is a reference version, mainly for compiling a class library
* jar. It is likely that VM implementers replace this with their own
* version that can communicate effectively with the VM.
*/
/**
* Code relocated from java.lang.String by
* @author Dave Grove <groved@us.ibm.com>
*/
final class VMString
{
/**
* Holds the references for each intern()'d String. If all references to
* the string disappear, and the VM properly supports weak references,
* the String will be GC'd.
*/
private static final WeakHashMap internTable = new WeakHashMap();
/**
* Fetches this String from the intern hashtable. If two Strings are
* considered equal, by the equals() method, then intern() will return the
* same String instance. ie. if (s1.equals(s2)) then
* (s1.intern() == s2.intern()). All string literals and string-valued
* constant expressions are already interned.
*
* @param str the String to intern
* @return the interned String
*/
static String intern(String str)
{
synchronized (internTable)
{
WeakReference ref = (WeakReference) internTable.get(str);
if (ref != null)
{
String s = (String) ref.get();
// If s is null, then no strong references exist to the String;
// the weak hash map will soon delete the key.
if (s != null)
return s;
}
internTable.put(str, new WeakReference(str));
}
return str;
}
} // class VMString

View file

@ -0,0 +1,181 @@
/* VMSystem.java -- helper for java.lang.system
Copyright (C) 1998, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
/**
* VMSystem is a package-private helper class for System that the
* VM must implement.
*
* @author John Keiser
*/
final class VMSystem
{
/**
* Copy one array onto another from <code>src[srcStart]</code> ...
* <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ...
* <code>dest[destStart+len-1]</code>. First, the arguments are validated:
* neither array may be null, they must be of compatible types, and the
* start and length must fit within both arrays. Then the copying starts,
* and proceeds through increasing slots. If src and dest are the same
* array, this will appear to copy the data to a temporary location first.
* An ArrayStoreException in the middle of copying will leave earlier
* elements copied, but later elements unchanged.
*
* @param src the array to copy elements from
* @param srcStart the starting position in src
* @param dest the array to copy elements to
* @param destStart the starting position in dest
* @param len the number of elements to copy
* @throws NullPointerException if src or dest is null
* @throws ArrayStoreException if src or dest is not an array, if they are
* not compatible array types, or if an incompatible runtime type
* is stored in dest
* @throws IndexOutOfBoundsException if len is negative, or if the start or
* end copy position in either array is out of bounds
*/
static native void arraycopy(Object src, int srcStart,
Object dest, int destStart, int len);
/**
* Get a hash code computed by the VM for the Object. This hash code will
* be the same as Object's hashCode() method. It is usually some
* convolution of the pointer to the Object internal to the VM. It
* follows standard hash code rules, in that it will remain the same for a
* given Object for the lifetime of that Object.
*
* @param o the Object to get the hash code for
* @return the VM-dependent hash code for this Object
*/
static native int identityHashCode(Object o);
/**
* Convert a library name to its platform-specific variant.
*
* @param libname the library name, as used in <code>loadLibrary</code>
* @return the platform-specific mangling of the name
* @XXX Add this method
static native String mapLibraryName(String libname);
*/
/**
* Set {@link #in} to a new InputStream.
*
* @param in the new InputStream
* @see #setIn(InputStream)
*/
static native void setIn(InputStream in);
/**
* Set {@link #out} to a new PrintStream.
*
* @param out the new PrintStream
* @see #setOut(PrintStream)
*/
static native void setOut(PrintStream out);
/**
* Set {@link #err} to a new PrintStream.
*
* @param err the new PrintStream
* @see #setErr(PrintStream)
*/
static native void setErr(PrintStream err);
/**
* Get the current time, measured in the number of milliseconds from the
* beginning of Jan. 1, 1970. This is gathered from the system clock, with
* any attendant incorrectness (it may be timezone dependent).
*
* @return the current time
* @see java.util.Date
*/
public static native long currentTimeMillis();
/**
* Helper method which creates the standard input stream.
* VM implementors may choose to construct these streams differently.
* This method can also return null if the stream is created somewhere
* else in the VM startup sequence.
*/
static InputStream makeStandardInputStream()
{
return new BufferedInputStream(new FileInputStream(FileDescriptor.in));
}
/**
* Helper method which creates the standard output stream.
* VM implementors may choose to construct these streams differently.
* This method can also return null if the stream is created somewhere
* else in the VM startup sequence.
*/
static PrintStream makeStandardOutputStream()
{
return new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true);
}
/**
* Helper method which creates the standard error stream.
* VM implementors may choose to construct these streams differently.
* This method can also return null if the stream is created somewhere
* else in the VM startup sequence.
*/
static PrintStream makeStandardErrorStream()
{
return new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err)), true);
}
/**
* Gets the value of an environment variable.
* Always returning null is a valid (but not very useful) implementation.
*
* @param name The name of the environment variable (will not be null).
* @return The string value of the variable or null when the
* environment variable is not defined.
*/
static native String getenv(String name);
}

View file

@ -0,0 +1,450 @@
/* VMThread -- VM interface for Thread of executable code
Copyright (C) 2003, 2004, 2005 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
/**
* VM interface for Thread of executable code. Holds VM dependent state.
* It is deliberately package local and final and should only be accessed
* by the Thread class.
* <p>
* This is the GNU Classpath reference implementation, it should be adapted
* for a specific VM.
* <p>
* The following methods must be implemented:
* <ul>
* <li>native void start(long stacksize);
* <li>native void interrupt();
* <li>native boolean isInterrupted();
* <li>native void suspend();
* <li>native void resume();
* <li>native void nativeSetPriority(int priority);
* <li>native void nativeStop(Throwable t);
* <li>native static Thread currentThread();
* <li>static native void yield();
* <li>static native boolean interrupted();
* </ul>
* All other methods may be implemented to make Thread handling more efficient
* or to implement some optional (and sometimes deprecated) behaviour. Default
* implementations are provided but it is highly recommended to optimize them
* for a specific VM.
*
* @author Jeroen Frijters (jeroen@frijters.net)
* @author Dalibor Topic (robilad@kaffe.org)
*/
final class VMThread
{
/**
* The Thread object that this VM state belongs to.
* Used in currentThread() and start().
* Note: when this thread dies, this reference is *not* cleared
*/
volatile Thread thread;
/**
* Flag that is set when the thread runs, used by stop() to protect against
* stop's getting lost.
*/
private volatile boolean running;
/**
* VM private data.
*/
private transient Object vmdata;
/**
* Private constructor, create VMThreads with the static create method.
*
* @param thread The Thread object that was just created.
*/
private VMThread(Thread thread)
{
this.thread = thread;
}
/**
* This method is the initial Java code that gets executed when a native
* thread starts. It's job is to coordinate with the rest of the VMThread
* logic and to start executing user code and afterwards handle clean up.
*/
private void run()
{
try
{
try
{
running = true;
synchronized(thread)
{
Throwable t = thread.stillborn;
if(t != null)
{
thread.stillborn = null;
throw t;
}
}
thread.run();
}
catch(Throwable t)
{
try
{
thread.group.uncaughtException(thread, t);
}
catch(Throwable ignore)
{
}
}
}
finally
{
// Setting runnable to false is partial protection against stop
// being called while we're cleaning up. To be safe all code in
// VMThread be unstoppable.
running = false;
thread.die();
synchronized(this)
{
// release the threads waiting to join us
notifyAll();
}
}
}
/**
* Creates a native Thread. This is called from the start method of Thread.
* The Thread is started.
*
* @param thread The newly created Thread object
* @param stacksize Indicates the requested stacksize. Normally zero,
* non-zero values indicate requested stack size in bytes but it is up
* to the specific VM implementation to interpret them and may be ignored.
*/
static void create(Thread thread, long stacksize)
{
VMThread vmThread = new VMThread(thread);
vmThread.start(stacksize);
thread.vmThread = vmThread;
}
/**
* Gets the name of the thread. Usually this is the name field of the
* associated Thread object, but some implementation might choose to
* return the name of the underlying platform thread.
*/
String getName()
{
return thread.name;
}
/**
* Set the name of the thread. Usually this sets the name field of the
* associated Thread object, but some implementations might choose to
* set the name of the underlying platform thread.
* @param name The new name
*/
void setName(String name)
{
thread.name = name;
}
/**
* Set the thread priority field in the associated Thread object and
* calls the native method to set the priority of the underlying
* platform thread.
* @param priority The new priority
*/
void setPriority(int priority)
{
thread.priority = priority;
nativeSetPriority(priority);
}
/**
* Returns the priority. Usually this is the priority field from the
* associated Thread object, but some implementation might choose to
* return the priority of the underlying platform thread.
* @return this Thread's priority
*/
int getPriority()
{
return thread.priority;
}
/**
* Returns true if the thread is a daemon thread. Usually this is the
* daemon field from the associated Thread object, but some
* implementation might choose to return the daemon state of the underlying
* platform thread.
* @return whether this is a daemon Thread or not
*/
boolean isDaemon()
{
return thread.daemon;
}
/**
* Returns the number of stack frames in this Thread.
* Will only be called when when a previous call to suspend() returned true.
*
* @deprecated unsafe operation
*/
native int countStackFrames();
/**
* Wait the specified amount of time for the Thread in question to die.
*
* <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
* not offer that fine a grain of timing resolution. Besides, there is
* no guarantee that this thread can start up immediately when time expires,
* because some other thread may be active. So don't expect real-time
* performance.
*
* @param ms the number of milliseconds to wait, or 0 for forever
* @param ns the number of extra nanoseconds to sleep (0-999999)
* @throws InterruptedException if the Thread is interrupted; it's
* <i>interrupted status</i> will be cleared
*/
synchronized void join(long ms, int ns) throws InterruptedException
{
// Round up
ms += (ns != 0) ? 1 : 0;
// Compute end time, but don't overflow
long now = System.currentTimeMillis();
long end = now + ms;
if (end < now)
end = Long.MAX_VALUE;
// A VM is allowed to return from wait() without notify() having been
// called, so we loop to handle possible spurious wakeups.
while(thread.vmThread != null)
{
// We use the VMThread object to wait on, because this is a private
// object, so client code cannot call notify on us.
wait(ms);
if(ms != 0)
{
now = System.currentTimeMillis();
ms = end - now;
if(ms <= 0)
{
break;
}
}
}
}
/**
* Cause this Thread to stop abnormally and throw the specified exception.
* If you stop a Thread that has not yet started, the stop is ignored
* (contrary to what the JDK documentation says).
* <b>WARNING</b>This bypasses Java security, and can throw a checked
* exception which the call stack is unprepared to handle. Do not abuse
* this power.
*
* <p>This is inherently unsafe, as it can interrupt synchronized blocks and
* leave data in bad states.
*
* <p><b>NOTE</b> stop() should take care not to stop a thread if it is
* executing code in this class.
*
* @param t the Throwable to throw when the Thread dies
* @deprecated unsafe operation, try not to use
*/
void stop(Throwable t)
{
// Note: we assume that we own the lock on thread
// (i.e. that Thread.stop() is synchronized)
if(running)
nativeStop(t);
else
thread.stillborn = t;
}
/**
* Create a native thread on the underlying platform and start it executing
* on the run method of this object.
* @param stacksize the requested size of the native thread stack
*/
native void start(long stacksize);
/**
* Interrupt this thread.
*/
native void interrupt();
/**
* Determine whether this Thread has been interrupted, but leave
* the <i>interrupted status</i> alone in the process.
*
* @return whether the Thread has been interrupted
*/
native boolean isInterrupted();
/**
* Suspend this Thread. It will not come back, ever, unless it is resumed.
*/
native void suspend();
/**
* Resume this Thread. If the thread is not suspended, this method does
* nothing.
*/
native void resume();
/**
* Set the priority of the underlying platform thread.
*
* @param priority the new priority
*/
native void nativeSetPriority(int priority);
/**
* Asynchronously throw the specified throwable in this Thread.
*
* @param t the exception to throw
*/
native void nativeStop(Throwable t);
/**
* Return the Thread object associated with the currently executing
* thread.
*
* @return the currently executing Thread
*/
static native Thread currentThread();
/**
* Yield to another thread. The Thread will not lose any locks it holds
* during this time. There are no guarantees which thread will be
* next to run, and it could even be this one, but most VMs will choose
* the highest priority thread that has been waiting longest.
*/
static native void yield();
/**
* Suspend the current Thread's execution for the specified amount of
* time. The Thread will not lose any locks it has during this time. There
* are no guarantees which thread will be next to run, but most VMs will
* choose the highest priority thread that has been waiting longest.
*
* <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
* not offer that fine a grain of timing resolution. Besides, there is
* no guarantee that this thread can start up immediately when time expires,
* because some other thread may be active. So don't expect real-time
* performance.
*
* @param ms the number of milliseconds to sleep.
* @param ns the number of extra nanoseconds to sleep (0-999999)
* @throws InterruptedException if the Thread is (or was) interrupted;
* it's <i>interrupted status</i> will be cleared
*/
static void sleep(long ms, int ns) throws InterruptedException
{
// Round up
ms += (ns != 0) ? 1 : 0;
// Note: JDK treats a zero length sleep is like Thread.yield(),
// without checking the interrupted status of the thread.
// It's unclear if this is a bug in the implementation or the spec.
// See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203
if (ms == 0)
{
if (Thread.interrupted())
throw new InterruptedException();
return;
}
// Compute end time, but don't overflow
long now = System.currentTimeMillis();
long end = now + ms;
if (end < now)
end = Long.MAX_VALUE;
// A VM is allowed to return from wait() without notify() having been
// called, so we loop to handle possible spurious wakeups.
VMThread vt = Thread.currentThread().vmThread;
synchronized (vt)
{
while (true)
{
vt.wait(ms);
now = System.currentTimeMillis();
if (now >= end)
break;
ms = end - now;
}
}
}
/**
* Determine whether the current Thread has been interrupted, and clear
* the <i>interrupted status</i> in the process.
*
* @return whether the current Thread has been interrupted
*/
static native boolean interrupted();
/**
* Checks whether the current thread holds the monitor on a given object.
* This allows you to do <code>assert Thread.holdsLock(obj)</code>.
*
* @param obj the object to check
* @return true if the current thread is currently synchronized on obj
* @throws NullPointerException if obj is null
*/
static boolean holdsLock(Object obj)
{
/* Use obj.notify to check if the current thread holds
* the monitor of the object.
* If it doesn't, notify will throw an exception.
*/
try
{
obj.notify();
// okay, current thread holds lock
return true;
}
catch (IllegalMonitorStateException e)
{
// it doesn't hold the lock
return false;
}
}
}

View file

@ -0,0 +1,82 @@
/* java.lang.VMThrowable -- VM support methods for Throwable.
Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
/**
* VM dependant state and support methods for Throwable.
* It is deliberately package local and final and should only be accessed
* by the Throwable class.
* <p>
* This is the GNU Classpath reference implementation, it should be adapted
* for a specific VM. The reference implementation does nothing.
*
* @author Mark Wielaard (mark@klomp.org)
*/
final class VMThrowable
{
/**
* VM private data.
*/
private transient Object vmdata;
/**
* Private contructor, create VMThrowables with fillInStackTrace();
*/
private VMThrowable() { }
/**
* Fill in the stack trace with the current execution stack.
* Called by <code>Throwable.fillInStackTrace()</code> to get the state of
* the VM. Can return null when the VM does not support caputing the VM
* execution state.
*
* @return a new VMThrowable containing the current execution stack trace.
* @see Throwable#fillInStackTrace()
*/
static native VMThrowable fillInStackTrace(Throwable t);
/**
* Returns an <code>StackTraceElement</code> array based on the execution
* state of the VM as captured by <code>fillInStackTrace</code>.
* Called by <code>Throwable.getStackTrace()</code>.
*
* @return a non-null but possible zero length array of StackTraceElement.
* @see Throwable#getStackTrace()
*/
native StackTraceElement[] getStackTrace(Throwable t);
}

View file

@ -0,0 +1,249 @@
/* java.lang.reflect.Constructor - reflection of Java constructors
Copyright (C) 1998, 2001 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang.reflect;
import java.util.Arrays;
/**
* The Constructor class represents a constructor of a class. It also allows
* dynamic creation of an object, via reflection. Invocation on Constructor
* objects knows how to do widening conversions, but throws
* {@link IllegalArgumentException} if a narrowing conversion would be
* necessary. You can query for information on this Constructor regardless
* of location, but construction access may be limited by Java language
* access controls. If you can't do it in the compiler, you can't normally
* do it here either.<p>
*
* <B>Note:</B> This class returns and accepts types as Classes, even
* primitive types; there are Class types defined that represent each
* different primitive type. They are <code>java.lang.Boolean.TYPE,
* java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
* byte.class</code>, etc. These are not to be confused with the
* classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
* real classes.<p>
*
* Also note that this is not a serializable class. It is entirely feasible
* to make it serializable using the Externalizable interface, but this is
* on Sun, not me.
*
* @author John Keiser
* @author Eric Blake <ebb9@email.byu.edu>
* @see Member
* @see Class
* @see java.lang.Class#getConstructor(Object[])
* @see java.lang.Class#getDeclaredConstructor(Object[])
* @see java.lang.Class#getConstructors()
* @see java.lang.Class#getDeclaredConstructors()
* @since 1.1
* @status updated to 1.4
*/
public final class Constructor
extends AccessibleObject implements Member
{
private Class clazz;
private int slot;
/**
* This class is uninstantiable except from native code.
*/
private Constructor(Class declaringClass,int slot)
{
this.clazz = declaringClass;
this.slot = slot;
}
private Constructor()
{
}
/**
* Gets the class that declared this constructor.
* @return the class that declared this member
*/
public Class getDeclaringClass()
{
return clazz;
}
/**
* Gets the name of this constructor (the non-qualified name of the class
* it was declared in).
* @return the name of this constructor
*/
public String getName()
{
return getDeclaringClass().getName();
}
/**
* Gets the modifiers this constructor uses. Use the <code>Modifier</code>
* class to interpret the values. A constructor can only have a subset of the
* following modifiers: public, private, protected.
*
* @return an integer representing the modifiers to this Member
* @see Modifier
*/
public native int getModifiers();
/**
* Get the parameter list for this constructor, in declaration order. If the
* constructor takes no parameters, returns a 0-length array (not null).
*
* @return a list of the types of the constructor's parameters
*/
public native Class[] getParameterTypes();
/**
* Get the exception types this constructor says it throws, in no particular
* order. If the constructor has no throws clause, returns a 0-length array
* (not null).
*
* @return a list of the types in the constructor's throws clause
*/
public native Class[] getExceptionTypes();
/**
* Compare two objects to see if they are semantically equivalent.
* Two Constructors are semantically equivalent if they have the same
* declaring class and the same parameter list. This ignores different
* exception clauses, but since you can't create a Method except through the
* VM, this is just the == relation.
*
* @param o the object to compare to
* @return <code>true</code> if they are equal; <code>false</code> if not.
*/
public boolean equals(Object o)
{
if (!(o instanceof Constructor))
return false;
Constructor that = (Constructor)o;
if (this.getDeclaringClass() != that.getDeclaringClass())
return false;
if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
return false;
return true;
}
/**
* Get the hash code for the Constructor. The Constructor hash code is the
* hash code of the declaring class's name.
*
* @return the hash code for the object
*/
public int hashCode()
{
return getDeclaringClass().getName().hashCode();
}
/**
* Get a String representation of the Constructor. A Constructor's String
* representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
* throws &lt;exceptions&gt;", where everything after ')' is omitted if
* there are no exceptions.<br> Example:
* <code>public java.io.FileInputStream(java.lang.Runnable)
* throws java.io.FileNotFoundException</code>
*
* @return the String representation of the Constructor
*/
public String toString()
{
// 128 is a reasonable buffer initial size for constructor
StringBuffer sb = new StringBuffer(128);
Modifier.toString(getModifiers(), sb).append(' ');
sb.append(getDeclaringClass().getName()).append('(');
Class[] c = getParameterTypes();
if (c.length > 0)
{
sb.append(c[0].getName());
for (int i = 1; i < c.length; i++)
sb.append(',').append(c[i].getName());
}
sb.append(')');
c = getExceptionTypes();
if (c.length > 0)
{
sb.append(" throws ").append(c[0].getName());
for (int i = 1; i < c.length; i++)
sb.append(',').append(c[i].getName());
}
return sb.toString();
}
/**
* Create a new instance by invoking the constructor. Arguments are
* automatically unwrapped and widened, if needed.<p>
*
* If this class is abstract, you will get an
* <code>InstantiationException</code>. If the constructor takes 0
* arguments, you may use null or a 0-length array for <code>args</code>.<p>
*
* If this Constructor enforces access control, your runtime context is
* evaluated, and you may have an <code>IllegalAccessException</code> if
* you could not create this object in similar compiled code. If the class
* is uninitialized, you trigger class initialization, which may end in a
* <code>ExceptionInInitializerError</code>.<p>
*
* Then, the constructor is invoked. If it completes normally, the return
* value will be the new object. If it completes abruptly, the exception is
* wrapped in an <code>InvocationTargetException</code>.
*
* @param args the arguments to the constructor
* @return the newly created object
* @throws IllegalAccessException if the constructor could not normally be
* called by the Java code (i.e. it is not public)
* @throws IllegalArgumentException if the number of arguments is incorrect;
* or if the arguments types are wrong even with a widening
* conversion
* @throws InstantiationException if the class is abstract
* @throws InvocationTargetException if the constructor throws an exception
* @throws ExceptionInInitializerError if construction triggered class
* initialization, which then failed
*/
public Object newInstance(Object args[])
throws InstantiationException, IllegalAccessException,
InvocationTargetException
{
return constructNative(args, clazz, slot);
}
private native Object constructNative(Object[] args, Class declaringClass,
int slot)
throws InstantiationException, IllegalAccessException,
InvocationTargetException;
}

View file

@ -0,0 +1,589 @@
/* java.lang.reflect.Field - reflection of Java fields
Copyright (C) 1998, 2001 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang.reflect;
/**
* The Field class represents a member variable of a class. It also allows
* dynamic access to a member, via reflection. This works for both
* static and instance fields. Operations on Field objects know how to
* do widening conversions, but throw {@link IllegalArgumentException} if
* a narrowing conversion would be necessary. You can query for information
* on this Field regardless of location, but get and set access may be limited
* by Java language access controls. If you can't do it in the compiler, you
* can't normally do it here either.<p>
*
* <B>Note:</B> This class returns and accepts types as Classes, even
* primitive types; there are Class types defined that represent each
* different primitive type. They are <code>java.lang.Boolean.TYPE,
* java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
* byte.class</code>, etc. These are not to be confused with the
* classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
* real classes.<p>
*
* Also note that this is not a serializable class. It is entirely feasible
* to make it serializable using the Externalizable interface, but this is
* on Sun, not me.
*
* @author John Keiser
* @author Eric Blake <ebb9@email.byu.edu>
* @see Member
* @see Class
* @see Class#getField(String)
* @see Class#getDeclaredField(String)
* @see Class#getFields()
* @see Class#getDeclaredFields()
* @since 1.1
* @status updated to 1.4
*/
public final class Field
extends AccessibleObject implements Member
{
private Class declaringClass;
private String name;
private int slot;
/**
* This class is uninstantiable except natively.
*/
private Field(Class declaringClass, String name, int slot)
{
this.declaringClass = declaringClass;
this.name = name;
this.slot = slot;
}
/**
* Gets the class that declared this field, or the class where this field
* is a non-inherited member.
* @return the class that declared this member
*/
public Class getDeclaringClass()
{
return declaringClass;
}
/**
* Gets the name of this field.
* @return the name of this field
*/
public String getName()
{
return name;
}
/**
* Gets the modifiers this field uses. Use the <code>Modifier</code>
* class to interpret the values. A field can only have a subset of the
* following modifiers: public, private, protected, static, final,
* transient, and volatile.
*
* @return an integer representing the modifiers to this Member
* @see Modifier
*/
public native int getModifiers();
/**
* Gets the type of this field.
* @return the type of this field
*/
public native Class getType();
/**
* Compare two objects to see if they are semantically equivalent.
* Two Fields are semantically equivalent if they have the same declaring
* class, name, and type. Since you can't creat a Field except through
* the VM, this is just the == relation.
*
* @param o the object to compare to
* @return <code>true</code> if they are equal; <code>false</code> if not
*/
public boolean equals(Object o)
{
if (!(o instanceof Field))
return false;
Field that = (Field)o;
if (this.getDeclaringClass() != that.getDeclaringClass())
return false;
if (!this.getName().equals(that.getName()))
return false;
if (this.getType() != that.getType())
return false;
return true;
}
/**
* Get the hash code for the Field. The Field hash code is the hash code
* of its name XOR'd with the hash code of its class name.
*
* @return the hash code for the object.
*/
public int hashCode()
{
return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
}
/**
* Get a String representation of the Field. A Field's String
* representation is "&lt;modifiers&gt; &lt;type&gt;
* &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
* <code>public transient boolean gnu.parse.Parser.parseComplete</code>
*
* @return the String representation of the Field
*/
public String toString()
{
// 64 is a reasonable buffer initial size for field
StringBuffer sb = new StringBuffer(64);
Modifier.toString(getModifiers(), sb).append(' ');
sb.append(getType().getName()).append(' ');
sb.append(getDeclaringClass().getName()).append('.');
sb.append(getName());
return sb.toString();
}
/**
* Get the value of this Field. If it is primitive, it will be wrapped
* in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
*
* If the field is static, <code>o</code> will be ignored. Otherwise, if
* <code>o</code> is null, you get a <code>NullPointerException</code>,
* and if it is incompatible with the declaring class of the field, you
* get an <code>IllegalArgumentException</code>.<p>
*
* Next, if this Field enforces access control, your runtime context is
* evaluated, and you may have an <code>IllegalAccessException</code> if
* you could not access this field in similar compiled code. If the field
* is static, and its class is uninitialized, you trigger class
* initialization, which may end in a
* <code>ExceptionInInitializerError</code>.<p>
*
* Finally, the field is accessed, and primitives are wrapped (but not
* necessarily in new objects). This method accesses the field of the
* declaring class, even if the instance passed in belongs to a subclass
* which declares another field to hide this one.
*
* @param o the object to get the value of this Field from
* @return the value of the Field
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if <code>o</code> is not an instance of
* the class or interface declaring this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #getBoolean(Object)
* @see #getByte(Object)
* @see #getChar(Object)
* @see #getShort(Object)
* @see #getInt(Object)
* @see #getLong(Object)
* @see #getFloat(Object)
* @see #getDouble(Object)
*/
public native Object get(Object o)
throws IllegalAccessException;
/**
* Get the value of this boolean Field. If the field is static,
* <code>o</code> will be ignored.
*
* @param o the object to get the value of this Field from
* @return the value of the Field
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a boolean field of
* <code>o</code>, or if <code>o</code> is not an instance of the
* declaring class of this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #get(Object)
*/
public native boolean getBoolean(Object o)
throws IllegalAccessException;
/**
* Get the value of this byte Field. If the field is static,
* <code>o</code> will be ignored.
*
* @param o the object to get the value of this Field from
* @return the value of the Field
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a byte field of
* <code>o</code>, or if <code>o</code> is not an instance of the
* declaring class of this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #get(Object)
*/
public native byte getByte(Object o)
throws IllegalAccessException;
/**
* Get the value of this Field as a char. If the field is static,
* <code>o</code> will be ignored.
*
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a char field of
* <code>o</code>, or if <code>o</code> is not an instance
* of the declaring class of this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #get(Object)
*/
public native char getChar(Object o)
throws IllegalAccessException;
/**
* Get the value of this Field as a short. If the field is static,
* <code>o</code> will be ignored.
*
* @param o the object to get the value of this Field from
* @return the value of the Field
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a byte or short
* field of <code>o</code>, or if <code>o</code> is not an instance
* of the declaring class of this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #get(Object)
*/
public native short getShort(Object o)
throws IllegalAccessException;
/**
* Get the value of this Field as an int. If the field is static,
* <code>o</code> will be ignored.
*
* @param o the object to get the value of this Field from
* @return the value of the Field
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a byte, short, char, or
* int field of <code>o</code>, or if <code>o</code> is not an
* instance of the declaring class of this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #get(Object)
*/
public native int getInt(Object o)
throws IllegalAccessException;
/**
* Get the value of this Field as a long. If the field is static,
* <code>o</code> will be ignored.
*
* @param o the object to get the value of this Field from
* @return the value of the Field
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a byte, short, char, int,
* or long field of <code>o</code>, or if <code>o</code> is not an
* instance of the declaring class of this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #get(Object)
*/
public native long getLong(Object o)
throws IllegalAccessException;
/**
* Get the value of this Field as a float. If the field is static,
* <code>o</code> will be ignored.
*
* @param o the object to get the value of this Field from
* @return the value of the Field
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a byte, short, char, int,
* long, or float field of <code>o</code>, or if <code>o</code> is
* not an instance of the declaring class of this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #get(Object)
*/
public native float getFloat(Object o)
throws IllegalAccessException;
/**
* Get the value of this Field as a double. If the field is static,
* <code>o</code> will be ignored.
*
* @param o the object to get the value of this Field from
* @return the value of the Field
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a byte, short, char, int,
* long, float, or double field of <code>o</code>, or if
* <code>o</code> is not an instance of the declaring class of this
* field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #get(Object)
*/
public native double getDouble(Object o)
throws IllegalAccessException;
/**
* Set the value of this Field. If it is a primitive field, the value
* will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
*
* If the field is static, <code>o</code> will be ignored. Otherwise, if
* <code>o</code> is null, you get a <code>NullPointerException</code>,
* and if it is incompatible with the declaring class of the field, you
* get an <code>IllegalArgumentException</code>.<p>
*
* Next, if this Field enforces access control, your runtime context is
* evaluated, and you may have an <code>IllegalAccessException</code> if
* you could not access this field in similar compiled code. This also
* occurs whether or not there is access control if the field is final.
* If the field is primitive, and unwrapping your argument fails, you will
* get an <code>IllegalArgumentException</code>; likewise, this error
* happens if <code>value</code> cannot be cast to the correct object type.
* If the field is static, and its class is uninitialized, you trigger class
* initialization, which may end in a
* <code>ExceptionInInitializerError</code>.<p>
*
* Finally, the field is set with the widened value. This method accesses
* the field of the declaring class, even if the instance passed in belongs
* to a subclass which declares another field to hide this one.
*
* @param o the object to set this Field on
* @param value the value to set this Field to
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if <code>value</code> cannot be
* converted by a widening conversion to the underlying type of
* the Field, or if <code>o</code> is not an instance of the class
* declaring this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #setBoolean(Object, boolean)
* @see #setByte(Object, byte)
* @see #setChar(Object, char)
* @see #setShort(Object, short)
* @see #setInt(Object, int)
* @see #setLong(Object, long)
* @see #setFloat(Object, float)
* @see #setDouble(Object, double)
*/
public native void set(Object o, Object value)
throws IllegalAccessException;
/**
* Set this boolean Field. If the field is static, <code>o</code> will be
* ignored.
*
* @param o the object to set this Field on
* @param value the value to set this Field to
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a boolean field, or if
* <code>o</code> is not an instance of the class declaring this
* field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #set(Object, Object)
*/
public native void setBoolean(Object o, boolean value)
throws IllegalAccessException;
/**
* Set this byte Field. If the field is static, <code>o</code> will be
* ignored.
*
* @param o the object to set this Field on
* @param value the value to set this Field to
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a byte, short, int, long,
* float, or double field, or if <code>o</code> is not an instance
* of the class declaring this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #set(Object, Object)
*/
public native void setByte(Object o, byte value)
throws IllegalAccessException;
/**
* Set this char Field. If the field is static, <code>o</code> will be
* ignored.
*
* @param o the object to set this Field on
* @param value the value to set this Field to
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a char, int, long,
* float, or double field, or if <code>o</code> is not an instance
* of the class declaring this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #set(Object, Object)
*/
public native void setChar(Object o, char value)
throws IllegalAccessException;
/**
* Set this short Field. If the field is static, <code>o</code> will be
* ignored.
*
* @param o the object to set this Field on
* @param value the value to set this Field to
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a short, int, long,
* float, or double field, or if <code>o</code> is not an instance
* of the class declaring this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #set(Object, Object)
*/
public native void setShort(Object o, short value)
throws IllegalAccessException;
/**
* Set this int Field. If the field is static, <code>o</code> will be
* ignored.
*
* @param o the object to set this Field on
* @param value the value to set this Field to
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not an int, long, float, or
* double field, or if <code>o</code> is not an instance of the
* class declaring this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #set(Object, Object)
*/
public native void setInt(Object o, int value)
throws IllegalAccessException;
/**
* Set this long Field. If the field is static, <code>o</code> will be
* ignored.
*
* @param o the object to set this Field on
* @param value the value to set this Field to
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a long, float, or double
* field, or if <code>o</code> is not an instance of the class
* declaring this field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #set(Object, Object)
*/
public native void setLong(Object o, long value)
throws IllegalAccessException;
/**
* Set this float Field. If the field is static, <code>o</code> will be
* ignored.
*
* @param o the object to set this Field on
* @param value the value to set this Field to
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a float or long field, or
* if <code>o</code> is not an instance of the class declaring this
* field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #set(Object, Object)
*/
public native void setFloat(Object o, float value)
throws IllegalAccessException;
/**
* Set this double Field. If the field is static, <code>o</code> will be
* ignored.
*
* @param o the object to set this Field on
* @param value the value to set this Field to
* @throws IllegalAccessException if you could not normally access this field
* (i.e. it is not public)
* @throws IllegalArgumentException if this is not a double field, or if
* <code>o</code> is not an instance of the class declaring this
* field
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static field triggered
* class initialization, which then failed
* @see #set(Object, Object)
*/
public native void setDouble(Object o, double value)
throws IllegalAccessException;
}

View file

@ -0,0 +1,339 @@
/* java.lang.reflect.Method - reflection of Java methods
Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang.reflect;
import java.util.Arrays;
/**
* The Method class represents a member method of a class. It also allows
* dynamic invocation, via reflection. This works for both static and
* instance methods. Invocation on Method objects knows how to do
* widening conversions, but throws {@link IllegalArgumentException} if
* a narrowing conversion would be necessary. You can query for information
* on this Method regardless of location, but invocation access may be limited
* by Java language access controls. If you can't do it in the compiler, you
* can't normally do it here either.<p>
*
* <B>Note:</B> This class returns and accepts types as Classes, even
* primitive types; there are Class types defined that represent each
* different primitive type. They are <code>java.lang.Boolean.TYPE,
* java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
* byte.class</code>, etc. These are not to be confused with the
* classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
* real classes.<p>
*
* Also note that this is not a serializable class. It is entirely feasible
* to make it serializable using the Externalizable interface, but this is
* on Sun, not me.
*
* @author John Keiser
* @author Eric Blake <ebb9@email.byu.edu>
* @see Member
* @see Class
* @see java.lang.Class#getMethod(String,Object[])
* @see java.lang.Class#getDeclaredMethod(String,Object[])
* @see java.lang.Class#getMethods()
* @see java.lang.Class#getDeclaredMethods()
* @since 1.1
* @status updated to 1.4
*/
public final class Method
extends AccessibleObject implements Member
{
Class declaringClass;
String name;
int slot;
/**
* This class is uninstantiable.
*/
private Method(Class declaringClass, String name, int slot)
{
this.declaringClass = declaringClass;
this.name = name;
this.slot = slot;
}
/**
* Gets the class that declared this method, or the class where this method
* is a non-inherited member.
* @return the class that declared this member
*/
public Class getDeclaringClass()
{
return declaringClass;
}
/**
* Gets the name of this method.
* @return the name of this method
*/
public String getName()
{
return name;
}
/**
* Gets the modifiers this method uses. Use the <code>Modifier</code>
* class to interpret the values. A method can only have a subset of the
* following modifiers: public, private, protected, abstract, static,
* final, synchronized, native, and strictfp.
*
* @return an integer representing the modifiers to this Member
* @see Modifier
*/
public native int getModifiers();
/**
* Gets the return type of this method.
* @return the type of this method
*/
public native Class getReturnType();
/**
* Get the parameter list for this method, in declaration order. If the
* method takes no parameters, returns a 0-length array (not null).
*
* @return a list of the types of the method's parameters
*/
public native Class[] getParameterTypes();
/**
* Get the exception types this method says it throws, in no particular
* order. If the method has no throws clause, returns a 0-length array
* (not null).
*
* @return a list of the types in the method's throws clause
*/
public native Class[] getExceptionTypes();
/**
* Compare two objects to see if they are semantically equivalent.
* Two Methods are semantically equivalent if they have the same declaring
* class, name, parameter list, and return type.
*
* @param o the object to compare to
* @return <code>true</code> if they are equal; <code>false</code> if not
*/
public boolean equals(Object o)
{
// Implementation note:
// The following is a correct but possibly slow implementation.
//
// This class has a private field 'slot' that could be used by
// the VM implementation to "link" a particular method to a Class.
// In that case equals could be simply implemented as:
//
// if (o instanceof Method)
// {
// Method m = (Method)o;
// return m.declaringClass == this.declaringClass
// && m.slot == this.slot;
// }
// return false;
//
// If a VM uses the Method class as their native/internal representation
// then just using the following would be optimal:
//
// return this == o;
//
if (!(o instanceof Method))
return false;
Method that = (Method)o;
if (this.getDeclaringClass() != that.getDeclaringClass())
return false;
if (!this.getName().equals(that.getName()))
return false;
if (this.getReturnType() != that.getReturnType())
return false;
if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
return false;
return true;
}
/**
* Get the hash code for the Method. The Method hash code is the hash code
* of its name XOR'd with the hash code of its class name.
*
* @return the hash code for the object
*/
public int hashCode()
{
return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
}
/**
* Get a String representation of the Method. A Method's String
* representation is "&lt;modifiers&gt; &lt;returntype&gt;
* &lt;methodname&gt;(&lt;paramtypes&gt;) throws &lt;exceptions&gt;", where
* everything after ')' is omitted if there are no exceptions.<br> Example:
* <code>public static int run(java.lang.Runnable,int)</code>
*
* @return the String representation of the Method
*/
public String toString()
{
// 128 is a reasonable buffer initial size for constructor
StringBuffer sb = new StringBuffer(128);
Modifier.toString(getModifiers(), sb).append(' ');
sb.append(getUserTypeName(getReturnType().getName())).append(' ');
sb.append(getDeclaringClass().getName()).append('.');
sb.append(getName()).append('(');
Class[] c = getParameterTypes();
if (c.length > 0)
{
sb.append(getUserTypeName(c[0].getName()));
for (int i = 1; i < c.length; i++)
sb.append(',').append(getUserTypeName(c[i].getName()));
}
sb.append(')');
c = getExceptionTypes();
if (c.length > 0)
{
sb.append(" throws ").append(c[0].getName());
for (int i = 1; i < c.length; i++)
sb.append(',').append(c[i].getName());
}
return sb.toString();
}
private static String getUserTypeName(String typeSpec)
{
int pos = 0;
String typeName = "";
String arrayPart = "";
while (typeSpec.charAt(pos) == '[')
{
arrayPart += "[]";
++pos;
}
switch (typeSpec.charAt(pos))
{
case 'Z':
typeName = "boolean";
break;
case 'B':
typeName = "byte";
break;
case 'C':
typeName = "char";
break;
case 'D':
typeName = "double";
break;
case 'F':
typeName = "float";
break;
case 'I':
typeName = "int";
break;
case 'J':
typeName = "long";
break;
case 'S':
typeName = "short";
break;
case 'L':
typeName = typeSpec.substring(pos + 1, typeSpec.length() - 1);
break;
default:
typeName = typeSpec;
break;
}
return typeName + arrayPart;
}
/**
* Invoke the method. Arguments are automatically unwrapped and widened,
* and the result is automatically wrapped, if needed.<p>
*
* If the method is static, <code>o</code> will be ignored. Otherwise,
* the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot
* mimic the behavior of nonvirtual lookup (as in super.foo()). This means
* you will get a <code>NullPointerException</code> if <code>o</code> is
* null, and an <code>IllegalArgumentException</code> if it is incompatible
* with the declaring class of the method. If the method takes 0 arguments,
* you may use null or a 0-length array for <code>args</code>.<p>
*
* Next, if this Method enforces access control, your runtime context is
* evaluated, and you may have an <code>IllegalAccessException</code> if
* you could not acces this method in similar compiled code. If the method
* is static, and its class is uninitialized, you trigger class
* initialization, which may end in a
* <code>ExceptionInInitializerError</code>.<p>
*
* Finally, the method is invoked. If it completes normally, the return value
* will be null for a void method, a wrapped object for a primitive return
* method, or the actual return of an Object method. If it completes
* abruptly, the exception is wrapped in an
* <code>InvocationTargetException</code>.
*
* @param o the object to invoke the method on
* @param args the arguments to the method
* @return the return value of the method, wrapped in the appropriate
* wrapper if it is primitive
* @throws IllegalAccessException if the method could not normally be called
* by the Java code (i.e. it is not public)
* @throws IllegalArgumentException if the number of arguments is incorrect;
* if the arguments types are wrong even with a widening conversion;
* or if <code>o</code> is not an instance of the class or interface
* declaring this method
* @throws InvocationTargetException if the method throws an exception
* @throws NullPointerException if <code>o</code> is null and this field
* requires an instance
* @throws ExceptionInInitializerError if accessing a static method triggered
* class initialization, which then failed
*/
public Object invoke(Object o, Object[] args)
throws IllegalAccessException, InvocationTargetException
{
return invokeNative(o, args, declaringClass, slot);
}
/*
* NATIVE HELPERS
*/
private native Object invokeNative(Object o, Object[] args,
Class declaringClass, int slot)
throws IllegalAccessException, InvocationTargetException;
}

View file

@ -0,0 +1,93 @@
/* VMInetAddress.java -- Class to model an Internet address
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.net;
import gnu.classpath.Configuration;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.StringTokenizer;
class VMInetAddress implements Serializable
{
static
{
if (Configuration.INIT_LOAD_LIBRARY)
System.loadLibrary("javanet");
}
/**
* This method looks up the hostname of the local machine
* we are on. If the actual hostname cannot be determined, then the
* value "localhost" will be used. This native method wrappers the
* "gethostname" function.
*
* @return The local hostname.
*/
public static native String getLocalHostname();
/**
* Returns the value of the special address INADDR_ANY
*/
public static native byte[] lookupInaddrAny() throws UnknownHostException;
/**
* This method returns the hostname for a given IP address. It will
* throw an UnknownHostException if the hostname cannot be determined.
*
* @param ip The IP address as a byte array
*
* @return The hostname
*
* @exception UnknownHostException If the reverse lookup fails
*/
public static native String getHostByAddr(byte[] ip)
throws UnknownHostException;
/**
* Returns a list of all IP addresses for a given hostname. Will throw
* an UnknownHostException if the hostname cannot be resolved.
*/
public static native byte[][] getHostByName(String hostname)
throws UnknownHostException;
}

View file

@ -0,0 +1,66 @@
/* VMNetworkInterface.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.net;
import gnu.classpath.Configuration;
import java.util.Enumeration;
import java.util.Vector;
/**
* This class models a network interface on the host computer. A network
* interface contains a name (typically associated with a specific
* hardware adapter) and a list of addresses that are bound to it.
* For example, an ethernet interface may be named "eth0" and have the
* address 192.168.1.101 assigned to it.
*
* @author Michael Koch (konqueror@gmx.de)
* @since 1.4
*/
final class VMNetworkInterface
{
static
{
if (Configuration.INIT_LOAD_LIBRARY)
System.loadLibrary("javanet");
}
public static native Vector getInterfaces()
throws SocketException;
}

View file

@ -0,0 +1,66 @@
/* VMDirectByteBuffer.java --
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.nio;
import gnu.classpath.Configuration;
import gnu.classpath.RawData;
final class VMDirectByteBuffer
{
static
{
// load the shared library needed for native methods.
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary("javanio");
}
init();
}
private static native void init();
static native RawData allocate (int capacity);
static native void free(RawData address);
static native byte get(RawData address, int index);
static native void get(RawData address, int index, byte[] dst, int offset, int length);
static native void put(RawData address, int index, byte value);
static native RawData adjustAddress(RawData address, int offset);
static native void shiftDown(RawData address, int dst_offset, int src_offset, int count);
}

View file

@ -0,0 +1,116 @@
/* VMChannels.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.nio.channels;
import gnu.java.nio.ChannelInputStream;
import gnu.java.nio.ChannelOutputStream;
import gnu.java.nio.channels.FileChannelImpl;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
final class VMChannels
{
/**
* This class isn't intended to be instantiated.
*/
private VMChannels()
{
// Do nothing here.
}
private static Object createStream(Class streamClass, Channel ch)
{
try
{
Class[] argTypes = new Class[1];
argTypes[0] = FileChannelImpl.class;
Constructor constructor =
streamClass.getDeclaredConstructor(argTypes);
constructor.setAccessible(true);
Object[] args = new Object[1];
args[0] = ch;
return constructor.newInstance(args);
}
catch (IllegalAccessException e)
{
// Ignored.
}
catch (InstantiationException e)
{
// Ignored.
}
catch (InvocationTargetException e)
{
// Ignored.
}
catch (NoSuchMethodException e)
{
// Ignored.
}
return null;
}
/**
* Constructs a stream that reads bytes from the given channel.
*/
static InputStream newInputStream(ReadableByteChannel ch)
{
if (ch instanceof FileChannelImpl)
return (FileInputStream) createStream(FileInputStream.class, ch);
return new ChannelInputStream(ch);
}
/**
* Constructs a stream that writes bytes to the given channel.
*/
static OutputStream newOutputStream(WritableByteChannel ch)
{
if (ch instanceof FileChannelImpl)
return (FileOutputStream) createStream(FileOutputStream.class, ch);
return new ChannelOutputStream(ch);
}
}

View file

@ -0,0 +1,260 @@
/* VMAccessController.java -- VM-specific access controller methods.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.security;
import java.util.HashSet;
import java.util.LinkedList;
final class VMAccessController
{
// Fields.
// -------------------------------------------------------------------------
/**
* This is a per-thread stack of AccessControlContext objects (which can
* be null) for each call to AccessController.doPrivileged in each thread's
* call stack. We use this to remember which context object corresponds to
* which call.
*/
private static final ThreadLocal contexts = new ThreadLocal();
/**
* This is a Boolean that, if set, tells getContext that it has already
* been called once, allowing us to handle recursive permission checks
* caused by methods getContext calls.
*/
private static final ThreadLocal inGetContext = new ThreadLocal();
/**
* And we return this all-permissive context to ensure that privileged
* methods called from getContext succeed.
*/
private static final AccessControlContext DEFAULT_CONTEXT;
static
{
CodeSource source = new CodeSource(null, null);
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
ProtectionDomain[] domain = new ProtectionDomain[] {
new ProtectionDomain(source, permissions)
};
DEFAULT_CONTEXT = new AccessControlContext(domain);
}
private static final boolean DEBUG = false;
private static void debug(String msg)
{
System.err.print(">>> VMAccessController: ");
System.err.println(msg);
}
// Constructors.
// -------------------------------------------------------------------------
private VMAccessController() { }
// Class methods.
// -------------------------------------------------------------------------
/**
* Relate a class (which should be an instance of {@link PrivilegedAction}
* with an access control context. This method is used by {@link
* AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
* to set up the context that will be returned by {@link #getContext()}.
* This method relates the class to the current thread, so contexts
* pushed from one thread will not be available to another.
*
* @param acc The access control context.
*/
static void pushContext (AccessControlContext acc)
{
if (DEBUG)
debug("pushing " + acc);
LinkedList stack = (LinkedList) contexts.get();
if (stack == null)
{
stack = new LinkedList();
contexts.set(stack);
}
stack.addFirst(acc);
}
/**
* Removes the relation of a class to an {@link AccessControlContext}.
* This method is used by {@link AccessController} when exiting from a
* call to {@link
* AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
*/
static void popContext()
{
if (DEBUG)
debug("popping context");
// Stack should never be null, nor should it be empty, if this method
// and its counterpart has been called properly.
LinkedList stack = (LinkedList) contexts.get();
if (stack != null)
{
stack.removeFirst();
if (stack.isEmpty())
contexts.set(null);
}
}
/**
* Examine the method stack of the currently running thread, and create
* an {@link AccessControlContext} filled in with the appropriate {@link
* ProtectionDomain} objects given this stack.
*
* @return The context.
*/
static AccessControlContext getContext()
{
// If we are already in getContext, but called a method that needs
// a permission check, return the all-permissive context so methods
// called from here succeed.
//
// XXX is this necessary? We should verify if there are any calls in
// the stack below this method that require permission checks.
Boolean inCall = (Boolean) inGetContext.get();
if (inCall != null && inCall.booleanValue())
{
if (DEBUG)
debug("already in getContext");
return DEFAULT_CONTEXT;
}
inGetContext.set(Boolean.TRUE);
Object[][] stack = getStack();
Class[] classes = (Class[]) stack[0];
String[] methods = (String[]) stack[1];
if (DEBUG)
debug(">>> got trace of length " + classes.length);
HashSet domains = new HashSet();
HashSet seenDomains = new HashSet();
AccessControlContext context = null;
int privileged = 0;
// We walk down the stack, adding each ProtectionDomain for each
// class in the call stack. If we reach a call to doPrivileged,
// we don't add any more stack frames. We skip the first three stack
// frames, since they comprise the calls to getStack, getContext,
// and AccessController.getContext.
for (int i = 3; i < classes.length && privileged < 2; i++)
{
Class clazz = classes[i];
String method = methods[i];
if (DEBUG)
{
debug(">>> checking " + clazz + "." + method);
debug(">>> loader = " + clazz.getClassLoader());
}
// If the previous frame was a call to doPrivileged, then this is
// the last frame we look at.
if (privileged == 1)
privileged = 2;
if (clazz.equals (AccessController.class)
&& method.equals ("doPrivileged"))
{
// If there was a call to doPrivileged with a supplied context,
// return that context.
LinkedList l = (LinkedList) contexts.get();
if (l != null)
context = (AccessControlContext) l.getFirst();
privileged = 1;
}
ProtectionDomain domain = clazz.getProtectionDomain();
if (domain == null)
continue;
if (seenDomains.contains(domain))
continue;
seenDomains.add(domain);
// Create a static snapshot of this domain, which may change over time
// if the current policy changes.
domains.add(new ProtectionDomain(domain.getCodeSource(),
domain.getPermissions()));
}
if (DEBUG)
debug("created domains: " + domains);
ProtectionDomain[] result = (ProtectionDomain[])
domains.toArray(new ProtectionDomain[domains.size()]);
// Intersect the derived protection domain with the context supplied
// to doPrivileged.
if (context != null)
context = new AccessControlContext(result, context,
IntersectingDomainCombiner.SINGLETON);
// No context was supplied. Return the derived one.
else
context = new AccessControlContext(result);
inGetContext.set(Boolean.FALSE);
return context;
}
/**
* Returns a snapshot of the current call stack as a pair of arrays:
* the first an array of classes in the call stack, the second an array
* of strings containing the method names in the call stack. The two
* arrays match up, meaning that method <i>i</i> is declared in class
* <i>i</i>. The arrays are clean; it will only contain Java methods,
* and no element of the list should be null.
*
* <p>The default implementation returns an empty stack, which will be
* interpreted as having no permissions whatsoever.
*
* @return A pair of arrays describing the current call stack. The first
* element is an array of Class objects, and the second is an array
* of Strings comprising the method names.
*/
private static Object[][] getStack()
{
return new Object[][] { new Class[0], new String[0] };
}
}

View file

@ -0,0 +1,345 @@
/* java.util.VMTimeZone
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util;
import gnu.classpath.Configuration;
import java.io.*;
/**
*
*/
final class VMTimeZone
{
static
{
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary("javautil");
}
}
/**
* This method returns a time zone id string which is in the form
* (standard zone name) or (standard zone name)(GMT offset) or
* (standard zone name)(GMT offset)(daylight time zone name). The
* GMT offset can be in seconds, or where it is evenly divisible by
* 3600, then it can be in hours. The offset must be the time to
* add to the local time to get GMT. If a offset is given and the
* time zone observes daylight saving then the (daylight time zone
* name) must also be given (otherwise it is assumed the time zone
* does not observe any daylight savings).
* <p>
* The result of this method is given to the method
* TimeZone.getDefaultTimeZone(String) which tries to map the time
* zone id to a known TimeZone. See that method on how the returned
* String is mapped to a real TimeZone object.
* <p>
* The reference implementation which is made for GNU/Posix like
* systems calls <code>System.getenv("TZ")</code>,
* <code>readTimeZoneFile("/etc/timezone")</code>,
* <code>readtzFile("/etc/localtime")</code> and finally
* <code>getSystemTimeZoneId()</code> till a supported TimeZone is
* found through <code>TimeZone.getDefaultTimeZone(String)</code>.
* If every method fails <code>null</code> is returned (which means
* the TimeZone code will fall back on GMT as default time zone).
* <p>
* Note that this method is called inside a
* <code>AccessController.doPrivileged()</code> block and runs with
* the priviliges of the java.util system classes. It will only be
* called when the default time zone is not yet set, the system
* property user.timezone isn't set and it is requested for the
* first time.
*/
static TimeZone getDefaultTimeZoneId()
{
TimeZone zone = null;
// See if TZ environment variable is set and accessible.
String tzid = System.getenv("TZ");
if (tzid != null && !tzid.equals(""))
zone = TimeZone.getDefaultTimeZone(tzid);
// Try to parse /etc/timezone.
if (zone == null)
{
tzid = readTimeZoneFile("/etc/timezone");
if (tzid != null && !tzid.equals(""))
zone = TimeZone.getDefaultTimeZone(tzid);
}
// Try to parse /etc/localtime
if (zone == null)
{
tzid = readtzFile("/etc/localtime");
if (tzid != null && !tzid.equals(""))
zone = TimeZone.getDefaultTimeZone(tzid);
}
// Try some system specific way
if (zone == null)
{
tzid = getSystemTimeZoneId();
if (tzid != null && !tzid.equals(""))
zone = TimeZone.getDefaultTimeZone(tzid);
}
return zone;
}
/**
* Tries to read the time zone name from a file. Only the first
* consecutive letters, digits, slashes, dashes and underscores are
* read from the file. If the file cannot be read or an IOException
* occurs null is returned.
* <p>
* The /etc/timezone file is not standard, but a lot of systems have
* it. If it exist the first line always contains a string
* describing the timezone of the host of domain. Some systems
* contain a /etc/TIMEZONE file which is used to set the TZ
* environment variable (which is checked before /etc/timezone is
* read).
*/
private static String readTimeZoneFile(String file)
{
File f = new File(file);
if (!f.exists())
return null;
InputStreamReader isr = null;
try
{
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
isr = new InputStreamReader(bis);
StringBuffer sb = new StringBuffer();
int i = isr.read();
while (i != -1)
{
char c = (char) i;
if (Character.isLetter(c) || Character.isDigit(c)
|| c == '/' || c == '-' || c == '_')
{
sb.append(c);
i = isr.read();
}
else
break;
}
return sb.toString();
}
catch (IOException ioe)
{
// Parse error, not a proper tzfile.
return null;
}
finally
{
try
{
if (isr != null)
isr.close();
}
catch (IOException ioe)
{
// Error while close, nothing we can do.
}
}
}
/**
* Tries to read a file as a "standard" tzfile and return a time
* zone id string as expected by <code>getDefaultTimeZone(String)</code>.
* If the file doesn't exist, an IOException occurs or it isn't a tzfile
* that can be parsed null is returned.
* <p>
* The tzfile structure (as also used by glibc) is described in the Olson
* tz database archive as can be found at
* <code>ftp://elsie.nci.nih.gov/pub/</code>.
* <p>
* At least the following platforms support the tzdata file format
* and /etc/localtime (GNU/Linux, Darwin, Solaris and FreeBSD at
* least). Some systems (like Darwin) don't start the file with the
* required magic bytes 'TZif', this implementation can handle
* that).
*/
private static String readtzFile(String file)
{
File f = new File(file);
if (!f.exists())
return null;
DataInputStream dis = null;
try
{
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
// Make sure we are reading a tzfile.
byte[] tzif = new byte[4];
dis.readFully(tzif);
if (tzif[0] == 'T' && tzif[1] == 'Z'
&& tzif[2] == 'i' && tzif[3] == 'f')
// Reserved bytes, ttisgmtcnt, ttisstdcnt and leapcnt
skipFully(dis, 16 + 3 * 4);
else
// Darwin has tzdata files that don't start with the TZif marker
skipFully(dis, 16 + 3 * 4 - 4);
int timecnt = dis.readInt();
int typecnt = dis.readInt();
if (typecnt > 0)
{
int charcnt = dis.readInt();
// Transition times plus indexed transition times.
skipFully(dis, timecnt * (4 + 1));
// Get last gmt_offset and dst/non-dst time zone names.
int abbrind = -1;
int dst_abbrind = -1;
int gmt_offset = 0;
while (typecnt-- > 0)
{
// gmtoff
int offset = dis.readInt();
int dst = dis.readByte();
if (dst == 0)
{
abbrind = dis.readByte();
gmt_offset = offset;
}
else
dst_abbrind = dis.readByte();
}
// gmt_offset is the offset you must add to UTC/GMT to
// get the local time, we need the offset to add to
// the local time to get UTC/GMT.
gmt_offset *= -1;
// Turn into hours if possible.
if (gmt_offset % 3600 == 0)
gmt_offset /= 3600;
if (abbrind >= 0)
{
byte[] names = new byte[charcnt];
dis.readFully(names);
int j = abbrind;
while (j < charcnt && names[j] != 0)
j++;
String zonename = new String(names, abbrind, j - abbrind,
"ASCII");
String dst_zonename;
if (dst_abbrind >= 0)
{
j = dst_abbrind;
while (j < charcnt && names[j] != 0)
j++;
dst_zonename = new String(names, dst_abbrind,
j - dst_abbrind, "ASCII");
}
else
dst_zonename = "";
// Only use gmt offset when necessary.
// Also special case GMT+/- timezones.
String offset_string;
if ("".equals(dst_zonename)
&& (gmt_offset == 0
|| zonename.startsWith("GMT+")
|| zonename.startsWith("GMT-")))
offset_string = "";
else
offset_string = Integer.toString(gmt_offset);
String id = zonename + offset_string + dst_zonename;
return id;
}
}
// Something didn't match while reading the file.
return null;
}
catch (IOException ioe)
{
// Parse error, not a proper tzfile.
return null;
}
finally
{
try
{
if (dis != null)
dis.close();
}
catch(IOException ioe)
{
// Error while close, nothing we can do.
}
}
}
/**
* Skips the requested number of bytes in the given InputStream.
* Throws EOFException if not enough bytes could be skipped.
* Negative numbers of bytes to skip are ignored.
*/
private static void skipFully(InputStream is, long l) throws IOException
{
while (l > 0)
{
long k = is.skip(l);
if (k <= 0)
throw new EOFException();
l -= k;
}
}
/**
* Tries to get the system time zone id through native code.
*/
private static native String getSystemTimeZoneId();
}